blob: c8bc267ace9d66172c04680d4fd635ce164a26f6 [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,
Vince Lehman5144f822014-07-23 15:12:56 -0700116 shared_ptr<InternalFace> face,
117 ndn::KeyChain& keyChain)
118 : ManagerBase(face, FACE_MANAGER_PRIVILEGE, keyChain)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700119 , m_faceTable(faceTable)
Vince Lehman5144f822014-07-23 15:12:56 -0700120 , m_faceStatusPublisher(m_faceTable, *m_face, FACES_LIST_DATASET_PREFIX, keyChain)
121 , m_channelStatusPublisher(m_factories, *m_face, CHANNELS_LIST_DATASET_PREFIX, keyChain)
122 , m_notificationStream(m_face, FACE_EVENTS_PREFIX, keyChain)
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600123 , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600124 SIGNED_COMMAND_VERBS +
125 (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600126 , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600127 UNSIGNED_COMMAND_VERBS +
128 (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600129
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700130{
131 face->setInterestFilter("/localhost/nfd/faces",
132 bind(&FaceManager::onFaceRequest, this, _2));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600133
134 m_faceTable.onAdd += bind(&FaceManager::onAddFace, this, _1);
135 m_faceTable.onRemove += bind(&FaceManager::onRemoveFace, this, _1);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700136}
137
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600138FaceManager::~FaceManager()
139{
140
141}
142
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700143void
144FaceManager::setConfigFile(ConfigFile& configFile)
145{
146 configFile.addSectionHandler("face_system",
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600147 bind(&FaceManager::onConfig, this, _1, _2, _3));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700148}
149
150
151void
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600152FaceManager::onConfig(const ConfigSection& configSection,
153 bool isDryRun,
154 const std::string& filename)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700155{
156 bool hasSeenUnix = false;
157 bool hasSeenTcp = false;
158 bool hasSeenUdp = false;
159 bool hasSeenEther = false;
Wentao Shang53df1632014-04-21 12:01:32 -0700160 bool hasSeenWebSocket = false;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700161
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600162 const std::list<shared_ptr<NetworkInterfaceInfo> > nicList(listNetworkInterfaces());
163
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700164 for (ConfigSection::const_iterator item = configSection.begin();
165 item != configSection.end();
166 ++item)
167 {
168 if (item->first == "unix")
169 {
170 if (hasSeenUnix)
171 throw Error("Duplicate \"unix\" section");
172 hasSeenUnix = true;
173
174 processSectionUnix(item->second, isDryRun);
175 }
176 else if (item->first == "tcp")
177 {
178 if (hasSeenTcp)
179 throw Error("Duplicate \"tcp\" section");
180 hasSeenTcp = true;
181
182 processSectionTcp(item->second, isDryRun);
183 }
184 else if (item->first == "udp")
185 {
186 if (hasSeenUdp)
187 throw Error("Duplicate \"udp\" section");
188 hasSeenUdp = true;
189
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600190 processSectionUdp(item->second, isDryRun, nicList);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700191 }
192 else if (item->first == "ether")
193 {
194 if (hasSeenEther)
195 throw Error("Duplicate \"ether\" section");
196 hasSeenEther = true;
197
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600198 processSectionEther(item->second, isDryRun, nicList);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700199 }
Wentao Shang53df1632014-04-21 12:01:32 -0700200 else if (item->first == "websocket")
201 {
202 if (hasSeenWebSocket)
203 throw Error("Duplicate \"websocket\" section");
204 hasSeenWebSocket = true;
205
206 processSectionWebSocket(item->second, isDryRun);
207 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700208 else
209 {
210 throw Error("Unrecognized option \"" + item->first + "\"");
211 }
212 }
213}
214
215void
216FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRun)
217{
218 // ; the unix section contains settings of UNIX stream faces and channels
219 // unix
220 // {
221 // listen yes ; set to 'no' to disable UNIX stream listener, default 'yes'
222 // path /var/run/nfd.sock ; UNIX stream listener path
223 // }
224
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600225#if defined(HAVE_UNIX_SOCKETS)
226
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700227 bool needToListen = true;
228 std::string path = "/var/run/nfd.sock";
229
230 for (ConfigSection::const_iterator i = configSection.begin();
231 i != configSection.end();
232 ++i)
233 {
234 if (i->first == "path")
235 {
236 path = i->second.get_value<std::string>();
237 }
238 else if (i->first == "listen")
239 {
240 needToListen = parseYesNo(i, i->first, "unix");
241 }
242 else
243 {
244 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"unix\" section");
245 }
246 }
247
248 if (!isDryRun)
249 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300250 if (m_factories.count("unix") > 0)
251 {
252 return;
253 // shared_ptr<UnixStreamFactory> factory
254 // = static_pointer_cast<UnixStreamFactory>(m_factories["unix"]);
255 // shared_ptr<UnixStreamChannel> unixChannel = factory->findChannel(path);
256
257 // if (static_cast<bool>(unixChannel))
258 // {
259 // return;
260 // }
261 }
262
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700263 shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
264 shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
265
266 if (needToListen)
267 {
268 // Should acceptFailed callback be used somehow?
269 unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
270 UnixStreamChannel::ConnectFailedCallback());
271 }
272
273 m_factories.insert(std::make_pair("unix", factory));
274 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600275#else
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300276 throw ConfigFile::Error("NFD was compiled without UNIX sockets support, "
277 "cannot process \"unix\" section");
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600278#endif // HAVE_UNIX_SOCKETS
279
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700280}
281
282void
283FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun)
284{
285 // ; the tcp section contains settings of TCP faces and channels
286 // tcp
287 // {
288 // listen yes ; set to 'no' to disable TCP listener, default 'yes'
289 // port 6363 ; TCP listener port number
290 // }
291
292 std::string port = "6363";
293 bool needToListen = true;
Steve DiBenedetto95152872014-04-11 12:40:59 -0600294 bool enableV4 = true;
295 bool enableV6 = true;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700296
297 for (ConfigSection::const_iterator i = configSection.begin();
298 i != configSection.end();
299 ++i)
300 {
301 if (i->first == "port")
302 {
303 port = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600304 try
305 {
306 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
307 NFD_LOG_TRACE("TCP port set to " << portNo);
308 }
309 catch (const std::bad_cast& error)
310 {
311 throw ConfigFile::Error("Invalid value for option " +
Steve DiBenedetto95152872014-04-11 12:40:59 -0600312 i->first + "\" in \"tcp\" section");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600313 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700314 }
315 else if (i->first == "listen")
316 {
317 needToListen = parseYesNo(i, i->first, "tcp");
318 }
Steve DiBenedetto95152872014-04-11 12:40:59 -0600319 else if (i->first == "enable_v4")
320 {
321 enableV4 = parseYesNo(i, i->first, "tcp");
322 }
323 else if (i->first == "enable_v6")
324 {
325 enableV6 = parseYesNo(i, i->first, "tcp");
326 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700327 else
328 {
329 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
330 }
331 }
332
Steve DiBenedetto95152872014-04-11 12:40:59 -0600333 if (!enableV4 && !enableV6)
334 {
335 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
336 " Remove \"tcp\" section to disable TCP channels or"
337 " re-enable at least one channel type.");
338 }
339
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700340 if (!isDryRun)
341 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300342 if (m_factories.count("tcp") > 0)
343 {
344 return;
345 }
346
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700347 shared_ptr<TcpFactory> factory = ndn::make_shared<TcpFactory>(port);
Steve DiBenedetto95152872014-04-11 12:40:59 -0600348 m_factories.insert(std::make_pair("tcp", factory));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700349
Steve DiBenedetto95152872014-04-11 12:40:59 -0600350 if (enableV4)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700351 {
Steve DiBenedetto95152872014-04-11 12:40:59 -0600352 shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
353 if (needToListen)
354 {
355 // Should acceptFailed callback be used somehow?
356 ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
357 TcpChannel::ConnectFailedCallback());
358 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700359
Steve DiBenedetto95152872014-04-11 12:40:59 -0600360 m_factories.insert(std::make_pair("tcp4", factory));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700361 }
362
Steve DiBenedetto95152872014-04-11 12:40:59 -0600363 if (enableV6)
364 {
365 shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
366 if (needToListen)
367 {
368 // Should acceptFailed callback be used somehow?
369 ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
370 TcpChannel::ConnectFailedCallback());
371 }
372
373 m_factories.insert(std::make_pair("tcp6", factory));
374 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700375 }
376}
377
378void
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600379FaceManager::processSectionUdp(const ConfigSection& configSection,
380 bool isDryRun,
381 const std::list<shared_ptr<NetworkInterfaceInfo> >& nicList)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700382{
383 // ; the udp section contains settings of UDP faces and channels
384 // udp
385 // {
386 // port 6363 ; UDP unicast port number
387 // idle_timeout 30 ; idle time (seconds) before closing a UDP unicast face
388 // keep_alive_interval 25; interval (seconds) between keep-alive refreshes
389
390 // ; NFD creates one UDP multicast face per NIC
391 // mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
392 // mcast_port 56363 ; UDP multicast port number
393 // mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
394 // }
395
396 std::string port = "6363";
Steve DiBenedetto95152872014-04-11 12:40:59 -0600397 bool enableV4 = true;
398 bool enableV6 = true;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700399 size_t timeout = 30;
400 size_t keepAliveInterval = 25;
401 bool useMcast = true;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600402 std::string mcastGroup = "224.0.23.170";
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700403 std::string mcastPort = "56363";
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600404
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700405
406 for (ConfigSection::const_iterator i = configSection.begin();
407 i != configSection.end();
408 ++i)
409 {
410 if (i->first == "port")
411 {
412 port = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600413 try
414 {
415 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
416 NFD_LOG_TRACE("UDP port set to " << portNo);
417 }
418 catch (const std::bad_cast& error)
419 {
420 throw ConfigFile::Error("Invalid value for option " +
421 i->first + "\" in \"udp\" section");
422 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700423 }
Steve DiBenedetto95152872014-04-11 12:40:59 -0600424 else if (i->first == "enable_v4")
425 {
426 enableV4 = parseYesNo(i, i->first, "udp");
427 }
428 else if (i->first == "enable_v6")
429 {
430 enableV6 = parseYesNo(i, i->first, "udp");
431 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700432 else if (i->first == "idle_timeout")
433 {
434 try
435 {
436 timeout = i->second.get_value<size_t>();
437 }
438 catch (const std::exception& e)
439 {
440 throw ConfigFile::Error("Invalid value for option \"" +
441 i->first + "\" in \"udp\" section");
442 }
443 }
444 else if (i->first == "keep_alive_interval")
445 {
446 try
447 {
448 keepAliveInterval = i->second.get_value<size_t>();
Alexander Afanasyevefea8fe2014-03-23 00:00:35 -0700449
450 /// \todo Make use of keepAliveInterval
451 (void)(keepAliveInterval);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700452 }
453 catch (const std::exception& e)
454 {
455 throw ConfigFile::Error("Invalid value for option \"" +
456 i->first + "\" in \"udp\" section");
457 }
458 }
459 else if (i->first == "mcast")
460 {
461 useMcast = parseYesNo(i, i->first, "udp");
462 }
463 else if (i->first == "mcast_port")
464 {
465 mcastPort = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600466 try
467 {
468 uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
469 NFD_LOG_TRACE("UDP multicast port set to " << portNo);
470 }
471 catch (const std::bad_cast& error)
472 {
473 throw ConfigFile::Error("Invalid value for option " +
474 i->first + "\" in \"udp\" section");
475 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700476 }
477 else if (i->first == "mcast_group")
478 {
479 using namespace boost::asio::ip;
480 mcastGroup = i->second.get_value<std::string>();
481 try
482 {
483 address mcastGroupTest = address::from_string(mcastGroup);
484 if (!mcastGroupTest.is_v4())
485 {
486 throw ConfigFile::Error("Invalid value for option \"" +
487 i->first + "\" in \"udp\" section");
488 }
489 }
490 catch(const std::runtime_error& e)
491 {
492 throw ConfigFile::Error("Invalid value for option \"" +
493 i->first + "\" in \"udp\" section");
494 }
495 }
496 else
497 {
498 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"udp\" section");
499 }
500 }
501
Steve DiBenedetto95152872014-04-11 12:40:59 -0600502 if (!enableV4 && !enableV6)
503 {
504 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
505 " Remove \"udp\" section to disable UDP channels or"
506 " re-enable at least one channel type.");
507 }
508 else if (useMcast && !enableV4)
509 {
510 throw ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
511 " have been disabled (conflicting configuration options set)");
512 }
513
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700514 /// \todo what is keep alive interval used for?
515
516 if (!isDryRun)
517 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300518 shared_ptr<UdpFactory> factory;
519 bool isReload = false;
520 if (m_factories.count("udp") > 0) {
521 isReload = true;
522 factory = static_pointer_cast<UdpFactory>(m_factories["udp"]);
523 }
524 else {
525 factory = ndn::make_shared<UdpFactory>(port);
526 m_factories.insert(std::make_pair("udp", factory));
527 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700528
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300529 if (!isReload && enableV4)
Steve DiBenedetto95152872014-04-11 12:40:59 -0600530 {
531 shared_ptr<UdpChannel> v4Channel =
532 factory->createChannel("0.0.0.0", port, time::seconds(timeout));
533
534 v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
535 UdpChannel::ConnectFailedCallback());
536
537 m_factories.insert(std::make_pair("udp4", factory));
538 }
539
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300540 if (!isReload && enableV6)
Steve DiBenedetto95152872014-04-11 12:40:59 -0600541 {
542 shared_ptr<UdpChannel> v6Channel =
543 factory->createChannel("::", port, time::seconds(timeout));
544
545 v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
546 UdpChannel::ConnectFailedCallback());
547 m_factories.insert(std::make_pair("udp6", factory));
548 }
549
550 if (useMcast && enableV4)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700551 {
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200552 std::list<shared_ptr<NetworkInterfaceInfo> > ipv4MulticastInterfaces;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600553 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
554 i != nicList.end();
555 ++i)
556 {
557 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
558 if (nic->isUp() && nic->isMulticastCapable() && !nic->ipv4Addresses.empty())
559 {
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200560 ipv4MulticastInterfaces.push_back(nic);
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600561 }
562 }
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200563
564 bool isNicNameNecessary = false;
565
566#if defined(__linux__)
567 if (ipv4MulticastInterfaces.size() > 1)
568 {
569 //On Linux, if we have more than one MulticastUdpFace we need to specify
570 //the name of the interface
571 isNicNameNecessary = true;
572 }
573#endif
574
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300575 std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
576 for (UdpFactory::MulticastFaceMap::const_iterator i =
577 factory->getMulticastFaces().begin();
578 i != factory->getMulticastFaces().end();
579 ++i)
580 {
581 multicastFacesToRemove.push_back(i->second);
582 }
583
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200584 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i =
585 ipv4MulticastInterfaces.begin();
586 i != ipv4MulticastInterfaces.end();
587 ++i)
588 {
589 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
590 shared_ptr<MulticastUdpFace> newFace;
591 newFace = factory->createMulticastFace(nic->ipv4Addresses[0].to_string(),
592 mcastGroup,
593 mcastPort,
594 isNicNameNecessary ? nic->name : "");
595
596 addCreatedFaceToForwarder(newFace);
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300597 multicastFacesToRemove.remove(newFace);
598 }
599
600 for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
601 multicastFacesToRemove.begin();
602 i != multicastFacesToRemove.end();
603 ++i)
604 {
605 (*i)->close();
606 }
607 }
608 else
609 {
610 std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
611 for (UdpFactory::MulticastFaceMap::const_iterator i =
612 factory->getMulticastFaces().begin();
613 i != factory->getMulticastFaces().end();
614 ++i)
615 {
616 multicastFacesToRemove.push_back(i->second);
617 }
618
619 for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
620 multicastFacesToRemove.begin();
621 i != multicastFacesToRemove.end();
622 ++i)
623 {
624 (*i)->close();
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200625 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600626 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700627 }
628}
629
630void
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600631FaceManager::processSectionEther(const ConfigSection& configSection,
632 bool isDryRun,
633 const std::list<shared_ptr<NetworkInterfaceInfo> >& nicList)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700634{
635 // ; the ether section contains settings of Ethernet faces and channels
636 // ether
637 // {
638 // ; NFD creates one Ethernet multicast face per NIC
639 // mcast yes ; set to 'no' to disable Ethernet multicast, default 'yes'
640 // mcast_group 01:00:5E:00:17:AA ; Ethernet multicast group
641 // }
642
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700643#if defined(HAVE_LIBPCAP)
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600644
645 using ethernet::Address;
646
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700647 bool useMcast = true;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600648 Address mcastGroup(ethernet::getDefaultMulticastAddress());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700649
650 for (ConfigSection::const_iterator i = configSection.begin();
651 i != configSection.end();
652 ++i)
653 {
654 if (i->first == "mcast")
655 {
656 useMcast = parseYesNo(i, i->first, "ether");
657 }
658
659 else if (i->first == "mcast_group")
660 {
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600661 mcastGroup = Address::fromString(i->second.get_value<std::string>());
662 if (mcastGroup.isNull())
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700663 {
664 throw ConfigFile::Error("Invalid value for option \"" +
665 i->first + "\" in \"ether\" section");
666 }
667 }
668 else
669 {
670 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"ether\" section");
671 }
672 }
673
674 if (!isDryRun)
675 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300676 shared_ptr<EthernetFactory> factory;
677 if (m_factories.count("ether") > 0) {
678 factory = static_pointer_cast<EthernetFactory>(m_factories["ether"]);
679 }
680 else {
681 factory = ndn::make_shared<EthernetFactory>();
682 m_factories.insert(std::make_pair("ether", factory));
683 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700684
685 if (useMcast)
686 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300687 std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
688 for (EthernetFactory::MulticastFaceMap::const_iterator i =
689 factory->getMulticastFaces().begin();
690 i != factory->getMulticastFaces().end();
691 ++i)
692 {
693 multicastFacesToRemove.push_back(i->second);
694 }
695
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600696 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
697 i != nicList.end();
698 ++i)
699 {
700 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
701 if (nic->isUp() && nic->isMulticastCapable())
702 {
703 try
704 {
705 shared_ptr<EthernetFace> newFace =
Davide Pesaventob60cc122014-03-19 19:26:02 +0100706 factory->createMulticastFace(nic, mcastGroup);
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700707
708 addCreatedFaceToForwarder(newFace);
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300709 multicastFacesToRemove.remove(newFace);
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600710 }
711 catch (const EthernetFactory::Error& factoryError)
712 {
713 NFD_LOG_ERROR(factoryError.what() << ", continuing");
714 }
715 catch (const EthernetFace::Error& faceError)
716 {
717 NFD_LOG_ERROR(faceError.what() << ", continuing");
718 }
719 }
720 }
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300721
722 for (std::list<shared_ptr<EthernetFace> >::iterator i =
723 multicastFacesToRemove.begin();
724 i != multicastFacesToRemove.end();
725 ++i)
726 {
727 (*i)->close();
728 }
729 }
730 else
731 {
732 std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
733 for (EthernetFactory::MulticastFaceMap::const_iterator i =
734 factory->getMulticastFaces().begin();
735 i != factory->getMulticastFaces().end();
736 ++i)
737 {
738 multicastFacesToRemove.push_back(i->second);
739 }
740
741 for (std::list<shared_ptr<EthernetFace> >::iterator i =
742 multicastFacesToRemove.begin();
743 i != multicastFacesToRemove.end();
744 ++i)
745 {
746 (*i)->close();
747 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700748 }
749 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600750#else
751 throw ConfigFile::Error("NFD was compiled without libpcap, cannot process \"ether\" section");
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700752#endif // HAVE_LIBPCAP
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700753}
754
Wentao Shang53df1632014-04-21 12:01:32 -0700755void
756FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool isDryRun)
757{
758 // ; the websocket section contains settings of WebSocket faces and channels
759 // websocket
760 // {
761 // listen yes ; set to 'no' to disable WebSocket listener, default 'yes'
762 // port 9696 ; WebSocket listener port number
763 // enable_v4 yes ; set to 'no' to disable listening on IPv4 socket, default 'yes'
764 // enable_v6 yes ; set to 'no' to disable listening on IPv6 socket, default 'yes'
765 // }
766
767#if defined(HAVE_WEBSOCKET)
768
769 std::string port = "9696";
770 bool needToListen = true;
771 bool enableV4 = true;
772 bool enableV6 = true;
773
774 for (ConfigSection::const_iterator i = configSection.begin();
775 i != configSection.end();
776 ++i)
777 {
778 if (i->first == "port")
779 {
780 port = i->second.get_value<std::string>();
781 try
782 {
783 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
784 NFD_LOG_TRACE("WebSocket port set to " << portNo);
785 }
786 catch (const std::bad_cast& error)
787 {
788 throw ConfigFile::Error("Invalid value for option " +
789 i->first + "\" in \"websocket\" section");
790 }
791 }
792 else if (i->first == "listen")
793 {
794 needToListen = parseYesNo(i, i->first, "websocket");
795 }
796 else if (i->first == "enable_v4")
797 {
798 enableV4 = parseYesNo(i, i->first, "websocket");
799 }
800 else if (i->first == "enable_v6")
801 {
802 enableV6 = parseYesNo(i, i->first, "websocket");
803 }
804 else
805 {
806 throw ConfigFile::Error("Unrecognized option \"" +
807 i->first + "\" in \"websocket\" section");
808 }
809 }
810
811 if (!enableV4 && !enableV6)
812 {
813 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
814 " Remove \"websocket\" section to disable WebSocket channels or"
815 " re-enable at least one channel type.");
816 }
817
818 if (!enableV4 && enableV6)
819 {
820 throw ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel.");
821 }
822
823 if (!isDryRun)
824 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300825 if (m_factories.count("websocket") > 0)
826 {
827 return;
828 }
829
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700830 shared_ptr<WebSocketFactory> factory = ndn::make_shared<WebSocketFactory>(port);
Wentao Shang53df1632014-04-21 12:01:32 -0700831 m_factories.insert(std::make_pair("websocket", factory));
Wentao Shang53df1632014-04-21 12:01:32 -0700832
833 if (enableV6 && enableV4)
834 {
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600835 shared_ptr<WebSocketChannel> ip46Channel = factory->createChannel("::", port);
Wentao Shang53df1632014-04-21 12:01:32 -0700836 if (needToListen)
837 {
838 ip46Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
839 }
840
841 m_factories.insert(std::make_pair("websocket46", factory));
842 }
843 else if (enableV4)
844 {
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600845 shared_ptr<WebSocketChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
Wentao Shang53df1632014-04-21 12:01:32 -0700846 if (needToListen)
847 {
848 ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
849 }
850
851 m_factories.insert(std::make_pair("websocket4", factory));
852 }
853 }
854#else
855 throw ConfigFile::Error("NFD was compiled without WebSocket, "
856 "cannot process \"websocket\" section");
857#endif // HAVE_WEBSOCKET
858}
859
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700860
861void
862FaceManager::onFaceRequest(const Interest& request)
863{
864 const Name& command = request.getName();
865 const size_t commandNComps = command.size();
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600866 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700867
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300868 UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor =
869 m_unsignedVerbDispatch.find(verb);
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600870 if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
871 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700872 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700873 (unsignedVerbProcessor->second)(this, request);
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600874 }
875 else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600876 commandNComps < COMMAND_SIGNED_NCOMPS)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700877 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700878 NFD_LOG_DEBUG("command result: unsigned verb: " << command);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700879 sendResponse(command, 401, "Signature required");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700880 }
881 else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
882 !COMMAND_PREFIX.isPrefixOf(command))
883 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700884 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700885 sendResponse(command, 400, "Malformed command");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700886 }
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600887 else
888 {
889 validate(request,
890 bind(&FaceManager::onValidatedFaceRequest, this, _1),
891 bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
892 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700893}
894
895void
896FaceManager::onValidatedFaceRequest(const shared_ptr<const Interest>& request)
897{
898 const Name& command = request->getName();
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600899 const Name::Component& verb = command[COMMAND_PREFIX.size()];
900 const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700901
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600902 SignedVerbDispatchTable::const_iterator signedVerbProcessor = m_signedVerbDispatch.find(verb);
903 if (signedVerbProcessor != m_signedVerbDispatch.end())
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700904 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600905 ControlParameters parameters;
906 if (!extractParameters(parameterComponent, parameters))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700907 {
908 sendResponse(command, 400, "Malformed command");
909 return;
910 }
911
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700912 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600913 (signedVerbProcessor->second)(this, *request, parameters);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700914 }
915 else
916 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700917 NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700918 sendResponse(command, 501, "Unsupported command");
919 }
920
921}
922
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700923void
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700924FaceManager::addCreatedFaceToForwarder(const shared_ptr<Face>& newFace)
925{
926 m_faceTable.add(newFace);
927
Junxiao Shi6e694322014-04-03 10:27:13 -0700928 //NFD_LOG_DEBUG("Created face " << newFace->getRemoteUri() << " ID " << newFace->getId());
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700929}
930
931void
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700932FaceManager::onCreated(const Name& requestName,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600933 ControlParameters& parameters,
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700934 const shared_ptr<Face>& newFace)
935{
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700936 addCreatedFaceToForwarder(newFace);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600937 parameters.setFaceId(newFace->getId());
Steve DiBenedetto25999282014-05-22 15:25:12 -0600938 parameters.setUri(newFace->getRemoteUri().toString());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700939
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600940 sendResponse(requestName, 200, "Success", parameters.wireEncode());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700941}
942
943void
944FaceManager::onConnectFailed(const Name& requestName, const std::string& reason)
945{
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700946 NFD_LOG_DEBUG("Failed to create face: " << reason);
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600947 sendResponse(requestName, 408, reason);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700948}
949
950void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600951FaceManager::createFace(const Interest& request,
952 ControlParameters& parameters)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700953{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600954 const Name& requestName = request.getName();
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600955 ndn::nfd::FaceCreateCommand command;
956
957 if (!validateParameters(command, parameters))
958 {
959 sendResponse(requestName, 400, "Malformed command");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600960 NFD_LOG_TRACE("invalid control parameters URI");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600961 return;
962 }
963
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700964 FaceUri uri;
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600965 if (!uri.parse(parameters.getUri()))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700966 {
967 sendResponse(requestName, 400, "Malformed command");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600968 NFD_LOG_TRACE("failed to parse URI");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700969 return;
970 }
971
972 FactoryMap::iterator factory = m_factories.find(uri.getScheme());
973 if (factory == m_factories.end())
974 {
975 sendResponse(requestName, 501, "Unsupported protocol");
976 return;
977 }
978
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600979 try
980 {
981 factory->second->createFace(uri,
982 bind(&FaceManager::onCreated,
983 this, requestName, parameters, _1),
984 bind(&FaceManager::onConnectFailed,
985 this, requestName, _1));
986 }
987 catch (const std::runtime_error& error)
988 {
989 std::string errorMessage = "NFD error: ";
990 errorMessage += error.what();
991
992 NFD_LOG_ERROR(errorMessage);
993 sendResponse(requestName, 500, errorMessage);
994 }
995 catch (const std::logic_error& error)
996 {
997 std::string errorMessage = "NFD error: ";
998 errorMessage += error.what();
999
1000 NFD_LOG_ERROR(errorMessage);
1001 sendResponse(requestName, 500, errorMessage);
1002 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001003}
1004
1005
1006void
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001007FaceManager::destroyFace(const Interest& request,
1008 ControlParameters& parameters)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001009{
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001010 const Name& requestName = request.getName();
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001011 ndn::nfd::FaceDestroyCommand command;
1012
1013 if (!validateParameters(command, parameters))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001014 {
1015 sendResponse(requestName, 400, "Malformed command");
1016 return;
1017 }
1018
1019 shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001020 if (static_cast<bool>(target))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001021 {
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001022 target->close();
1023 }
Steve DiBenedettoba749052014-03-22 19:54:53 -06001024
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001025 sendResponse(requestName, 200, "Success", parameters.wireEncode());
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001026
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001027}
1028
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001029void
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001030FaceManager::onAddFace(shared_ptr<Face> face)
1031{
Junxiao Shi6e694322014-04-03 10:27:13 -07001032 ndn::nfd::FaceEventNotification notification;
1033 notification.setKind(ndn::nfd::FACE_EVENT_CREATED)
1034 .setFaceId(face->getId())
1035 .setRemoteUri(face->getRemoteUri().toString())
1036 .setLocalUri(face->getLocalUri().toString())
1037 .setFlags(getFaceFlags(*face));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001038
Junxiao Shi6e694322014-04-03 10:27:13 -07001039 m_notificationStream.postNotification(notification);
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001040}
1041
1042void
1043FaceManager::onRemoveFace(shared_ptr<Face> face)
1044{
Junxiao Shi6e694322014-04-03 10:27:13 -07001045 ndn::nfd::FaceEventNotification notification;
1046 notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
1047 .setFaceId(face->getId())
1048 .setRemoteUri(face->getRemoteUri().toString())
1049 .setLocalUri(face->getLocalUri().toString())
1050 .setFlags(getFaceFlags(*face));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001051
Junxiao Shi6e694322014-04-03 10:27:13 -07001052 m_notificationStream.postNotification(notification);
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001053}
1054
1055
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001056bool
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001057FaceManager::extractLocalControlParameters(const Interest& request,
1058 ControlParameters& parameters,
1059 ControlCommand& command,
1060 shared_ptr<LocalFace>& outFace,
1061 LocalControlFeature& outFeature)
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001062{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001063 if (!validateParameters(command, parameters))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001064 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001065 sendResponse(request.getName(), 400, "Malformed command");
1066 return false;
1067 }
1068
1069 shared_ptr<Face> face = m_faceTable.get(request.getIncomingFaceId());
1070
1071 if (!static_cast<bool>(face))
1072 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001073 NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001074 sendResponse(request.getName(), 410, "Face not found");
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001075 return false;
1076 }
1077 else if (!face->isLocal())
1078 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001079 NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
1080 face->getId());
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001081 sendResponse(request.getName(), 412, "Face is non-local");
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001082 return false;
1083 }
1084
1085 outFace = dynamic_pointer_cast<LocalFace>(face);
1086 outFeature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
1087
1088 return true;
1089}
1090
1091void
1092FaceManager::enableLocalControl(const Interest& request,
1093 ControlParameters& parameters)
1094{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001095 ndn::nfd::FaceEnableLocalControlCommand command;
1096
1097
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001098 shared_ptr<LocalFace> face;
1099 LocalControlFeature feature;
1100
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001101 if (extractLocalControlParameters(request, parameters, command, face, feature))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001102 {
1103 face->setLocalControlHeaderFeature(feature, true);
1104 sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
1105 }
1106}
1107
1108void
1109FaceManager::disableLocalControl(const Interest& request,
1110 ControlParameters& parameters)
1111{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001112 ndn::nfd::FaceDisableLocalControlCommand command;
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001113 shared_ptr<LocalFace> face;
1114 LocalControlFeature feature;
1115
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001116 if (extractLocalControlParameters(request, parameters, command, face, feature))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001117 {
1118 face->setLocalControlHeaderFeature(feature, false);
1119 sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
1120 }
1121}
1122
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001123void
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001124FaceManager::listFaces(const Interest& request)
1125{
1126 const Name& command = request.getName();
1127 const size_t commandNComps = command.size();
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001128
Steve DiBenedettoef04f272014-06-04 14:28:31 -06001129 if (commandNComps < FACES_LIST_DATASET_NCOMPS ||
1130 !FACES_LIST_DATASET_PREFIX.isPrefixOf(command))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001131 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001132 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001133 sendResponse(command, 400, "Malformed command");
1134 return;
1135 }
1136
Steve DiBenedettoef04f272014-06-04 14:28:31 -06001137 m_faceStatusPublisher.publish();
1138}
1139
1140void
1141FaceManager::listChannels(const Interest& request)
1142{
1143 NFD_LOG_DEBUG("in listChannels");
1144 const Name& command = request.getName();
1145 const size_t commandNComps = command.size();
1146
1147 if (commandNComps < CHANNELS_LIST_DATASET_NCOMPS ||
1148 !CHANNELS_LIST_DATASET_PREFIX.isPrefixOf(command))
1149 {
1150 NFD_LOG_DEBUG("command result: malformed");
1151 sendResponse(command, 400, "Malformed command");
1152 return;
1153 }
1154
1155 NFD_LOG_DEBUG("publishing");
1156 m_channelStatusPublisher.publish();
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001157}
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001158
Alexander Afanasyev5959b012014-06-02 19:18:12 +03001159shared_ptr<ProtocolFactory>
1160FaceManager::findFactory(const std::string& protocol)
1161{
1162 FactoryMap::iterator factory = m_factories.find(protocol);
1163 if (factory != m_factories.end())
1164 return factory->second;
1165 else
1166 return shared_ptr<ProtocolFactory>();
1167}
1168
1169
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001170} // namespace nfd