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> 44 Dispatcher& dispatcher,
47 , m_faceSystem(faceSystem)
48 , m_faceTable(faceSystem.getFaceTable())
51 registerCommandHandler<ndn::nfd::FaceCreateCommand>(
"create", bind(&FaceManager::createFace,
this, _4, _5));
52 registerCommandHandler<ndn::nfd::FaceUpdateCommand>(
"update", bind(&FaceManager::updateFace,
this, _3, _4, _5));
53 registerCommandHandler<ndn::nfd::FaceDestroyCommand>(
"destroy", bind(&FaceManager::destroyFace,
this, _4, _5));
62 m_faceAddConn = m_faceTable.
afterAdd.connect([
this] (
const Face& face) {
63 connectFaceStateChangeSignal(face);
64 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
66 m_faceRemoveConn = m_faceTable.
beforeRemove.connect([
this] (
const Face& face) {
67 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
72 FaceManager::createFace(
const ControlParameters& parameters,
73 const ndn::mgmt::CommandContinuation& done)
76 if (!remoteUri.parse(parameters.getUri())) {
77 NFD_LOG_TRACE(
"failed to parse remote URI: " << parameters.getUri());
78 done(ControlResponse(400,
"Malformed command"));
82 if (!remoteUri.isCanonical()) {
83 NFD_LOG_TRACE(
"received non-canonical remote URI: " << remoteUri.toString());
84 done(ControlResponse(400,
"Non-canonical remote URI"));
88 optional<FaceUri> localUri;
89 if (parameters.hasLocalUri()) {
92 if (!localUri->parse(parameters.getLocalUri())) {
93 NFD_LOG_TRACE(
"failed to parse local URI: " << parameters.getLocalUri());
94 done(ControlResponse(400,
"Malformed command"));
98 if (!localUri->isCanonical()) {
99 NFD_LOG_TRACE(
"received non-canonical local URI: " << localUri->toString());
100 done(ControlResponse(400,
"Non-canonical local URI"));
106 if (factory ==
nullptr) {
107 NFD_LOG_TRACE(
"received create request for unsupported protocol: " << remoteUri.getScheme());
108 done(ControlResponse(406,
"Unsupported protocol"));
113 faceParams.
persistency = parameters.getFacePersistency();
114 if (parameters.hasBaseCongestionMarkingInterval()) {
117 if (parameters.hasDefaultCongestionThreshold()) {
120 if (parameters.hasMtu()) {
121 faceParams.
mtu = parameters.getMtu();
123 faceParams.
wantLocalFields = parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
124 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
125 faceParams.
wantLpReliability = parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) &&
126 parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
127 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
131 factory->
createFace({remoteUri, localUri, faceParams},
132 [
this, parameters, done] (
const auto& face) {
133 this->afterCreateFaceSuccess(face, parameters, done);
135 [done] (uint32_t status,
const std::string& reason) {
137 done(ControlResponse(status, reason));
140 catch (
const std::runtime_error& error) {
142 done(ControlResponse(500,
"Face creation failed due to internal error"));
145 catch (
const std::logic_error& error) {
147 done(ControlResponse(500,
"Face creation failed due to internal error"));
156 auto transport = face.getTransport();
157 BOOST_ASSERT(transport !=
nullptr);
159 if (transport->getMtu() > 0) {
160 to.setMtu(std::min(static_cast<size_t>(transport->getMtu()), ndn::MAX_NDN_PACKET_SIZE));
163 to.setMtu(ndn::MAX_NDN_PACKET_SIZE);
167 static ControlParameters
170 ControlParameters params;
171 params.setFaceId(face.getId())
172 .setFacePersistency(face.getPersistency());
175 if (linkService !=
nullptr) {
176 const auto& options = linkService->
getOptions();
177 params.setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
178 .setDefaultCongestionThreshold(options.defaultCongestionThreshold)
179 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields,
false)
180 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled,
false)
181 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking,
false);
187 static ControlParameters
191 params.setUri(face.getRemoteUri().toString())
192 .setLocalUri(face.getLocalUri().toString());
200 FaceManager::afterCreateFaceSuccess(
const shared_ptr<Face>& face,
201 const ControlParameters& parameters,
202 const ndn::mgmt::CommandContinuation& done)
205 NFD_LOG_TRACE(
"Attempted to create duplicate face of " << face->getId());
207 done(ControlResponse(409,
"Face with remote URI already exists").setBody(response.wireEncode()));
213 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
214 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
215 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
216 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
218 m_faceTable.
add(face);
221 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
228 if (linkService ==
nullptr) {
233 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
234 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
235 options.
allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
237 if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
238 options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
240 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
241 options.allowCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
243 if (parameters.hasBaseCongestionMarkingInterval()) {
244 options.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
246 if (parameters.hasDefaultCongestionThreshold()) {
247 options.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
250 linkService->setOptions(options);
254 FaceManager::updateFace(
const Interest& interest,
255 const ControlParameters& parameters,
256 const ndn::mgmt::CommandContinuation& done)
258 FaceId faceId = parameters.getFaceId();
260 auto incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
261 if (incomingFaceIdTag ==
nullptr) {
263 done(ControlResponse(404,
"No FaceId specified and IncomingFaceId not available"));
266 faceId = *incomingFaceIdTag;
269 Face* face = m_faceTable.
get(faceId);
270 if (face ==
nullptr) {
272 done(ControlResponse(404,
"Specified face does not exist"));
277 ControlParameters response;
278 bool areParamsValid =
true;
280 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
281 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
282 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
283 NFD_LOG_TRACE(
"received request to enable local fields on non-local face");
284 areParamsValid =
false;
285 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
286 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
290 if (parameters.hasFacePersistency()) {
291 auto persistency = parameters.getFacePersistency();
292 if (!face->getTransport()->canChangePersistencyTo(persistency)) {
293 NFD_LOG_TRACE(
"cannot change face persistency to " << persistency);
294 areParamsValid =
false;
295 response.setFacePersistency(persistency);
299 if (!areParamsValid) {
300 done(ControlResponse(409,
"Invalid properties specified").setBody(response.wireEncode()));
305 if (parameters.hasFacePersistency()) {
306 face->setPersistency(parameters.getFacePersistency());
312 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
316 FaceManager::destroyFace(
const ControlParameters& parameters,
317 const ndn::mgmt::CommandContinuation& done)
319 Face* face = m_faceTable.
get(parameters.getFaceId());
320 if (face !=
nullptr) {
324 done(ControlResponse(200,
"OK").setBody(parameters.wireEncode()));
331 to.setFaceId(face.getId())
332 .setRemoteUri(face.getRemoteUri().toString())
333 .setLocalUri(face.getLocalUri().toString())
334 .setFaceScope(face.getScope())
335 .setFacePersistency(face.getPersistency())
336 .setLinkType(face.getLinkType());
339 if (linkService !=
nullptr) {
340 const auto& options = linkService->
getOptions();
341 to.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields)
342 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled)
343 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking);
347 static ndn::nfd::FaceStatus
350 ndn::nfd::FaceStatus status;
353 auto expirationTime = face.getExpirationTime();
354 if (expirationTime != time::steady_clock::TimePoint::max()) {
355 status.setExpirationPeriod(std::max(0_ms,
356 time::duration_cast<time::milliseconds>(expirationTime - now)));
360 if (linkService !=
nullptr) {
361 const auto& options = linkService->
getOptions();
362 status.setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
363 .setDefaultCongestionThreshold(options.defaultCongestionThreshold);
368 const auto& counters = face.getCounters();
369 status.setNInInterests(counters.nInInterests)
370 .setNOutInterests(counters.nOutInterests)
371 .setNInData(counters.nInData)
372 .setNOutData(counters.nOutData)
373 .setNInNacks(counters.nInNacks)
374 .setNOutNacks(counters.nOutNacks)
375 .setNInBytes(counters.nInBytes)
376 .setNOutBytes(counters.nOutBytes);
382 FaceManager::listFaces(ndn::mgmt::StatusDatasetContext& context)
384 auto now = time::steady_clock::now();
385 for (
const auto& face : m_faceTable) {
387 context.append(status.wireEncode());
393 FaceManager::listChannels(ndn::mgmt::StatusDatasetContext& context)
395 auto factories = m_faceSystem.listProtocolFactories();
396 for (
const auto* factory : factories) {
397 for (
const auto& channel : factory->getChannels()) {
398 ndn::nfd::ChannelStatus entry;
399 entry.setLocalUri(channel->getUri().toString());
400 context.append(entry.wireEncode());
407 matchFilter(
const ndn::nfd::FaceQueryFilter& filter,
const Face& face)
409 if (filter.hasFaceId() &&
410 filter.getFaceId() !=
static_cast<uint64_t
>(face.getId())) {
414 if (filter.hasUriScheme() &&
415 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
416 filter.getUriScheme() != face.getLocalUri().getScheme()) {
420 if (filter.hasRemoteUri() &&
421 filter.getRemoteUri() != face.getRemoteUri().toString()) {
425 if (filter.hasLocalUri() &&
426 filter.getLocalUri() != face.getLocalUri().toString()) {
430 if (filter.hasFaceScope() &&
431 filter.getFaceScope() != face.getScope()) {
435 if (filter.hasFacePersistency() &&
436 filter.getFacePersistency() != face.getPersistency()) {
440 if (filter.hasLinkType() &&
441 filter.getLinkType() != face.getLinkType()) {
449 FaceManager::queryFaces(
const Interest& interest,
450 ndn::mgmt::StatusDatasetContext& context)
452 ndn::nfd::FaceQueryFilter faceFilter;
454 faceFilter.wireDecode(interest.getName()[-1].blockFromValue());
456 catch (
const tlv::Error& e) {
458 return context.reject(ControlResponse(400,
"Malformed filter"));
461 auto now = time::steady_clock::now();
462 for (
const auto& face : m_faceTable) {
465 context.append(status.wireEncode());
472 FaceManager::notifyFaceEvent(
const Face& face, ndn::nfd::FaceEventKind kind)
474 ndn::nfd::FaceEventNotification notification;
475 notification.setKind(kind);
478 m_postNotification(notification.wireEncode());
482 FaceManager::connectFaceStateChangeSignal(
const Face& face)
486 FaceId faceId = face.getId();
487 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
489 if (newState == FaceState::UP) {
490 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
492 else if (newState == FaceState::DOWN) {
493 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
495 else if (newState == FaceState::CLOSED) {
497 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.
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)
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
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)