blob: b6cca366818059ed6e1682c7fc40ebfd5bc8617c [file] [log] [blame]
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Steve DiBenedettoef04f272014-06-04 14:28:31 -06003 * Copyright (c) 2014, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070025
26#include "face-manager.hpp"
27
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -060028#include "core/logger.hpp"
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070029#include "core/face-uri.hpp"
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -060030#include "core/network-interface.hpp"
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070031#include "fw/face-table.hpp"
Alexander Afanasyeve515f0a2014-06-30 15:28:10 -070032#include "face/face-flags.hpp"
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070033#include "face/tcp-factory.hpp"
34#include "face/udp-factory.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070035#include "core/config-file.hpp"
Steve DiBenedettofbb40a82014-03-11 19:40:15 -060036
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -060037#ifdef HAVE_UNIX_SOCKETS
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070038#include "face/unix-stream-factory.hpp"
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -060039#endif // HAVE_UNIX_SOCKETS
40
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070041#ifdef HAVE_LIBPCAP
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070042#include "face/ethernet-factory.hpp"
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070043#endif // HAVE_LIBPCAP
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070044
Wentao Shang53df1632014-04-21 12:01:32 -070045#ifdef HAVE_WEBSOCKET
46#include "face/websocket-factory.hpp"
47#endif // HAVE_WEBSOCKET
48
Alexander Afanasyev4a771362014-04-24 21:29:33 -070049#include <ndn-cxx/management/nfd-face-event-notification.hpp>
Davide Pesavento52a18f92014-04-10 00:55:01 +020050
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070051namespace nfd {
52
53NFD_LOG_INIT("FaceManager");
54
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060055const Name FaceManager::COMMAND_PREFIX("/localhost/nfd/faces");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070056
57const size_t FaceManager::COMMAND_UNSIGNED_NCOMPS =
58 FaceManager::COMMAND_PREFIX.size() +
59 1 + // verb
Steve DiBenedetto7564d972014-03-24 14:28:46 -060060 1; // verb parameters
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070061
62const size_t FaceManager::COMMAND_SIGNED_NCOMPS =
63 FaceManager::COMMAND_UNSIGNED_NCOMPS +
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070064 4; // (timestamp, nonce, signed info tlv, signature tlv)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070065
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060066const FaceManager::SignedVerbAndProcessor FaceManager::SIGNED_COMMAND_VERBS[] =
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070067 {
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060068 SignedVerbAndProcessor(
Steve DiBenedetto7564d972014-03-24 14:28:46 -060069 Name::Component("create"),
70 &FaceManager::createFace
71 ),
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070072
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060073 SignedVerbAndProcessor(
Steve DiBenedetto7564d972014-03-24 14:28:46 -060074 Name::Component("destroy"),
75 &FaceManager::destroyFace
76 ),
77
78 SignedVerbAndProcessor(
79 Name::Component("enable-local-control"),
80 &FaceManager::enableLocalControl
81 ),
82
83 SignedVerbAndProcessor(
84 Name::Component("disable-local-control"),
85 &FaceManager::disableLocalControl
86 ),
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070087 };
88
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060089const FaceManager::UnsignedVerbAndProcessor FaceManager::UNSIGNED_COMMAND_VERBS[] =
90 {
91 UnsignedVerbAndProcessor(
92 Name::Component("list"),
93 &FaceManager::listFaces
94 ),
Steve DiBenedettofbb40a82014-03-11 19:40:15 -060095
96 UnsignedVerbAndProcessor(
97 Name::Component("events"),
98 &FaceManager::ignoreUnsignedVerb
99 ),
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600100
101 UnsignedVerbAndProcessor(
102 Name::Component("channels"),
103 &FaceManager::listChannels
104 ),
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600105 };
106
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600107const Name FaceManager::FACES_LIST_DATASET_PREFIX("/localhost/nfd/faces/list");
108const size_t FaceManager::FACES_LIST_DATASET_NCOMPS = FACES_LIST_DATASET_PREFIX.size();
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600109
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600110const Name FaceManager::FACE_EVENTS_PREFIX("/localhost/nfd/faces/events");
111
112const Name FaceManager::CHANNELS_LIST_DATASET_PREFIX("/localhost/nfd/faces/channels");
113const size_t FaceManager::CHANNELS_LIST_DATASET_NCOMPS = CHANNELS_LIST_DATASET_PREFIX.size();
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700114
115FaceManager::FaceManager(FaceTable& faceTable,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700116 shared_ptr<InternalFace> face)
117 : ManagerBase(face, FACE_MANAGER_PRIVILEGE)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700118 , m_faceTable(faceTable)
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600119 , m_faceStatusPublisher(m_faceTable, m_face, FACES_LIST_DATASET_PREFIX)
120 , m_channelStatusPublisher(m_factories, m_face, CHANNELS_LIST_DATASET_PREFIX)
121 , m_notificationStream(m_face, FACE_EVENTS_PREFIX)
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600122 , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600123 SIGNED_COMMAND_VERBS +
124 (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600125 , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600126 UNSIGNED_COMMAND_VERBS +
127 (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600128
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700129{
130 face->setInterestFilter("/localhost/nfd/faces",
131 bind(&FaceManager::onFaceRequest, this, _2));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600132
133 m_faceTable.onAdd += bind(&FaceManager::onAddFace, this, _1);
134 m_faceTable.onRemove += bind(&FaceManager::onRemoveFace, this, _1);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700135}
136
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600137FaceManager::~FaceManager()
138{
139
140}
141
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700142void
143FaceManager::setConfigFile(ConfigFile& configFile)
144{
145 configFile.addSectionHandler("face_system",
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600146 bind(&FaceManager::onConfig, this, _1, _2, _3));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700147}
148
149
150void
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600151FaceManager::onConfig(const ConfigSection& configSection,
152 bool isDryRun,
153 const std::string& filename)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700154{
155 bool hasSeenUnix = false;
156 bool hasSeenTcp = false;
157 bool hasSeenUdp = false;
158 bool hasSeenEther = false;
Wentao Shang53df1632014-04-21 12:01:32 -0700159 bool hasSeenWebSocket = false;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700160
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600161 const std::list<shared_ptr<NetworkInterfaceInfo> > nicList(listNetworkInterfaces());
162
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700163 for (ConfigSection::const_iterator item = configSection.begin();
164 item != configSection.end();
165 ++item)
166 {
167 if (item->first == "unix")
168 {
169 if (hasSeenUnix)
170 throw Error("Duplicate \"unix\" section");
171 hasSeenUnix = true;
172
173 processSectionUnix(item->second, isDryRun);
174 }
175 else if (item->first == "tcp")
176 {
177 if (hasSeenTcp)
178 throw Error("Duplicate \"tcp\" section");
179 hasSeenTcp = true;
180
181 processSectionTcp(item->second, isDryRun);
182 }
183 else if (item->first == "udp")
184 {
185 if (hasSeenUdp)
186 throw Error("Duplicate \"udp\" section");
187 hasSeenUdp = true;
188
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600189 processSectionUdp(item->second, isDryRun, nicList);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700190 }
191 else if (item->first == "ether")
192 {
193 if (hasSeenEther)
194 throw Error("Duplicate \"ether\" section");
195 hasSeenEther = true;
196
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600197 processSectionEther(item->second, isDryRun, nicList);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700198 }
Wentao Shang53df1632014-04-21 12:01:32 -0700199 else if (item->first == "websocket")
200 {
201 if (hasSeenWebSocket)
202 throw Error("Duplicate \"websocket\" section");
203 hasSeenWebSocket = true;
204
205 processSectionWebSocket(item->second, isDryRun);
206 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700207 else
208 {
209 throw Error("Unrecognized option \"" + item->first + "\"");
210 }
211 }
212}
213
214void
215FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRun)
216{
217 // ; the unix section contains settings of UNIX stream faces and channels
218 // unix
219 // {
220 // listen yes ; set to 'no' to disable UNIX stream listener, default 'yes'
221 // path /var/run/nfd.sock ; UNIX stream listener path
222 // }
223
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600224#if defined(HAVE_UNIX_SOCKETS)
225
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700226 bool needToListen = true;
227 std::string path = "/var/run/nfd.sock";
228
229 for (ConfigSection::const_iterator i = configSection.begin();
230 i != configSection.end();
231 ++i)
232 {
233 if (i->first == "path")
234 {
235 path = i->second.get_value<std::string>();
236 }
237 else if (i->first == "listen")
238 {
239 needToListen = parseYesNo(i, i->first, "unix");
240 }
241 else
242 {
243 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"unix\" section");
244 }
245 }
246
247 if (!isDryRun)
248 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300249 if (m_factories.count("unix") > 0)
250 {
251 return;
252 // shared_ptr<UnixStreamFactory> factory
253 // = static_pointer_cast<UnixStreamFactory>(m_factories["unix"]);
254 // shared_ptr<UnixStreamChannel> unixChannel = factory->findChannel(path);
255
256 // if (static_cast<bool>(unixChannel))
257 // {
258 // return;
259 // }
260 }
261
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700262 shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
263 shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
264
265 if (needToListen)
266 {
267 // Should acceptFailed callback be used somehow?
268 unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
269 UnixStreamChannel::ConnectFailedCallback());
270 }
271
272 m_factories.insert(std::make_pair("unix", factory));
273 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600274#else
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300275 throw ConfigFile::Error("NFD was compiled without UNIX sockets support, "
276 "cannot process \"unix\" section");
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600277#endif // HAVE_UNIX_SOCKETS
278
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700279}
280
281void
282FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun)
283{
284 // ; the tcp section contains settings of TCP faces and channels
285 // tcp
286 // {
287 // listen yes ; set to 'no' to disable TCP listener, default 'yes'
288 // port 6363 ; TCP listener port number
289 // }
290
291 std::string port = "6363";
292 bool needToListen = true;
Steve DiBenedetto95152872014-04-11 12:40:59 -0600293 bool enableV4 = true;
294 bool enableV6 = true;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700295
296 for (ConfigSection::const_iterator i = configSection.begin();
297 i != configSection.end();
298 ++i)
299 {
300 if (i->first == "port")
301 {
302 port = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600303 try
304 {
305 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
306 NFD_LOG_TRACE("TCP port set to " << portNo);
307 }
308 catch (const std::bad_cast& error)
309 {
310 throw ConfigFile::Error("Invalid value for option " +
Steve DiBenedetto95152872014-04-11 12:40:59 -0600311 i->first + "\" in \"tcp\" section");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600312 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700313 }
314 else if (i->first == "listen")
315 {
316 needToListen = parseYesNo(i, i->first, "tcp");
317 }
Steve DiBenedetto95152872014-04-11 12:40:59 -0600318 else if (i->first == "enable_v4")
319 {
320 enableV4 = parseYesNo(i, i->first, "tcp");
321 }
322 else if (i->first == "enable_v6")
323 {
324 enableV6 = parseYesNo(i, i->first, "tcp");
325 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700326 else
327 {
328 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
329 }
330 }
331
Steve DiBenedetto95152872014-04-11 12:40:59 -0600332 if (!enableV4 && !enableV6)
333 {
334 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
335 " Remove \"tcp\" section to disable TCP channels or"
336 " re-enable at least one channel type.");
337 }
338
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700339 if (!isDryRun)
340 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300341 if (m_factories.count("tcp") > 0)
342 {
343 return;
344 }
345
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700346 shared_ptr<TcpFactory> factory = ndn::make_shared<TcpFactory>(port);
Steve DiBenedetto95152872014-04-11 12:40:59 -0600347 m_factories.insert(std::make_pair("tcp", factory));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700348
Steve DiBenedetto95152872014-04-11 12:40:59 -0600349 if (enableV4)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700350 {
Steve DiBenedetto95152872014-04-11 12:40:59 -0600351 shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
352 if (needToListen)
353 {
354 // Should acceptFailed callback be used somehow?
355 ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
356 TcpChannel::ConnectFailedCallback());
357 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700358
Steve DiBenedetto95152872014-04-11 12:40:59 -0600359 m_factories.insert(std::make_pair("tcp4", factory));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700360 }
361
Steve DiBenedetto95152872014-04-11 12:40:59 -0600362 if (enableV6)
363 {
364 shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
365 if (needToListen)
366 {
367 // Should acceptFailed callback be used somehow?
368 ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
369 TcpChannel::ConnectFailedCallback());
370 }
371
372 m_factories.insert(std::make_pair("tcp6", factory));
373 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700374 }
375}
376
377void
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600378FaceManager::processSectionUdp(const ConfigSection& configSection,
379 bool isDryRun,
380 const std::list<shared_ptr<NetworkInterfaceInfo> >& nicList)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700381{
382 // ; the udp section contains settings of UDP faces and channels
383 // udp
384 // {
385 // port 6363 ; UDP unicast port number
386 // idle_timeout 30 ; idle time (seconds) before closing a UDP unicast face
387 // keep_alive_interval 25; interval (seconds) between keep-alive refreshes
388
389 // ; NFD creates one UDP multicast face per NIC
390 // mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
391 // mcast_port 56363 ; UDP multicast port number
392 // mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
393 // }
394
395 std::string port = "6363";
Steve DiBenedetto95152872014-04-11 12:40:59 -0600396 bool enableV4 = true;
397 bool enableV6 = true;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700398 size_t timeout = 30;
399 size_t keepAliveInterval = 25;
400 bool useMcast = true;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600401 std::string mcastGroup = "224.0.23.170";
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700402 std::string mcastPort = "56363";
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600403
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700404
405 for (ConfigSection::const_iterator i = configSection.begin();
406 i != configSection.end();
407 ++i)
408 {
409 if (i->first == "port")
410 {
411 port = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600412 try
413 {
414 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
415 NFD_LOG_TRACE("UDP port set to " << portNo);
416 }
417 catch (const std::bad_cast& error)
418 {
419 throw ConfigFile::Error("Invalid value for option " +
420 i->first + "\" in \"udp\" section");
421 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700422 }
Steve DiBenedetto95152872014-04-11 12:40:59 -0600423 else if (i->first == "enable_v4")
424 {
425 enableV4 = parseYesNo(i, i->first, "udp");
426 }
427 else if (i->first == "enable_v6")
428 {
429 enableV6 = parseYesNo(i, i->first, "udp");
430 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700431 else if (i->first == "idle_timeout")
432 {
433 try
434 {
435 timeout = i->second.get_value<size_t>();
436 }
437 catch (const std::exception& e)
438 {
439 throw ConfigFile::Error("Invalid value for option \"" +
440 i->first + "\" in \"udp\" section");
441 }
442 }
443 else if (i->first == "keep_alive_interval")
444 {
445 try
446 {
447 keepAliveInterval = i->second.get_value<size_t>();
Alexander Afanasyevefea8fe2014-03-23 00:00:35 -0700448
449 /// \todo Make use of keepAliveInterval
450 (void)(keepAliveInterval);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700451 }
452 catch (const std::exception& e)
453 {
454 throw ConfigFile::Error("Invalid value for option \"" +
455 i->first + "\" in \"udp\" section");
456 }
457 }
458 else if (i->first == "mcast")
459 {
460 useMcast = parseYesNo(i, i->first, "udp");
461 }
462 else if (i->first == "mcast_port")
463 {
464 mcastPort = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600465 try
466 {
467 uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
468 NFD_LOG_TRACE("UDP multicast port set to " << portNo);
469 }
470 catch (const std::bad_cast& error)
471 {
472 throw ConfigFile::Error("Invalid value for option " +
473 i->first + "\" in \"udp\" section");
474 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700475 }
476 else if (i->first == "mcast_group")
477 {
478 using namespace boost::asio::ip;
479 mcastGroup = i->second.get_value<std::string>();
480 try
481 {
482 address mcastGroupTest = address::from_string(mcastGroup);
483 if (!mcastGroupTest.is_v4())
484 {
485 throw ConfigFile::Error("Invalid value for option \"" +
486 i->first + "\" in \"udp\" section");
487 }
488 }
489 catch(const std::runtime_error& e)
490 {
491 throw ConfigFile::Error("Invalid value for option \"" +
492 i->first + "\" in \"udp\" section");
493 }
494 }
495 else
496 {
497 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"udp\" section");
498 }
499 }
500
Steve DiBenedetto95152872014-04-11 12:40:59 -0600501 if (!enableV4 && !enableV6)
502 {
503 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
504 " Remove \"udp\" section to disable UDP channels or"
505 " re-enable at least one channel type.");
506 }
507 else if (useMcast && !enableV4)
508 {
509 throw ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
510 " have been disabled (conflicting configuration options set)");
511 }
512
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700513 /// \todo what is keep alive interval used for?
514
515 if (!isDryRun)
516 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300517 shared_ptr<UdpFactory> factory;
518 bool isReload = false;
519 if (m_factories.count("udp") > 0) {
520 isReload = true;
521 factory = static_pointer_cast<UdpFactory>(m_factories["udp"]);
522 }
523 else {
524 factory = ndn::make_shared<UdpFactory>(port);
525 m_factories.insert(std::make_pair("udp", factory));
526 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700527
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300528 if (!isReload && enableV4)
Steve DiBenedetto95152872014-04-11 12:40:59 -0600529 {
530 shared_ptr<UdpChannel> v4Channel =
531 factory->createChannel("0.0.0.0", port, time::seconds(timeout));
532
533 v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
534 UdpChannel::ConnectFailedCallback());
535
536 m_factories.insert(std::make_pair("udp4", factory));
537 }
538
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300539 if (!isReload && enableV6)
Steve DiBenedetto95152872014-04-11 12:40:59 -0600540 {
541 shared_ptr<UdpChannel> v6Channel =
542 factory->createChannel("::", port, time::seconds(timeout));
543
544 v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
545 UdpChannel::ConnectFailedCallback());
546 m_factories.insert(std::make_pair("udp6", factory));
547 }
548
549 if (useMcast && enableV4)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700550 {
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200551 std::list<shared_ptr<NetworkInterfaceInfo> > ipv4MulticastInterfaces;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600552 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
553 i != nicList.end();
554 ++i)
555 {
556 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
557 if (nic->isUp() && nic->isMulticastCapable() && !nic->ipv4Addresses.empty())
558 {
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200559 ipv4MulticastInterfaces.push_back(nic);
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600560 }
561 }
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200562
563 bool isNicNameNecessary = false;
564
565#if defined(__linux__)
566 if (ipv4MulticastInterfaces.size() > 1)
567 {
568 //On Linux, if we have more than one MulticastUdpFace we need to specify
569 //the name of the interface
570 isNicNameNecessary = true;
571 }
572#endif
573
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300574 std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
575 for (UdpFactory::MulticastFaceMap::const_iterator i =
576 factory->getMulticastFaces().begin();
577 i != factory->getMulticastFaces().end();
578 ++i)
579 {
580 multicastFacesToRemove.push_back(i->second);
581 }
582
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200583 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i =
584 ipv4MulticastInterfaces.begin();
585 i != ipv4MulticastInterfaces.end();
586 ++i)
587 {
588 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
589 shared_ptr<MulticastUdpFace> newFace;
590 newFace = factory->createMulticastFace(nic->ipv4Addresses[0].to_string(),
591 mcastGroup,
592 mcastPort,
593 isNicNameNecessary ? nic->name : "");
594
595 addCreatedFaceToForwarder(newFace);
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300596 multicastFacesToRemove.remove(newFace);
597 }
598
599 for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
600 multicastFacesToRemove.begin();
601 i != multicastFacesToRemove.end();
602 ++i)
603 {
604 (*i)->close();
605 }
606 }
607 else
608 {
609 std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
610 for (UdpFactory::MulticastFaceMap::const_iterator i =
611 factory->getMulticastFaces().begin();
612 i != factory->getMulticastFaces().end();
613 ++i)
614 {
615 multicastFacesToRemove.push_back(i->second);
616 }
617
618 for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
619 multicastFacesToRemove.begin();
620 i != multicastFacesToRemove.end();
621 ++i)
622 {
623 (*i)->close();
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200624 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600625 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700626 }
627}
628
629void
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600630FaceManager::processSectionEther(const ConfigSection& configSection,
631 bool isDryRun,
632 const std::list<shared_ptr<NetworkInterfaceInfo> >& nicList)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700633{
634 // ; the ether section contains settings of Ethernet faces and channels
635 // ether
636 // {
637 // ; NFD creates one Ethernet multicast face per NIC
638 // mcast yes ; set to 'no' to disable Ethernet multicast, default 'yes'
639 // mcast_group 01:00:5E:00:17:AA ; Ethernet multicast group
640 // }
641
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700642#if defined(HAVE_LIBPCAP)
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600643
644 using ethernet::Address;
645
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700646 bool useMcast = true;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600647 Address mcastGroup(ethernet::getDefaultMulticastAddress());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700648
649 for (ConfigSection::const_iterator i = configSection.begin();
650 i != configSection.end();
651 ++i)
652 {
653 if (i->first == "mcast")
654 {
655 useMcast = parseYesNo(i, i->first, "ether");
656 }
657
658 else if (i->first == "mcast_group")
659 {
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600660 mcastGroup = Address::fromString(i->second.get_value<std::string>());
661 if (mcastGroup.isNull())
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700662 {
663 throw ConfigFile::Error("Invalid value for option \"" +
664 i->first + "\" in \"ether\" section");
665 }
666 }
667 else
668 {
669 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"ether\" section");
670 }
671 }
672
673 if (!isDryRun)
674 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300675 shared_ptr<EthernetFactory> factory;
676 if (m_factories.count("ether") > 0) {
677 factory = static_pointer_cast<EthernetFactory>(m_factories["ether"]);
678 }
679 else {
680 factory = ndn::make_shared<EthernetFactory>();
681 m_factories.insert(std::make_pair("ether", factory));
682 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700683
684 if (useMcast)
685 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300686 std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
687 for (EthernetFactory::MulticastFaceMap::const_iterator i =
688 factory->getMulticastFaces().begin();
689 i != factory->getMulticastFaces().end();
690 ++i)
691 {
692 multicastFacesToRemove.push_back(i->second);
693 }
694
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600695 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
696 i != nicList.end();
697 ++i)
698 {
699 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
700 if (nic->isUp() && nic->isMulticastCapable())
701 {
702 try
703 {
704 shared_ptr<EthernetFace> newFace =
Davide Pesaventob60cc122014-03-19 19:26:02 +0100705 factory->createMulticastFace(nic, mcastGroup);
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700706
707 addCreatedFaceToForwarder(newFace);
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300708 multicastFacesToRemove.remove(newFace);
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600709 }
710 catch (const EthernetFactory::Error& factoryError)
711 {
712 NFD_LOG_ERROR(factoryError.what() << ", continuing");
713 }
714 catch (const EthernetFace::Error& faceError)
715 {
716 NFD_LOG_ERROR(faceError.what() << ", continuing");
717 }
718 }
719 }
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300720
721 for (std::list<shared_ptr<EthernetFace> >::iterator i =
722 multicastFacesToRemove.begin();
723 i != multicastFacesToRemove.end();
724 ++i)
725 {
726 (*i)->close();
727 }
728 }
729 else
730 {
731 std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
732 for (EthernetFactory::MulticastFaceMap::const_iterator i =
733 factory->getMulticastFaces().begin();
734 i != factory->getMulticastFaces().end();
735 ++i)
736 {
737 multicastFacesToRemove.push_back(i->second);
738 }
739
740 for (std::list<shared_ptr<EthernetFace> >::iterator i =
741 multicastFacesToRemove.begin();
742 i != multicastFacesToRemove.end();
743 ++i)
744 {
745 (*i)->close();
746 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700747 }
748 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600749#else
750 throw ConfigFile::Error("NFD was compiled without libpcap, cannot process \"ether\" section");
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700751#endif // HAVE_LIBPCAP
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700752}
753
Wentao Shang53df1632014-04-21 12:01:32 -0700754void
755FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool isDryRun)
756{
757 // ; the websocket section contains settings of WebSocket faces and channels
758 // websocket
759 // {
760 // listen yes ; set to 'no' to disable WebSocket listener, default 'yes'
761 // port 9696 ; WebSocket listener port number
762 // enable_v4 yes ; set to 'no' to disable listening on IPv4 socket, default 'yes'
763 // enable_v6 yes ; set to 'no' to disable listening on IPv6 socket, default 'yes'
764 // }
765
766#if defined(HAVE_WEBSOCKET)
767
768 std::string port = "9696";
769 bool needToListen = true;
770 bool enableV4 = true;
771 bool enableV6 = true;
772
773 for (ConfigSection::const_iterator i = configSection.begin();
774 i != configSection.end();
775 ++i)
776 {
777 if (i->first == "port")
778 {
779 port = i->second.get_value<std::string>();
780 try
781 {
782 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
783 NFD_LOG_TRACE("WebSocket port set to " << portNo);
784 }
785 catch (const std::bad_cast& error)
786 {
787 throw ConfigFile::Error("Invalid value for option " +
788 i->first + "\" in \"websocket\" section");
789 }
790 }
791 else if (i->first == "listen")
792 {
793 needToListen = parseYesNo(i, i->first, "websocket");
794 }
795 else if (i->first == "enable_v4")
796 {
797 enableV4 = parseYesNo(i, i->first, "websocket");
798 }
799 else if (i->first == "enable_v6")
800 {
801 enableV6 = parseYesNo(i, i->first, "websocket");
802 }
803 else
804 {
805 throw ConfigFile::Error("Unrecognized option \"" +
806 i->first + "\" in \"websocket\" section");
807 }
808 }
809
810 if (!enableV4 && !enableV6)
811 {
812 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
813 " Remove \"websocket\" section to disable WebSocket channels or"
814 " re-enable at least one channel type.");
815 }
816
817 if (!enableV4 && enableV6)
818 {
819 throw ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel.");
820 }
821
822 if (!isDryRun)
823 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300824 if (m_factories.count("websocket") > 0)
825 {
826 return;
827 }
828
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700829 shared_ptr<WebSocketFactory> factory = ndn::make_shared<WebSocketFactory>(port);
Wentao Shang53df1632014-04-21 12:01:32 -0700830 m_factories.insert(std::make_pair("websocket", factory));
Wentao Shang53df1632014-04-21 12:01:32 -0700831
832 if (enableV6 && enableV4)
833 {
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600834 shared_ptr<WebSocketChannel> ip46Channel = factory->createChannel("::", port);
Wentao Shang53df1632014-04-21 12:01:32 -0700835 if (needToListen)
836 {
837 ip46Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
838 }
839
840 m_factories.insert(std::make_pair("websocket46", factory));
841 }
842 else if (enableV4)
843 {
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600844 shared_ptr<WebSocketChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
Wentao Shang53df1632014-04-21 12:01:32 -0700845 if (needToListen)
846 {
847 ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
848 }
849
850 m_factories.insert(std::make_pair("websocket4", factory));
851 }
852 }
853#else
854 throw ConfigFile::Error("NFD was compiled without WebSocket, "
855 "cannot process \"websocket\" section");
856#endif // HAVE_WEBSOCKET
857}
858
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700859
860void
861FaceManager::onFaceRequest(const Interest& request)
862{
863 const Name& command = request.getName();
864 const size_t commandNComps = command.size();
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600865 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700866
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300867 UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor =
868 m_unsignedVerbDispatch.find(verb);
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600869 if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
870 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700871 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700872 (unsignedVerbProcessor->second)(this, request);
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600873 }
874 else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600875 commandNComps < COMMAND_SIGNED_NCOMPS)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700876 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700877 NFD_LOG_DEBUG("command result: unsigned verb: " << command);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700878 sendResponse(command, 401, "Signature required");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700879 }
880 else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
881 !COMMAND_PREFIX.isPrefixOf(command))
882 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700883 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700884 sendResponse(command, 400, "Malformed command");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700885 }
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600886 else
887 {
888 validate(request,
889 bind(&FaceManager::onValidatedFaceRequest, this, _1),
890 bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
891 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700892}
893
894void
895FaceManager::onValidatedFaceRequest(const shared_ptr<const Interest>& request)
896{
897 const Name& command = request->getName();
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600898 const Name::Component& verb = command[COMMAND_PREFIX.size()];
899 const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700900
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600901 SignedVerbDispatchTable::const_iterator signedVerbProcessor = m_signedVerbDispatch.find(verb);
902 if (signedVerbProcessor != m_signedVerbDispatch.end())
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700903 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600904 ControlParameters parameters;
905 if (!extractParameters(parameterComponent, parameters))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700906 {
907 sendResponse(command, 400, "Malformed command");
908 return;
909 }
910
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700911 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600912 (signedVerbProcessor->second)(this, *request, parameters);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700913 }
914 else
915 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700916 NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700917 sendResponse(command, 501, "Unsupported command");
918 }
919
920}
921
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700922void
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700923FaceManager::addCreatedFaceToForwarder(const shared_ptr<Face>& newFace)
924{
925 m_faceTable.add(newFace);
926
Junxiao Shi6e694322014-04-03 10:27:13 -0700927 //NFD_LOG_DEBUG("Created face " << newFace->getRemoteUri() << " ID " << newFace->getId());
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700928}
929
930void
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700931FaceManager::onCreated(const Name& requestName,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600932 ControlParameters& parameters,
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700933 const shared_ptr<Face>& newFace)
934{
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700935 addCreatedFaceToForwarder(newFace);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600936 parameters.setFaceId(newFace->getId());
Steve DiBenedetto25999282014-05-22 15:25:12 -0600937 parameters.setUri(newFace->getRemoteUri().toString());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700938
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600939 sendResponse(requestName, 200, "Success", parameters.wireEncode());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700940}
941
942void
943FaceManager::onConnectFailed(const Name& requestName, const std::string& reason)
944{
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700945 NFD_LOG_DEBUG("Failed to create face: " << reason);
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600946 sendResponse(requestName, 408, reason);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700947}
948
949void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600950FaceManager::createFace(const Interest& request,
951 ControlParameters& parameters)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700952{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600953 const Name& requestName = request.getName();
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600954 ndn::nfd::FaceCreateCommand command;
955
956 if (!validateParameters(command, parameters))
957 {
958 sendResponse(requestName, 400, "Malformed command");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600959 NFD_LOG_TRACE("invalid control parameters URI");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600960 return;
961 }
962
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700963 FaceUri uri;
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600964 if (!uri.parse(parameters.getUri()))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700965 {
966 sendResponse(requestName, 400, "Malformed command");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600967 NFD_LOG_TRACE("failed to parse URI");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700968 return;
969 }
970
971 FactoryMap::iterator factory = m_factories.find(uri.getScheme());
972 if (factory == m_factories.end())
973 {
974 sendResponse(requestName, 501, "Unsupported protocol");
975 return;
976 }
977
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600978 try
979 {
980 factory->second->createFace(uri,
981 bind(&FaceManager::onCreated,
982 this, requestName, parameters, _1),
983 bind(&FaceManager::onConnectFailed,
984 this, requestName, _1));
985 }
986 catch (const std::runtime_error& error)
987 {
988 std::string errorMessage = "NFD error: ";
989 errorMessage += error.what();
990
991 NFD_LOG_ERROR(errorMessage);
992 sendResponse(requestName, 500, errorMessage);
993 }
994 catch (const std::logic_error& error)
995 {
996 std::string errorMessage = "NFD error: ";
997 errorMessage += error.what();
998
999 NFD_LOG_ERROR(errorMessage);
1000 sendResponse(requestName, 500, errorMessage);
1001 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001002}
1003
1004
1005void
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001006FaceManager::destroyFace(const Interest& request,
1007 ControlParameters& parameters)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001008{
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001009 const Name& requestName = request.getName();
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001010 ndn::nfd::FaceDestroyCommand command;
1011
1012 if (!validateParameters(command, parameters))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001013 {
1014 sendResponse(requestName, 400, "Malformed command");
1015 return;
1016 }
1017
1018 shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001019 if (static_cast<bool>(target))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001020 {
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001021 target->close();
1022 }
Steve DiBenedettoba749052014-03-22 19:54:53 -06001023
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001024 sendResponse(requestName, 200, "Success", parameters.wireEncode());
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001025
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001026}
1027
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001028void
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001029FaceManager::onAddFace(shared_ptr<Face> face)
1030{
Junxiao Shi6e694322014-04-03 10:27:13 -07001031 ndn::nfd::FaceEventNotification notification;
1032 notification.setKind(ndn::nfd::FACE_EVENT_CREATED)
1033 .setFaceId(face->getId())
1034 .setRemoteUri(face->getRemoteUri().toString())
1035 .setLocalUri(face->getLocalUri().toString())
1036 .setFlags(getFaceFlags(*face));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001037
Junxiao Shi6e694322014-04-03 10:27:13 -07001038 m_notificationStream.postNotification(notification);
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001039}
1040
1041void
1042FaceManager::onRemoveFace(shared_ptr<Face> face)
1043{
Junxiao Shi6e694322014-04-03 10:27:13 -07001044 ndn::nfd::FaceEventNotification notification;
1045 notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
1046 .setFaceId(face->getId())
1047 .setRemoteUri(face->getRemoteUri().toString())
1048 .setLocalUri(face->getLocalUri().toString())
1049 .setFlags(getFaceFlags(*face));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001050
Junxiao Shi6e694322014-04-03 10:27:13 -07001051 m_notificationStream.postNotification(notification);
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001052}
1053
1054
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001055bool
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001056FaceManager::extractLocalControlParameters(const Interest& request,
1057 ControlParameters& parameters,
1058 ControlCommand& command,
1059 shared_ptr<LocalFace>& outFace,
1060 LocalControlFeature& outFeature)
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001061{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001062 if (!validateParameters(command, parameters))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001063 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001064 sendResponse(request.getName(), 400, "Malformed command");
1065 return false;
1066 }
1067
1068 shared_ptr<Face> face = m_faceTable.get(request.getIncomingFaceId());
1069
1070 if (!static_cast<bool>(face))
1071 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001072 NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001073 sendResponse(request.getName(), 410, "Face not found");
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001074 return false;
1075 }
1076 else if (!face->isLocal())
1077 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001078 NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
1079 face->getId());
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001080 sendResponse(request.getName(), 412, "Face is non-local");
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001081 return false;
1082 }
1083
1084 outFace = dynamic_pointer_cast<LocalFace>(face);
1085 outFeature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
1086
1087 return true;
1088}
1089
1090void
1091FaceManager::enableLocalControl(const Interest& request,
1092 ControlParameters& parameters)
1093{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001094 ndn::nfd::FaceEnableLocalControlCommand command;
1095
1096
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001097 shared_ptr<LocalFace> face;
1098 LocalControlFeature feature;
1099
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001100 if (extractLocalControlParameters(request, parameters, command, face, feature))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001101 {
1102 face->setLocalControlHeaderFeature(feature, true);
1103 sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
1104 }
1105}
1106
1107void
1108FaceManager::disableLocalControl(const Interest& request,
1109 ControlParameters& parameters)
1110{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001111 ndn::nfd::FaceDisableLocalControlCommand command;
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001112 shared_ptr<LocalFace> face;
1113 LocalControlFeature feature;
1114
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001115 if (extractLocalControlParameters(request, parameters, command, face, feature))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001116 {
1117 face->setLocalControlHeaderFeature(feature, false);
1118 sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
1119 }
1120}
1121
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001122void
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001123FaceManager::listFaces(const Interest& request)
1124{
1125 const Name& command = request.getName();
1126 const size_t commandNComps = command.size();
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001127
Steve DiBenedettoef04f272014-06-04 14:28:31 -06001128 if (commandNComps < FACES_LIST_DATASET_NCOMPS ||
1129 !FACES_LIST_DATASET_PREFIX.isPrefixOf(command))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001130 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001131 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001132 sendResponse(command, 400, "Malformed command");
1133 return;
1134 }
1135
Steve DiBenedettoef04f272014-06-04 14:28:31 -06001136 m_faceStatusPublisher.publish();
1137}
1138
1139void
1140FaceManager::listChannels(const Interest& request)
1141{
1142 NFD_LOG_DEBUG("in listChannels");
1143 const Name& command = request.getName();
1144 const size_t commandNComps = command.size();
1145
1146 if (commandNComps < CHANNELS_LIST_DATASET_NCOMPS ||
1147 !CHANNELS_LIST_DATASET_PREFIX.isPrefixOf(command))
1148 {
1149 NFD_LOG_DEBUG("command result: malformed");
1150 sendResponse(command, 400, "Malformed command");
1151 return;
1152 }
1153
1154 NFD_LOG_DEBUG("publishing");
1155 m_channelStatusPublisher.publish();
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001156}
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001157
Alexander Afanasyev5959b012014-06-02 19:18:12 +03001158shared_ptr<ProtocolFactory>
1159FaceManager::findFactory(const std::string& protocol)
1160{
1161 FactoryMap::iterator factory = m_factories.find(protocol);
1162 if (factory != m_factories.end())
1163 return factory->second;
1164 else
1165 return shared_ptr<ProtocolFactory>();
1166}
1167
1168
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001169} // namespace nfd