33 #include <ndn-cxx/lp/tags.hpp> 34 #include <ndn-cxx/mgmt/nfd/channel-status.hpp> 35 #include <ndn-cxx/mgmt/nfd/face-event-notification.hpp> 36 #include <ndn-cxx/mgmt/nfd/face-query-filter.hpp> 37 #include <ndn-cxx/mgmt/nfd/face-status.hpp> 46 , m_faceSystem(faceSystem)
47 , m_faceTable(faceSystem.getFaceTable())
50 registerCommandHandler<ndn::nfd::FaceCreateCommand>(
"create", bind(&FaceManager::createFace,
this, _4, _5));
51 registerCommandHandler<ndn::nfd::FaceUpdateCommand>(
"update", bind(&FaceManager::updateFace,
this, _3, _4, _5));
52 registerCommandHandler<ndn::nfd::FaceDestroyCommand>(
"destroy", bind(&FaceManager::destroyFace,
this, _4, _5));
61 m_faceAddConn = m_faceTable.
afterAdd.connect([
this] (
const Face& face) {
62 connectFaceStateChangeSignal(face);
63 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
65 m_faceRemoveConn = m_faceTable.
beforeRemove.connect([
this] (
const Face& face) {
66 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
71 FaceManager::createFace(
const ControlParameters& parameters,
72 const ndn::mgmt::CommandContinuation& done)
75 if (!remoteUri.parse(parameters.getUri())) {
76 NFD_LOG_TRACE(
"failed to parse remote URI: " << parameters.getUri());
77 done(ControlResponse(400,
"Malformed command"));
81 if (!remoteUri.isCanonical()) {
82 NFD_LOG_TRACE(
"received non-canonical remote URI: " << remoteUri.toString());
83 done(ControlResponse(400,
"Non-canonical remote URI"));
87 optional<FaceUri> localUri;
88 if (parameters.hasLocalUri()) {
91 if (!localUri->parse(parameters.getLocalUri())) {
92 NFD_LOG_TRACE(
"failed to parse local URI: " << parameters.getLocalUri());
93 done(ControlResponse(400,
"Malformed command"));
97 if (!localUri->isCanonical()) {
98 NFD_LOG_TRACE(
"received non-canonical local URI: " << localUri->toString());
99 done(ControlResponse(400,
"Non-canonical local URI"));
105 if (factory ==
nullptr) {
106 NFD_LOG_TRACE(
"received create request for unsupported protocol: " << remoteUri.getScheme());
107 done(ControlResponse(406,
"Unsupported protocol"));
112 faceParams.
persistency = parameters.getFacePersistency();
113 if (parameters.hasBaseCongestionMarkingInterval()) {
116 if (parameters.hasDefaultCongestionThreshold()) {
119 if (parameters.hasMtu()) {
120 faceParams.
mtu = parameters.getMtu();
122 faceParams.
wantLocalFields = parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
123 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
124 faceParams.
wantLpReliability = parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) &&
125 parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
126 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
130 factory->
createFace({remoteUri, localUri, faceParams},
131 [
this, parameters, done] (
const auto& face) {
132 this->afterCreateFaceSuccess(face, parameters, done);
134 [done] (uint32_t status,
const std::string& reason) {
136 done(ControlResponse(status, reason));
139 catch (
const std::runtime_error& error) {
141 done(ControlResponse(500,
"Face creation failed due to internal error"));
144 catch (
const std::logic_error& error) {
146 done(ControlResponse(500,
"Face creation failed due to internal error"));
155 auto transport = face.getTransport();
156 BOOST_ASSERT(transport !=
nullptr);
158 if (transport->getMtu() > 0) {
159 to.setMtu(std::min(static_cast<size_t>(transport->getMtu()), ndn::MAX_NDN_PACKET_SIZE));
162 to.setMtu(ndn::MAX_NDN_PACKET_SIZE);
166 static ControlParameters
169 ControlParameters params;
170 params.setFaceId(face.getId())
171 .setFacePersistency(face.getPersistency());
174 if (linkService !=
nullptr) {
175 const auto& options = linkService->
getOptions();
176 params.setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
177 .setDefaultCongestionThreshold(options.defaultCongestionThreshold)
178 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields,
false)
179 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled,
false)
180 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking,
false);
186 static ControlParameters
190 params.setUri(face.getRemoteUri().toString())
191 .setLocalUri(face.getLocalUri().toString());
199 FaceManager::afterCreateFaceSuccess(
const shared_ptr<Face>& face,
200 const ControlParameters& parameters,
201 const ndn::mgmt::CommandContinuation& done)
204 NFD_LOG_TRACE(
"Attempted to create duplicate face of " << face->getId());
206 done(ControlResponse(409,
"Face with remote URI already exists").setBody(response.wireEncode()));
212 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
213 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
214 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
215 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
217 m_faceTable.
add(face);
220 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
227 if (linkService ==
nullptr) {
232 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
233 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
234 options.
allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
236 if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
237 options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
239 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
240 options.allowCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
242 if (parameters.hasBaseCongestionMarkingInterval()) {
243 options.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
245 if (parameters.hasDefaultCongestionThreshold()) {
246 options.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
249 linkService->setOptions(options);
253 FaceManager::updateFace(
const Interest& interest,
254 const ControlParameters& parameters,
255 const ndn::mgmt::CommandContinuation& done)
257 FaceId faceId = parameters.getFaceId();
259 auto incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
260 if (incomingFaceIdTag ==
nullptr) {
262 done(ControlResponse(404,
"No FaceId specified and IncomingFaceId not available"));
265 faceId = *incomingFaceIdTag;
268 Face* face = m_faceTable.
get(faceId);
269 if (face ==
nullptr) {
271 done(ControlResponse(404,
"Specified face does not exist"));
276 ControlParameters response;
277 bool areParamsValid =
true;
279 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
280 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
281 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
282 NFD_LOG_TRACE(
"received request to enable local fields on non-local face");
283 areParamsValid =
false;
284 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
285 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
289 if (parameters.hasFacePersistency()) {
290 auto persistency = parameters.getFacePersistency();
291 if (!face->getTransport()->canChangePersistencyTo(persistency)) {
292 NFD_LOG_TRACE(
"cannot change face persistency to " << persistency);
293 areParamsValid =
false;
294 response.setFacePersistency(persistency);
298 if (!areParamsValid) {
299 done(ControlResponse(409,
"Invalid properties specified").setBody(response.wireEncode()));
304 if (parameters.hasFacePersistency()) {
305 face->setPersistency(parameters.getFacePersistency());
311 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
315 FaceManager::destroyFace(
const ControlParameters& parameters,
316 const ndn::mgmt::CommandContinuation& done)
318 Face* face = m_faceTable.
get(parameters.getFaceId());
319 if (face !=
nullptr) {
323 done(ControlResponse(200,
"OK").setBody(parameters.wireEncode()));
330 to.setFaceId(face.getId())
331 .setRemoteUri(face.getRemoteUri().toString())
332 .setLocalUri(face.getLocalUri().toString())
333 .setFaceScope(face.getScope())
334 .setFacePersistency(face.getPersistency())
335 .setLinkType(face.getLinkType());
338 if (linkService !=
nullptr) {
339 const auto& options = linkService->
getOptions();
340 to.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields)
341 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled)
342 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking);
346 static ndn::nfd::FaceStatus
349 ndn::nfd::FaceStatus status;
352 auto expirationTime = face.getExpirationTime();
353 if (expirationTime != time::steady_clock::TimePoint::max()) {
354 status.setExpirationPeriod(std::max(0_ms,
355 time::duration_cast<time::milliseconds>(expirationTime - now)));
359 if (linkService !=
nullptr) {
360 const auto& options = linkService->
getOptions();
361 status.setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
362 .setDefaultCongestionThreshold(options.defaultCongestionThreshold);
367 const auto& counters = face.getCounters();
368 status.setNInInterests(counters.nInInterests)
369 .setNOutInterests(counters.nOutInterests)
370 .setNInData(counters.nInData)
371 .setNOutData(counters.nOutData)
372 .setNInNacks(counters.nInNacks)
373 .setNOutNacks(counters.nOutNacks)
374 .setNInBytes(counters.nInBytes)
375 .setNOutBytes(counters.nOutBytes);
381 FaceManager::listFaces(ndn::mgmt::StatusDatasetContext& context)
383 auto now = time::steady_clock::now();
384 for (
const auto& face : m_faceTable) {
386 context.append(status.wireEncode());
392 FaceManager::listChannels(ndn::mgmt::StatusDatasetContext& context)
394 auto factories = m_faceSystem.listProtocolFactories();
395 for (
const auto* factory : factories) {
396 for (
const auto& channel : factory->getChannels()) {
397 ndn::nfd::ChannelStatus entry;
398 entry.setLocalUri(channel->getUri().toString());
399 context.append(entry.wireEncode());
406 matchFilter(
const ndn::nfd::FaceQueryFilter& filter,
const Face& face)
408 if (filter.hasFaceId() &&
409 filter.getFaceId() !=
static_cast<uint64_t
>(face.getId())) {
413 if (filter.hasUriScheme() &&
414 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
415 filter.getUriScheme() != face.getLocalUri().getScheme()) {
419 if (filter.hasRemoteUri() &&
420 filter.getRemoteUri() != face.getRemoteUri().toString()) {
424 if (filter.hasLocalUri() &&
425 filter.getLocalUri() != face.getLocalUri().toString()) {
429 if (filter.hasFaceScope() &&
430 filter.getFaceScope() != face.getScope()) {
434 if (filter.hasFacePersistency() &&
435 filter.getFacePersistency() != face.getPersistency()) {
439 if (filter.hasLinkType() &&
440 filter.getLinkType() != face.getLinkType()) {
448 FaceManager::queryFaces(
const Interest& interest,
449 ndn::mgmt::StatusDatasetContext& context)
451 ndn::nfd::FaceQueryFilter faceFilter;
453 faceFilter.wireDecode(interest.getName()[-1].blockFromValue());
455 catch (
const tlv::Error& e) {
457 return context.reject(ControlResponse(400,
"Malformed filter"));
460 auto now = time::steady_clock::now();
461 for (
const auto& face : m_faceTable) {
464 context.append(status.wireEncode());
471 FaceManager::notifyFaceEvent(
const Face& face, ndn::nfd::FaceEventKind kind)
473 ndn::nfd::FaceEventNotification notification;
474 notification.setKind(kind);
477 m_postNotification(notification.wireEncode());
481 FaceManager::connectFaceStateChangeSignal(
const Face& face)
485 FaceId faceId = face.getId();
486 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
488 if (newState == FaceState::UP) {
489 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
491 else if (newState == FaceState::DOWN) {
492 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
494 else if (newState == FaceState::CLOSED) {
496 m_faceStateChangeConn.erase(faceId);
void registerStatusDatasetHandler(const std::string &verb, const ndn::mgmt::StatusDatasetHandler &handler)
static void updateLinkServiceOptions(Face &face, const ControlParameters ¶meters)
const ssize_t MTU_UNLIMITED
indicates the transport has no limit on payload size
const Options & getOptions() const
get Options used by GenericLinkService
boost::logic::tribool wantCongestionMarking
optional< uint64_t > defaultCongestionThreshold
GenericLinkService is a LinkService that implements the NDNLPv2 protocol.
Face * get(FaceId id) const
get face by FaceId
FaceManager(FaceSystem &faceSystem, Dispatcher &dispatcher, CommandAuthenticator &authenticator)
Parameters used to set Transport properties or LinkService options on a newly created face...
Provides ControlCommand authorization according to NFD configuration file.
A collection of common functions shared by all NFD managers, such as communicating with the dispatche...
static ndn::nfd::FaceStatus makeFaceStatus(const Face &face, const time::steady_clock::TimePoint &now)
void createFace(const CreateFaceRequest &req, const FaceCreatedCallback &onCreated, const FaceCreationFailedCallback &onFailure)
Create a unicast face.
optional< time::nanoseconds > baseCongestionMarkingInterval
static ControlParameters makeCreateFaceResponse(const Face &face)
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
static void copyMtu(const Face &face, T &to)
signal::Signal< FaceTable, Face & > beforeRemove
fires before a face is removed
ndn::mgmt::PostNotification registerNotificationStream(const std::string &verb)
signal::Signal< FaceTable, Face & > afterAdd
fires after a face is added
static bool matchFilter(const ndn::nfd::FaceQueryFilter &filter, const Face &face)
ndn::nfd::FacePersistency persistency
Provides support for an underlying protocol.
#define NFD_LOG_INIT(name)
bool allowLocalFields
enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy ...
uint64_t FaceId
identifies a face
const FaceId INVALID_FACEID
indicates an invalid FaceId
static ControlParameters makeUpdateFaceResponse(const Face &face)
static void copyFaceProperties(const Face &face, T &to)