31 #include <ndn-cxx/lp/tags.hpp>
32 #include <ndn-cxx/mgmt/nfd/channel-status.hpp>
40 , m_faceSystem(faceTable)
41 , m_faceTable(faceTable)
43 registerCommandHandler<ndn::nfd::FaceCreateCommand>(
"create",
44 bind(&FaceManager::createFace,
this, _2, _3, _4, _5));
46 registerCommandHandler<ndn::nfd::FaceUpdateCommand>(
"update",
47 bind(&FaceManager::updateFace,
this, _2, _3, _4, _5));
49 registerCommandHandler<ndn::nfd::FaceDestroyCommand>(
"destroy",
50 bind(&FaceManager::destroyFace,
this, _2, _3, _4, _5));
52 registerCommandHandler<ndn::nfd::FaceEnableLocalControlCommand>(
"enable-local-control",
53 bind(&FaceManager::enableLocalControl,
this, _2, _3, _4, _5));
55 registerCommandHandler<ndn::nfd::FaceDisableLocalControlCommand>(
"disable-local-control",
56 bind(&FaceManager::disableLocalControl,
this, _2, _3, _4, _5));
63 m_faceAddConn = m_faceTable.
afterAdd.connect([
this] (
const Face& face) {
64 connectFaceStateChangeSignal(face);
65 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
67 m_faceRemoveConn = m_faceTable.
beforeRemove.connect([
this] (
const Face& face) {
68 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
75 m_faceSystem.setConfigFile(configFile);
79 FaceManager::createFace(
const Name& topPrefix,
const Interest& interest,
80 const ControlParameters& parameters,
81 const ndn::mgmt::CommandContinuation& done)
84 if (!uri.parse(parameters.getUri())) {
86 done(ControlResponse(400,
"Malformed command"));
90 if (!uri.isCanonical()) {
92 done(ControlResponse(400,
"Non-canonical URI"));
96 ProtocolFactory* factory = m_faceSystem.getFactoryByScheme(uri.getScheme());
97 if (factory ==
nullptr) {
98 NFD_LOG_TRACE(
"received create request for unsupported protocol");
99 done(ControlResponse(406,
"Unsupported protocol"));
104 factory->createFace(uri,
105 parameters.getFacePersistency(),
106 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
107 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED),
108 bind(&FaceManager::afterCreateFaceSuccess,
this, parameters, _1, done),
109 bind(&FaceManager::afterCreateFaceFailure,
this, _1, _2, done));
111 catch (
const std::runtime_error& error) {
113 done(ControlResponse(500,
"Face creation failed due to internal error"));
116 catch (
const std::logic_error& error) {
118 done(ControlResponse(500,
"Face creation failed due to internal error"));
130 FaceManager::afterCreateFaceSuccess(
const ControlParameters& parameters,
131 const shared_ptr<Face>& face,
132 const ndn::mgmt::CommandContinuation& done)
153 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
154 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
155 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
156 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
158 m_faceTable.
add(face);
160 ControlParameters response;
161 response.setFaceId(face->getId());
162 response.setFacePersistency(face->getPersistency());
163 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
164 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
165 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) :
false,
168 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
173 FaceManager::afterCreateFaceFailure(uint32_t status,
174 const std::string& reason,
175 const ndn::mgmt::CommandContinuation& done)
179 done(ControlResponse(status, reason));
183 FaceManager::updateFace(
const Name& topPrefix,
const Interest& interest,
184 const ControlParameters& parameters,
185 const ndn::mgmt::CommandContinuation& done)
187 FaceId faceId = parameters.getFaceId();
190 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
191 if (incomingFaceIdTag ==
nullptr) {
193 done(ControlResponse(404,
"No FaceId specified and IncomingFaceId not available"));
196 faceId = *incomingFaceIdTag;
199 Face* face = m_faceTable.
get(faceId);
201 if (face ==
nullptr) {
203 done(ControlResponse(404,
"Specified face does not exist"));
208 ControlParameters response;
209 bool areParamsValid =
true;
211 if (parameters.hasFacePersistency()) {
213 NFD_LOG_TRACE(
"received unsupported face persistency change");
214 areParamsValid =
false;
215 response.setFacePersistency(parameters.getFacePersistency());
218 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
219 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
220 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
221 NFD_LOG_TRACE(
"received request to enable local fields on non-local face");
222 areParamsValid =
false;
223 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
224 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
227 if (!areParamsValid) {
228 done(ControlResponse(409,
"Invalid properties specified").setBody(response.wireEncode()));
236 setLinkServiceOptions(*face, parameters, response);
239 response.setFaceId(faceId);
240 response.setFacePersistency(face->getPersistency());
241 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
242 parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ?
243 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) :
false,
246 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
250 FaceManager::destroyFace(
const Name& topPrefix,
const Interest& interest,
251 const ControlParameters& parameters,
252 const ndn::mgmt::CommandContinuation& done)
254 Face* face = m_faceTable.
get(parameters.getFaceId());
255 if (face !=
nullptr) {
259 done(ControlResponse(200,
"OK").setBody(parameters.wireEncode()));
263 FaceManager::enableLocalControl(
const Name& topPrefix,
const Interest& interest,
264 const ControlParameters& parameters,
265 const ndn::mgmt::CommandContinuation& done)
267 Face* face = findFaceForLocalControl(interest, parameters, done);
273 auto service =
dynamic_cast<face::GenericLinkService*
>(face->getLinkService());
274 if (service ==
nullptr) {
275 return done(ControlResponse(503,
"LinkService type not supported"));
278 face::GenericLinkService::Options options = service->getOptions();
279 options.allowLocalFields =
true;
280 service->setOptions(options);
282 return done(ControlResponse(200,
"OK: enable all local fields on GenericLinkService")
283 .setBody(parameters.wireEncode()));
287 FaceManager::disableLocalControl(
const Name& topPrefix,
const Interest& interest,
288 const ControlParameters& parameters,
289 const ndn::mgmt::CommandContinuation& done)
291 Face* face = findFaceForLocalControl(interest, parameters, done);
297 auto service =
dynamic_cast<face::GenericLinkService*
>(face->getLinkService());
298 if (service ==
nullptr) {
299 return done(ControlResponse(503,
"LinkService type not supported"));
302 face::GenericLinkService::Options options = service->getOptions();
303 options.allowLocalFields =
false;
304 service->setOptions(options);
306 return done(ControlResponse(200,
"OK: disable all local fields on GenericLinkService")
307 .setBody(parameters.wireEncode()));
311 FaceManager::findFaceForLocalControl(
const Interest& request,
312 const ControlParameters& parameters,
313 const ndn::mgmt::CommandContinuation& done)
315 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
319 BOOST_ASSERT(incomingFaceIdTag !=
nullptr);
321 Face* face = m_faceTable.
get(*incomingFaceIdTag);
322 if (face ==
nullptr) {
323 NFD_LOG_DEBUG(
"FaceId " << *incomingFaceIdTag <<
" not found");
324 done(ControlResponse(410,
"Face not found"));
328 if (face->getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL) {
329 NFD_LOG_DEBUG(
"Cannot enable local control on non-local FaceId " << face->getId());
330 done(ControlResponse(412,
"Face is non-local"));
338 FaceManager::setLinkServiceOptions(Face& face,
339 const ControlParameters& parameters,
340 ControlParameters& response)
342 auto linkService =
dynamic_cast<face::GenericLinkService*
>(face.getLinkService());
343 BOOST_ASSERT(linkService !=
nullptr);
345 auto options = linkService->getOptions();
346 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
347 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
348 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
350 linkService->setOptions(options);
353 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields,
false);
357 FaceManager::listFaces(
const Name& topPrefix,
const Interest& interest,
358 ndn::mgmt::StatusDatasetContext& context)
360 auto now = time::steady_clock::now();
361 for (
const Face& face : m_faceTable) {
362 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
363 context.append(status.wireEncode());
369 FaceManager::listChannels(
const Name& topPrefix,
const Interest& interest,
370 ndn::mgmt::StatusDatasetContext& context)
372 std::set<const ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
373 for (
const ProtocolFactory* factory : factories) {
374 for (
const auto& channel : factory->getChannels()) {
375 ndn::nfd::ChannelStatus entry;
376 entry.setLocalUri(channel->getUri().toString());
377 context.append(entry.wireEncode());
384 FaceManager::queryFaces(
const Name& topPrefix,
const Interest& interest,
385 ndn::mgmt::StatusDatasetContext& context)
387 ndn::nfd::FaceQueryFilter faceFilter;
388 const Name& query = interest.getName();
390 faceFilter.wireDecode(query[-1].blockFromValue());
392 catch (
const tlv::Error& e) {
394 return context.reject(ControlResponse(400,
"Malformed filter"));
397 auto now = time::steady_clock::now();
398 for (
const Face& face : m_faceTable) {
399 if (!matchFilter(faceFilter, face)) {
402 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
403 context.append(status.wireEncode());
410 FaceManager::matchFilter(
const ndn::nfd::FaceQueryFilter& filter,
const Face& face)
412 if (filter.hasFaceId() &&
413 filter.getFaceId() !=
static_cast<uint64_t
>(face.getId())) {
417 if (filter.hasUriScheme() &&
418 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
419 filter.getUriScheme() != face.getLocalUri().getScheme()) {
423 if (filter.hasRemoteUri() &&
424 filter.getRemoteUri() != face.getRemoteUri().toString()) {
428 if (filter.hasLocalUri() &&
429 filter.getLocalUri() != face.getLocalUri().toString()) {
433 if (filter.hasFaceScope() &&
434 filter.getFaceScope() != face.getScope()) {
438 if (filter.hasFacePersistency() &&
439 filter.getFacePersistency() != face.getPersistency()) {
443 if (filter.hasLinkType() &&
444 filter.getLinkType() != face.getLinkType()) {
452 FaceManager::collectFaceStatus(
const Face& face,
const time::steady_clock::TimePoint& now)
454 ndn::nfd::FaceStatus status;
456 collectFaceProperties(face, status);
458 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
459 if (expirationTime != time::steady_clock::TimePoint::max()) {
460 status.setExpirationPeriod(std::max(time::milliseconds(0),
461 time::duration_cast<time::milliseconds>(expirationTime - now)));
464 const face::FaceCounters& counters = face.getCounters();
465 status.setNInInterests(counters.nInInterests)
466 .setNOutInterests(counters.nOutInterests)
467 .setNInDatas(counters.nInData)
468 .setNOutDatas(counters.nOutData)
469 .setNInNacks(counters.nInNacks)
470 .setNOutNacks(counters.nOutNacks)
471 .setNInBytes(counters.nInBytes)
472 .setNOutBytes(counters.nOutBytes);
477 template<
typename FaceTraits>
479 FaceManager::collectFaceProperties(
const Face& face, FaceTraits& traits)
481 traits.setFaceId(face.getId())
482 .setRemoteUri(face.getRemoteUri().toString())
483 .setLocalUri(face.getLocalUri().toString())
484 .setFaceScope(face.getScope())
485 .setFacePersistency(face.getPersistency())
486 .setLinkType(face.getLinkType());
489 auto linkService =
dynamic_cast<face::GenericLinkService*
>(face.getLinkService());
490 if (linkService !=
nullptr) {
491 auto linkServiceOptions = linkService->getOptions();
492 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
497 FaceManager::notifyFaceEvent(
const Face& face, ndn::nfd::FaceEventKind kind)
499 ndn::nfd::FaceEventNotification notification;
500 notification.setKind(kind);
501 collectFaceProperties(face, notification);
503 m_postNotification(notification.wireEncode());
507 FaceManager::connectFaceStateChangeSignal(
const Face& face)
509 FaceId faceId = face.getId();
510 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
512 const Face& face = *m_faceTable.get(faceId);
515 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
518 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
521 m_faceStateChangeConn.erase(faceId);
void registerStatusDatasetHandler(const std::string &verb, const ndn::mgmt::StatusDatasetHandler &handler)
#define NFD_LOG_DEBUG(expression)
configuration file parsing utility
Face * get(FaceId id) const
get face by FaceId
#define NFD_LOG_ERROR(expression)
provides ControlCommand authorization according to NFD configuration file
void add(shared_ptr< Face > face)
add a face
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
TransportState FaceState
indicates the state of a face
signal::Signal< FaceTable, Face & > beforeRemove
fires before a face is removed
the transport is closed, and can be safely deallocated
ndn::mgmt::PostNotification registerNotificationStream(const std::string &verb)
a collection of common functions shared by all NFD managers, such as communicating with the dispatche...
signal::Signal< FaceTable, Face & > afterAdd
fires after a face is added
void setConfigFile(ConfigFile &configFile)
Subscribe to face_system section for the config file.
#define NFD_LOG_INIT(name)
#define NFD_LOG_TRACE(expression)
uint64_t FaceId
identifies a face
FaceManager(FaceTable &faceTable, Dispatcher &dispatcher, CommandAuthenticator &authenticator)
the transport is down temporarily, and is being recovered