blob: e33bbe7169eab153b6aa1989f0bceace5fbfb713 [file] [log] [blame]
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * 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 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070024
25#include "face-manager.hpp"
26
Davide Pesavento52a18f92014-04-10 00:55:01 +020027#include "face-flags.hpp"
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"
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070032#include "face/tcp-factory.hpp"
33#include "face/udp-factory.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070034#include "core/config-file.hpp"
Steve DiBenedettofbb40a82014-03-11 19:40:15 -060035
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -060036#ifdef HAVE_UNIX_SOCKETS
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070037#include "face/unix-stream-factory.hpp"
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -060038#endif // HAVE_UNIX_SOCKETS
39
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070040#ifdef HAVE_LIBPCAP
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070041#include "face/ethernet-factory.hpp"
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070042#endif // HAVE_LIBPCAP
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070043
Wentao Shang53df1632014-04-21 12:01:32 -070044#ifdef HAVE_WEBSOCKET
45#include "face/websocket-factory.hpp"
46#endif // HAVE_WEBSOCKET
47
Alexander Afanasyev4a771362014-04-24 21:29:33 -070048#include <ndn-cxx/management/nfd-face-event-notification.hpp>
Davide Pesavento52a18f92014-04-10 00:55:01 +020049
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070050namespace nfd {
51
52NFD_LOG_INIT("FaceManager");
53
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060054const Name FaceManager::COMMAND_PREFIX("/localhost/nfd/faces");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070055
56const size_t FaceManager::COMMAND_UNSIGNED_NCOMPS =
57 FaceManager::COMMAND_PREFIX.size() +
58 1 + // verb
Steve DiBenedetto7564d972014-03-24 14:28:46 -060059 1; // verb parameters
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070060
61const size_t FaceManager::COMMAND_SIGNED_NCOMPS =
62 FaceManager::COMMAND_UNSIGNED_NCOMPS +
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070063 4; // (timestamp, nonce, signed info tlv, signature tlv)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070064
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060065const FaceManager::SignedVerbAndProcessor FaceManager::SIGNED_COMMAND_VERBS[] =
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070066 {
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060067 SignedVerbAndProcessor(
Steve DiBenedetto7564d972014-03-24 14:28:46 -060068 Name::Component("create"),
69 &FaceManager::createFace
70 ),
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070071
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060072 SignedVerbAndProcessor(
Steve DiBenedetto7564d972014-03-24 14:28:46 -060073 Name::Component("destroy"),
74 &FaceManager::destroyFace
75 ),
76
77 SignedVerbAndProcessor(
78 Name::Component("enable-local-control"),
79 &FaceManager::enableLocalControl
80 ),
81
82 SignedVerbAndProcessor(
83 Name::Component("disable-local-control"),
84 &FaceManager::disableLocalControl
85 ),
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070086 };
87
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060088const FaceManager::UnsignedVerbAndProcessor FaceManager::UNSIGNED_COMMAND_VERBS[] =
89 {
90 UnsignedVerbAndProcessor(
91 Name::Component("list"),
92 &FaceManager::listFaces
93 ),
Steve DiBenedettofbb40a82014-03-11 19:40:15 -060094
95 UnsignedVerbAndProcessor(
96 Name::Component("events"),
97 &FaceManager::ignoreUnsignedVerb
98 ),
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060099 };
100
101const Name FaceManager::LIST_COMMAND_PREFIX("/localhost/nfd/faces/list");
102const size_t FaceManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
103
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600104const Name FaceManager::EVENTS_COMMAND_PREFIX("/localhost/nfd/faces/events");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700105
106FaceManager::FaceManager(FaceTable& faceTable,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700107 shared_ptr<InternalFace> face)
108 : ManagerBase(face, FACE_MANAGER_PRIVILEGE)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700109 , m_faceTable(faceTable)
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600110 , m_statusPublisher(m_faceTable, m_face, LIST_COMMAND_PREFIX)
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600111 , m_notificationStream(m_face, EVENTS_COMMAND_PREFIX)
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600112 , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600113 SIGNED_COMMAND_VERBS +
114 (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600115 , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600116 UNSIGNED_COMMAND_VERBS +
117 (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600118
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700119{
120 face->setInterestFilter("/localhost/nfd/faces",
121 bind(&FaceManager::onFaceRequest, this, _2));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600122
123 m_faceTable.onAdd += bind(&FaceManager::onAddFace, this, _1);
124 m_faceTable.onRemove += bind(&FaceManager::onRemoveFace, this, _1);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700125}
126
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600127FaceManager::~FaceManager()
128{
129
130}
131
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700132void
133FaceManager::setConfigFile(ConfigFile& configFile)
134{
135 configFile.addSectionHandler("face_system",
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600136 bind(&FaceManager::onConfig, this, _1, _2, _3));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700137}
138
139
140void
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600141FaceManager::onConfig(const ConfigSection& configSection,
142 bool isDryRun,
143 const std::string& filename)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700144{
145 bool hasSeenUnix = false;
146 bool hasSeenTcp = false;
147 bool hasSeenUdp = false;
148 bool hasSeenEther = false;
Wentao Shang53df1632014-04-21 12:01:32 -0700149 bool hasSeenWebSocket = false;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700150
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600151 const std::list<shared_ptr<NetworkInterfaceInfo> > nicList(listNetworkInterfaces());
152
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700153 for (ConfigSection::const_iterator item = configSection.begin();
154 item != configSection.end();
155 ++item)
156 {
157 if (item->first == "unix")
158 {
159 if (hasSeenUnix)
160 throw Error("Duplicate \"unix\" section");
161 hasSeenUnix = true;
162
163 processSectionUnix(item->second, isDryRun);
164 }
165 else if (item->first == "tcp")
166 {
167 if (hasSeenTcp)
168 throw Error("Duplicate \"tcp\" section");
169 hasSeenTcp = true;
170
171 processSectionTcp(item->second, isDryRun);
172 }
173 else if (item->first == "udp")
174 {
175 if (hasSeenUdp)
176 throw Error("Duplicate \"udp\" section");
177 hasSeenUdp = true;
178
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600179 processSectionUdp(item->second, isDryRun, nicList);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700180 }
181 else if (item->first == "ether")
182 {
183 if (hasSeenEther)
184 throw Error("Duplicate \"ether\" section");
185 hasSeenEther = true;
186
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600187 processSectionEther(item->second, isDryRun, nicList);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700188 }
Wentao Shang53df1632014-04-21 12:01:32 -0700189 else if (item->first == "websocket")
190 {
191 if (hasSeenWebSocket)
192 throw Error("Duplicate \"websocket\" section");
193 hasSeenWebSocket = true;
194
195 processSectionWebSocket(item->second, isDryRun);
196 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700197 else
198 {
199 throw Error("Unrecognized option \"" + item->first + "\"");
200 }
201 }
202}
203
204void
205FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRun)
206{
207 // ; the unix section contains settings of UNIX stream faces and channels
208 // unix
209 // {
210 // listen yes ; set to 'no' to disable UNIX stream listener, default 'yes'
211 // path /var/run/nfd.sock ; UNIX stream listener path
212 // }
213
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600214#if defined(HAVE_UNIX_SOCKETS)
215
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700216 bool needToListen = true;
217 std::string path = "/var/run/nfd.sock";
218
219 for (ConfigSection::const_iterator i = configSection.begin();
220 i != configSection.end();
221 ++i)
222 {
223 if (i->first == "path")
224 {
225 path = i->second.get_value<std::string>();
226 }
227 else if (i->first == "listen")
228 {
229 needToListen = parseYesNo(i, i->first, "unix");
230 }
231 else
232 {
233 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"unix\" section");
234 }
235 }
236
237 if (!isDryRun)
238 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300239 if (m_factories.count("unix") > 0)
240 {
241 return;
242 // shared_ptr<UnixStreamFactory> factory
243 // = static_pointer_cast<UnixStreamFactory>(m_factories["unix"]);
244 // shared_ptr<UnixStreamChannel> unixChannel = factory->findChannel(path);
245
246 // if (static_cast<bool>(unixChannel))
247 // {
248 // return;
249 // }
250 }
251
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700252 shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
253 shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
254
255 if (needToListen)
256 {
257 // Should acceptFailed callback be used somehow?
258 unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
259 UnixStreamChannel::ConnectFailedCallback());
260 }
261
262 m_factories.insert(std::make_pair("unix", factory));
263 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600264#else
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300265 throw ConfigFile::Error("NFD was compiled without UNIX sockets support, "
266 "cannot process \"unix\" section");
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600267#endif // HAVE_UNIX_SOCKETS
268
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700269}
270
271void
272FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun)
273{
274 // ; the tcp section contains settings of TCP faces and channels
275 // tcp
276 // {
277 // listen yes ; set to 'no' to disable TCP listener, default 'yes'
278 // port 6363 ; TCP listener port number
279 // }
280
281 std::string port = "6363";
282 bool needToListen = true;
Steve DiBenedetto95152872014-04-11 12:40:59 -0600283 bool enableV4 = true;
284 bool enableV6 = true;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700285
286 for (ConfigSection::const_iterator i = configSection.begin();
287 i != configSection.end();
288 ++i)
289 {
290 if (i->first == "port")
291 {
292 port = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600293 try
294 {
295 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
296 NFD_LOG_TRACE("TCP port set to " << portNo);
297 }
298 catch (const std::bad_cast& error)
299 {
300 throw ConfigFile::Error("Invalid value for option " +
Steve DiBenedetto95152872014-04-11 12:40:59 -0600301 i->first + "\" in \"tcp\" section");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600302 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700303 }
304 else if (i->first == "listen")
305 {
306 needToListen = parseYesNo(i, i->first, "tcp");
307 }
Steve DiBenedetto95152872014-04-11 12:40:59 -0600308 else if (i->first == "enable_v4")
309 {
310 enableV4 = parseYesNo(i, i->first, "tcp");
311 }
312 else if (i->first == "enable_v6")
313 {
314 enableV6 = parseYesNo(i, i->first, "tcp");
315 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700316 else
317 {
318 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
319 }
320 }
321
Steve DiBenedetto95152872014-04-11 12:40:59 -0600322 if (!enableV4 && !enableV6)
323 {
324 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
325 " Remove \"tcp\" section to disable TCP channels or"
326 " re-enable at least one channel type.");
327 }
328
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700329 if (!isDryRun)
330 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300331 if (m_factories.count("tcp") > 0)
332 {
333 return;
334 }
335
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700336 shared_ptr<TcpFactory> factory = ndn::make_shared<TcpFactory>(port);
Steve DiBenedetto95152872014-04-11 12:40:59 -0600337 m_factories.insert(std::make_pair("tcp", factory));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700338
Steve DiBenedetto95152872014-04-11 12:40:59 -0600339 if (enableV4)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700340 {
Steve DiBenedetto95152872014-04-11 12:40:59 -0600341 shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
342 if (needToListen)
343 {
344 // Should acceptFailed callback be used somehow?
345 ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
346 TcpChannel::ConnectFailedCallback());
347 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700348
Steve DiBenedetto95152872014-04-11 12:40:59 -0600349 m_factories.insert(std::make_pair("tcp4", factory));
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700350 }
351
Steve DiBenedetto95152872014-04-11 12:40:59 -0600352 if (enableV6)
353 {
354 shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
355 if (needToListen)
356 {
357 // Should acceptFailed callback be used somehow?
358 ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
359 TcpChannel::ConnectFailedCallback());
360 }
361
362 m_factories.insert(std::make_pair("tcp6", factory));
363 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700364 }
365}
366
367void
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600368FaceManager::processSectionUdp(const ConfigSection& configSection,
369 bool isDryRun,
370 const std::list<shared_ptr<NetworkInterfaceInfo> >& nicList)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700371{
372 // ; the udp section contains settings of UDP faces and channels
373 // udp
374 // {
375 // port 6363 ; UDP unicast port number
376 // idle_timeout 30 ; idle time (seconds) before closing a UDP unicast face
377 // keep_alive_interval 25; interval (seconds) between keep-alive refreshes
378
379 // ; NFD creates one UDP multicast face per NIC
380 // mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
381 // mcast_port 56363 ; UDP multicast port number
382 // mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
383 // }
384
385 std::string port = "6363";
Steve DiBenedetto95152872014-04-11 12:40:59 -0600386 bool enableV4 = true;
387 bool enableV6 = true;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700388 size_t timeout = 30;
389 size_t keepAliveInterval = 25;
390 bool useMcast = true;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600391 std::string mcastGroup = "224.0.23.170";
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700392 std::string mcastPort = "56363";
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600393
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700394
395 for (ConfigSection::const_iterator i = configSection.begin();
396 i != configSection.end();
397 ++i)
398 {
399 if (i->first == "port")
400 {
401 port = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600402 try
403 {
404 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
405 NFD_LOG_TRACE("UDP port set to " << portNo);
406 }
407 catch (const std::bad_cast& error)
408 {
409 throw ConfigFile::Error("Invalid value for option " +
410 i->first + "\" in \"udp\" section");
411 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700412 }
Steve DiBenedetto95152872014-04-11 12:40:59 -0600413 else if (i->first == "enable_v4")
414 {
415 enableV4 = parseYesNo(i, i->first, "udp");
416 }
417 else if (i->first == "enable_v6")
418 {
419 enableV6 = parseYesNo(i, i->first, "udp");
420 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700421 else if (i->first == "idle_timeout")
422 {
423 try
424 {
425 timeout = i->second.get_value<size_t>();
426 }
427 catch (const std::exception& e)
428 {
429 throw ConfigFile::Error("Invalid value for option \"" +
430 i->first + "\" in \"udp\" section");
431 }
432 }
433 else if (i->first == "keep_alive_interval")
434 {
435 try
436 {
437 keepAliveInterval = i->second.get_value<size_t>();
Alexander Afanasyevefea8fe2014-03-23 00:00:35 -0700438
439 /// \todo Make use of keepAliveInterval
440 (void)(keepAliveInterval);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700441 }
442 catch (const std::exception& e)
443 {
444 throw ConfigFile::Error("Invalid value for option \"" +
445 i->first + "\" in \"udp\" section");
446 }
447 }
448 else if (i->first == "mcast")
449 {
450 useMcast = parseYesNo(i, i->first, "udp");
451 }
452 else if (i->first == "mcast_port")
453 {
454 mcastPort = i->second.get_value<std::string>();
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600455 try
456 {
457 uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
458 NFD_LOG_TRACE("UDP multicast port set to " << portNo);
459 }
460 catch (const std::bad_cast& error)
461 {
462 throw ConfigFile::Error("Invalid value for option " +
463 i->first + "\" in \"udp\" section");
464 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700465 }
466 else if (i->first == "mcast_group")
467 {
468 using namespace boost::asio::ip;
469 mcastGroup = i->second.get_value<std::string>();
470 try
471 {
472 address mcastGroupTest = address::from_string(mcastGroup);
473 if (!mcastGroupTest.is_v4())
474 {
475 throw ConfigFile::Error("Invalid value for option \"" +
476 i->first + "\" in \"udp\" section");
477 }
478 }
479 catch(const std::runtime_error& e)
480 {
481 throw ConfigFile::Error("Invalid value for option \"" +
482 i->first + "\" in \"udp\" section");
483 }
484 }
485 else
486 {
487 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"udp\" section");
488 }
489 }
490
Steve DiBenedetto95152872014-04-11 12:40:59 -0600491 if (!enableV4 && !enableV6)
492 {
493 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
494 " Remove \"udp\" section to disable UDP channels or"
495 " re-enable at least one channel type.");
496 }
497 else if (useMcast && !enableV4)
498 {
499 throw ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
500 " have been disabled (conflicting configuration options set)");
501 }
502
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700503 /// \todo what is keep alive interval used for?
504
505 if (!isDryRun)
506 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300507 shared_ptr<UdpFactory> factory;
508 bool isReload = false;
509 if (m_factories.count("udp") > 0) {
510 isReload = true;
511 factory = static_pointer_cast<UdpFactory>(m_factories["udp"]);
512 }
513 else {
514 factory = ndn::make_shared<UdpFactory>(port);
515 m_factories.insert(std::make_pair("udp", factory));
516 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700517
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300518 if (!isReload && enableV4)
Steve DiBenedetto95152872014-04-11 12:40:59 -0600519 {
520 shared_ptr<UdpChannel> v4Channel =
521 factory->createChannel("0.0.0.0", port, time::seconds(timeout));
522
523 v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
524 UdpChannel::ConnectFailedCallback());
525
526 m_factories.insert(std::make_pair("udp4", factory));
527 }
528
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300529 if (!isReload && enableV6)
Steve DiBenedetto95152872014-04-11 12:40:59 -0600530 {
531 shared_ptr<UdpChannel> v6Channel =
532 factory->createChannel("::", port, time::seconds(timeout));
533
534 v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
535 UdpChannel::ConnectFailedCallback());
536 m_factories.insert(std::make_pair("udp6", factory));
537 }
538
539 if (useMcast && enableV4)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700540 {
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200541 std::list<shared_ptr<NetworkInterfaceInfo> > ipv4MulticastInterfaces;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600542 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
543 i != nicList.end();
544 ++i)
545 {
546 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
547 if (nic->isUp() && nic->isMulticastCapable() && !nic->ipv4Addresses.empty())
548 {
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200549 ipv4MulticastInterfaces.push_back(nic);
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600550 }
551 }
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200552
553 bool isNicNameNecessary = false;
554
555#if defined(__linux__)
556 if (ipv4MulticastInterfaces.size() > 1)
557 {
558 //On Linux, if we have more than one MulticastUdpFace we need to specify
559 //the name of the interface
560 isNicNameNecessary = true;
561 }
562#endif
563
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300564 std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
565 for (UdpFactory::MulticastFaceMap::const_iterator i =
566 factory->getMulticastFaces().begin();
567 i != factory->getMulticastFaces().end();
568 ++i)
569 {
570 multicastFacesToRemove.push_back(i->second);
571 }
572
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200573 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i =
574 ipv4MulticastInterfaces.begin();
575 i != ipv4MulticastInterfaces.end();
576 ++i)
577 {
578 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
579 shared_ptr<MulticastUdpFace> newFace;
580 newFace = factory->createMulticastFace(nic->ipv4Addresses[0].to_string(),
581 mcastGroup,
582 mcastPort,
583 isNicNameNecessary ? nic->name : "");
584
585 addCreatedFaceToForwarder(newFace);
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300586 multicastFacesToRemove.remove(newFace);
587 }
588
589 for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
590 multicastFacesToRemove.begin();
591 i != multicastFacesToRemove.end();
592 ++i)
593 {
594 (*i)->close();
595 }
596 }
597 else
598 {
599 std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
600 for (UdpFactory::MulticastFaceMap::const_iterator i =
601 factory->getMulticastFaces().begin();
602 i != factory->getMulticastFaces().end();
603 ++i)
604 {
605 multicastFacesToRemove.push_back(i->second);
606 }
607
608 for (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
609 multicastFacesToRemove.begin();
610 i != multicastFacesToRemove.end();
611 ++i)
612 {
613 (*i)->close();
Giulio Grassi6d7176d2014-04-16 16:08:48 +0200614 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600615 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700616 }
617}
618
619void
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600620FaceManager::processSectionEther(const ConfigSection& configSection,
621 bool isDryRun,
622 const std::list<shared_ptr<NetworkInterfaceInfo> >& nicList)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700623{
624 // ; the ether section contains settings of Ethernet faces and channels
625 // ether
626 // {
627 // ; NFD creates one Ethernet multicast face per NIC
628 // mcast yes ; set to 'no' to disable Ethernet multicast, default 'yes'
629 // mcast_group 01:00:5E:00:17:AA ; Ethernet multicast group
630 // }
631
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700632#if defined(HAVE_LIBPCAP)
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600633
634 using ethernet::Address;
635
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700636 bool useMcast = true;
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600637 Address mcastGroup(ethernet::getDefaultMulticastAddress());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700638
639 for (ConfigSection::const_iterator i = configSection.begin();
640 i != configSection.end();
641 ++i)
642 {
643 if (i->first == "mcast")
644 {
645 useMcast = parseYesNo(i, i->first, "ether");
646 }
647
648 else if (i->first == "mcast_group")
649 {
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600650 mcastGroup = Address::fromString(i->second.get_value<std::string>());
651 if (mcastGroup.isNull())
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700652 {
653 throw ConfigFile::Error("Invalid value for option \"" +
654 i->first + "\" in \"ether\" section");
655 }
656 }
657 else
658 {
659 throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"ether\" section");
660 }
661 }
662
663 if (!isDryRun)
664 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300665 shared_ptr<EthernetFactory> factory;
666 if (m_factories.count("ether") > 0) {
667 factory = static_pointer_cast<EthernetFactory>(m_factories["ether"]);
668 }
669 else {
670 factory = ndn::make_shared<EthernetFactory>();
671 m_factories.insert(std::make_pair("ether", factory));
672 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700673
674 if (useMcast)
675 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300676 std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
677 for (EthernetFactory::MulticastFaceMap::const_iterator i =
678 factory->getMulticastFaces().begin();
679 i != factory->getMulticastFaces().end();
680 ++i)
681 {
682 multicastFacesToRemove.push_back(i->second);
683 }
684
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600685 for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
686 i != nicList.end();
687 ++i)
688 {
689 const shared_ptr<NetworkInterfaceInfo>& nic = *i;
690 if (nic->isUp() && nic->isMulticastCapable())
691 {
692 try
693 {
694 shared_ptr<EthernetFace> newFace =
Davide Pesaventob60cc122014-03-19 19:26:02 +0100695 factory->createMulticastFace(nic, mcastGroup);
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700696
697 addCreatedFaceToForwarder(newFace);
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300698 multicastFacesToRemove.remove(newFace);
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600699 }
700 catch (const EthernetFactory::Error& factoryError)
701 {
702 NFD_LOG_ERROR(factoryError.what() << ", continuing");
703 }
704 catch (const EthernetFace::Error& faceError)
705 {
706 NFD_LOG_ERROR(faceError.what() << ", continuing");
707 }
708 }
709 }
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300710
711 for (std::list<shared_ptr<EthernetFace> >::iterator i =
712 multicastFacesToRemove.begin();
713 i != multicastFacesToRemove.end();
714 ++i)
715 {
716 (*i)->close();
717 }
718 }
719 else
720 {
721 std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
722 for (EthernetFactory::MulticastFaceMap::const_iterator i =
723 factory->getMulticastFaces().begin();
724 i != factory->getMulticastFaces().end();
725 ++i)
726 {
727 multicastFacesToRemove.push_back(i->second);
728 }
729
730 for (std::list<shared_ptr<EthernetFace> >::iterator i =
731 multicastFacesToRemove.begin();
732 i != multicastFacesToRemove.end();
733 ++i)
734 {
735 (*i)->close();
736 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700737 }
738 }
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600739#else
740 throw ConfigFile::Error("NFD was compiled without libpcap, cannot process \"ether\" section");
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700741#endif // HAVE_LIBPCAP
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700742}
743
Wentao Shang53df1632014-04-21 12:01:32 -0700744void
745FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool isDryRun)
746{
747 // ; the websocket section contains settings of WebSocket faces and channels
748 // websocket
749 // {
750 // listen yes ; set to 'no' to disable WebSocket listener, default 'yes'
751 // port 9696 ; WebSocket listener port number
752 // enable_v4 yes ; set to 'no' to disable listening on IPv4 socket, default 'yes'
753 // enable_v6 yes ; set to 'no' to disable listening on IPv6 socket, default 'yes'
754 // }
755
756#if defined(HAVE_WEBSOCKET)
757
758 std::string port = "9696";
759 bool needToListen = true;
760 bool enableV4 = true;
761 bool enableV6 = true;
762
763 for (ConfigSection::const_iterator i = configSection.begin();
764 i != configSection.end();
765 ++i)
766 {
767 if (i->first == "port")
768 {
769 port = i->second.get_value<std::string>();
770 try
771 {
772 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
773 NFD_LOG_TRACE("WebSocket port set to " << portNo);
774 }
775 catch (const std::bad_cast& error)
776 {
777 throw ConfigFile::Error("Invalid value for option " +
778 i->first + "\" in \"websocket\" section");
779 }
780 }
781 else if (i->first == "listen")
782 {
783 needToListen = parseYesNo(i, i->first, "websocket");
784 }
785 else if (i->first == "enable_v4")
786 {
787 enableV4 = parseYesNo(i, i->first, "websocket");
788 }
789 else if (i->first == "enable_v6")
790 {
791 enableV6 = parseYesNo(i, i->first, "websocket");
792 }
793 else
794 {
795 throw ConfigFile::Error("Unrecognized option \"" +
796 i->first + "\" in \"websocket\" section");
797 }
798 }
799
800 if (!enableV4 && !enableV6)
801 {
802 throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
803 " Remove \"websocket\" section to disable WebSocket channels or"
804 " re-enable at least one channel type.");
805 }
806
807 if (!enableV4 && enableV6)
808 {
809 throw ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel.");
810 }
811
812 if (!isDryRun)
813 {
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300814 if (m_factories.count("websocket") > 0)
815 {
816 return;
817 }
818
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700819 shared_ptr<WebSocketFactory> factory = ndn::make_shared<WebSocketFactory>(port);
Wentao Shang53df1632014-04-21 12:01:32 -0700820 m_factories.insert(std::make_pair("websocket", factory));
821 uint16_t portNo = boost::lexical_cast<uint16_t>(port);
822
823 if (enableV6 && enableV4)
824 {
825 shared_ptr<WebSocketChannel> ip46Channel = factory->createChannel("::", portNo);
826 if (needToListen)
827 {
828 ip46Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
829 }
830
831 m_factories.insert(std::make_pair("websocket46", factory));
832 }
833 else if (enableV4)
834 {
835 shared_ptr<WebSocketChannel> ipv4Channel = factory->createChannel("0.0.0.0", portNo);
836 if (needToListen)
837 {
838 ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
839 }
840
841 m_factories.insert(std::make_pair("websocket4", factory));
842 }
843 }
844#else
845 throw ConfigFile::Error("NFD was compiled without WebSocket, "
846 "cannot process \"websocket\" section");
847#endif // HAVE_WEBSOCKET
848}
849
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700850
851void
852FaceManager::onFaceRequest(const Interest& request)
853{
854 const Name& command = request.getName();
855 const size_t commandNComps = command.size();
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600856 const Name::Component& verb = command.get(COMMAND_PREFIX.size());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700857
Alexander Afanasyev5959b012014-06-02 19:18:12 +0300858 UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor =
859 m_unsignedVerbDispatch.find(verb);
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600860 if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
861 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700862 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700863 (unsignedVerbProcessor->second)(this, request);
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600864 }
865 else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600866 commandNComps < COMMAND_SIGNED_NCOMPS)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700867 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700868 NFD_LOG_DEBUG("command result: unsigned verb: " << command);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700869 sendResponse(command, 401, "Signature required");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700870 }
871 else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
872 !COMMAND_PREFIX.isPrefixOf(command))
873 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700874 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700875 sendResponse(command, 400, "Malformed command");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700876 }
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600877 else
878 {
879 validate(request,
880 bind(&FaceManager::onValidatedFaceRequest, this, _1),
881 bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
882 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700883}
884
885void
886FaceManager::onValidatedFaceRequest(const shared_ptr<const Interest>& request)
887{
888 const Name& command = request->getName();
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600889 const Name::Component& verb = command[COMMAND_PREFIX.size()];
890 const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700891
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600892 SignedVerbDispatchTable::const_iterator signedVerbProcessor = m_signedVerbDispatch.find(verb);
893 if (signedVerbProcessor != m_signedVerbDispatch.end())
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700894 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600895 ControlParameters parameters;
896 if (!extractParameters(parameterComponent, parameters))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700897 {
898 sendResponse(command, 400, "Malformed command");
899 return;
900 }
901
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700902 NFD_LOG_DEBUG("command result: processing verb: " << verb);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600903 (signedVerbProcessor->second)(this, *request, parameters);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700904 }
905 else
906 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700907 NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700908 sendResponse(command, 501, "Unsupported command");
909 }
910
911}
912
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700913void
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700914FaceManager::addCreatedFaceToForwarder(const shared_ptr<Face>& newFace)
915{
916 m_faceTable.add(newFace);
917
Junxiao Shi6e694322014-04-03 10:27:13 -0700918 //NFD_LOG_DEBUG("Created face " << newFace->getRemoteUri() << " ID " << newFace->getId());
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700919}
920
921void
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700922FaceManager::onCreated(const Name& requestName,
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600923 ControlParameters& parameters,
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700924 const shared_ptr<Face>& newFace)
925{
Alexander Afanasyevbbe3f0c2014-03-23 11:44:01 -0700926 addCreatedFaceToForwarder(newFace);
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600927 parameters.setFaceId(newFace->getId());
Steve DiBenedetto25999282014-05-22 15:25:12 -0600928 parameters.setUri(newFace->getRemoteUri().toString());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700929
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600930 sendResponse(requestName, 200, "Success", parameters.wireEncode());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700931}
932
933void
934FaceManager::onConnectFailed(const Name& requestName, const std::string& reason)
935{
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -0700936 NFD_LOG_DEBUG("Failed to create face: " << reason);
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600937 sendResponse(requestName, 408, reason);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700938}
939
940void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600941FaceManager::createFace(const Interest& request,
942 ControlParameters& parameters)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700943{
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600944 const Name& requestName = request.getName();
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600945 ndn::nfd::FaceCreateCommand command;
946
947 if (!validateParameters(command, parameters))
948 {
949 sendResponse(requestName, 400, "Malformed command");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600950 NFD_LOG_TRACE("invalid control parameters URI");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600951 return;
952 }
953
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700954 FaceUri uri;
Steve DiBenedetto51d242a2014-03-31 13:46:43 -0600955 if (!uri.parse(parameters.getUri()))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700956 {
957 sendResponse(requestName, 400, "Malformed command");
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600958 NFD_LOG_TRACE("failed to parse URI");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700959 return;
960 }
961
962 FactoryMap::iterator factory = m_factories.find(uri.getScheme());
963 if (factory == m_factories.end())
964 {
965 sendResponse(requestName, 501, "Unsupported protocol");
966 return;
967 }
968
Steve DiBenedettoca53ac62014-03-27 19:58:40 -0600969 try
970 {
971 factory->second->createFace(uri,
972 bind(&FaceManager::onCreated,
973 this, requestName, parameters, _1),
974 bind(&FaceManager::onConnectFailed,
975 this, requestName, _1));
976 }
977 catch (const std::runtime_error& error)
978 {
979 std::string errorMessage = "NFD error: ";
980 errorMessage += error.what();
981
982 NFD_LOG_ERROR(errorMessage);
983 sendResponse(requestName, 500, errorMessage);
984 }
985 catch (const std::logic_error& error)
986 {
987 std::string errorMessage = "NFD error: ";
988 errorMessage += error.what();
989
990 NFD_LOG_ERROR(errorMessage);
991 sendResponse(requestName, 500, errorMessage);
992 }
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700993}
994
995
996void
Steve DiBenedetto7564d972014-03-24 14:28:46 -0600997FaceManager::destroyFace(const Interest& request,
998 ControlParameters& parameters)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700999{
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001000 const Name& requestName = request.getName();
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001001 ndn::nfd::FaceDestroyCommand command;
1002
1003 if (!validateParameters(command, parameters))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001004 {
1005 sendResponse(requestName, 400, "Malformed command");
1006 return;
1007 }
1008
1009 shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001010 if (static_cast<bool>(target))
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001011 {
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001012 target->close();
1013 }
Steve DiBenedettoba749052014-03-22 19:54:53 -06001014
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001015 sendResponse(requestName, 200, "Success", parameters.wireEncode());
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001016
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001017}
1018
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001019void
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001020FaceManager::onAddFace(shared_ptr<Face> face)
1021{
Junxiao Shi6e694322014-04-03 10:27:13 -07001022 ndn::nfd::FaceEventNotification notification;
1023 notification.setKind(ndn::nfd::FACE_EVENT_CREATED)
1024 .setFaceId(face->getId())
1025 .setRemoteUri(face->getRemoteUri().toString())
1026 .setLocalUri(face->getLocalUri().toString())
1027 .setFlags(getFaceFlags(*face));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001028
Junxiao Shi6e694322014-04-03 10:27:13 -07001029 m_notificationStream.postNotification(notification);
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001030}
1031
1032void
1033FaceManager::onRemoveFace(shared_ptr<Face> face)
1034{
Junxiao Shi6e694322014-04-03 10:27:13 -07001035 ndn::nfd::FaceEventNotification notification;
1036 notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
1037 .setFaceId(face->getId())
1038 .setRemoteUri(face->getRemoteUri().toString())
1039 .setLocalUri(face->getLocalUri().toString())
1040 .setFlags(getFaceFlags(*face));
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001041
Junxiao Shi6e694322014-04-03 10:27:13 -07001042 m_notificationStream.postNotification(notification);
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001043}
1044
1045
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001046bool
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001047FaceManager::extractLocalControlParameters(const Interest& request,
1048 ControlParameters& parameters,
1049 ControlCommand& command,
1050 shared_ptr<LocalFace>& outFace,
1051 LocalControlFeature& outFeature)
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001052{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001053 if (!validateParameters(command, parameters))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001054 {
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001055 sendResponse(request.getName(), 400, "Malformed command");
1056 return false;
1057 }
1058
1059 shared_ptr<Face> face = m_faceTable.get(request.getIncomingFaceId());
1060
1061 if (!static_cast<bool>(face))
1062 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001063 NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001064 sendResponse(request.getName(), 410, "Face not found");
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001065 return false;
1066 }
1067 else if (!face->isLocal())
1068 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001069 NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
1070 face->getId());
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001071 sendResponse(request.getName(), 412, "Face is non-local");
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001072 return false;
1073 }
1074
1075 outFace = dynamic_pointer_cast<LocalFace>(face);
1076 outFeature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
1077
1078 return true;
1079}
1080
1081void
1082FaceManager::enableLocalControl(const Interest& request,
1083 ControlParameters& parameters)
1084{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001085 ndn::nfd::FaceEnableLocalControlCommand command;
1086
1087
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001088 shared_ptr<LocalFace> face;
1089 LocalControlFeature feature;
1090
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001091 if (extractLocalControlParameters(request, parameters, command, face, feature))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001092 {
1093 face->setLocalControlHeaderFeature(feature, true);
1094 sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
1095 }
1096}
1097
1098void
1099FaceManager::disableLocalControl(const Interest& request,
1100 ControlParameters& parameters)
1101{
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001102 ndn::nfd::FaceDisableLocalControlCommand command;
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001103 shared_ptr<LocalFace> face;
1104 LocalControlFeature feature;
1105
Steve DiBenedetto51d242a2014-03-31 13:46:43 -06001106 if (extractLocalControlParameters(request, parameters, command, face, feature))
Steve DiBenedetto7564d972014-03-24 14:28:46 -06001107 {
1108 face->setLocalControlHeaderFeature(feature, false);
1109 sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
1110 }
1111}
1112
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001113void
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001114FaceManager::listFaces(const Interest& request)
1115{
1116 const Name& command = request.getName();
1117 const size_t commandNComps = command.size();
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001118
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001119 if (commandNComps < LIST_COMMAND_NCOMPS ||
1120 !LIST_COMMAND_PREFIX.isPrefixOf(command))
1121 {
Alexander Afanasyevbf9edee2014-03-31 23:05:27 -07001122 NFD_LOG_DEBUG("command result: malformed");
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001123 sendResponse(command, 400, "Malformed command");
1124 return;
1125 }
1126
1127 m_statusPublisher.publish();
1128}
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001129
Alexander Afanasyev5959b012014-06-02 19:18:12 +03001130shared_ptr<ProtocolFactory>
1131FaceManager::findFactory(const std::string& protocol)
1132{
1133 FactoryMap::iterator factory = m_factories.find(protocol);
1134 if (factory != m_factories.end())
1135 return factory->second;
1136 else
1137 return shared_ptr<ProtocolFactory>();
1138}
1139
1140
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001141} // namespace nfd