31 #include <boost/logic/tribool.hpp> 33 #include <ndn-cxx/lp/tags.hpp> 34 #include <ndn-cxx/mgmt/nfd/channel-status.hpp> 43 , m_faceSystem(faceSystem)
44 , m_faceTable(faceSystem.getFaceTable())
47 registerCommandHandler<ndn::nfd::FaceCreateCommand>(
"create",
48 bind(&FaceManager::createFace,
this, _2, _3, _4, _5));
50 registerCommandHandler<ndn::nfd::FaceUpdateCommand>(
"update",
51 bind(&FaceManager::updateFace,
this, _2, _3, _4, _5));
53 registerCommandHandler<ndn::nfd::FaceDestroyCommand>(
"destroy",
54 bind(&FaceManager::destroyFace,
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 (!remoteUri.parse(parameters.getUri())) {
85 NFD_LOG_TRACE(
"failed to parse remote URI: " << parameters.getUri());
86 done(ControlResponse(400,
"Malformed command"));
90 if (!remoteUri.isCanonical()) {
91 NFD_LOG_TRACE(
"received non-canonical remote URI: " << remoteUri.toString());
92 done(ControlResponse(400,
"Non-canonical remote URI"));
96 ndn::optional<FaceUri> localUri;
97 if (parameters.hasLocalUri()) {
100 if (!localUri->parse(parameters.getLocalUri())) {
101 NFD_LOG_TRACE(
"failed to parse local URI: " << parameters.getLocalUri());
102 done(ControlResponse(400,
"Malformed command"));
106 if (!localUri->isCanonical()) {
107 NFD_LOG_TRACE(
"received non-canonical local URI: " << localUri->toString());
108 done(ControlResponse(400,
"Non-canonical local URI"));
114 if (factory ==
nullptr) {
115 NFD_LOG_TRACE(
"received create request for unsupported protocol: " << remoteUri.getScheme());
116 done(ControlResponse(406,
"Unsupported protocol"));
121 faceParams.
persistency = parameters.getFacePersistency();
122 if (parameters.hasBaseCongestionMarkingInterval()) {
125 if (parameters.hasDefaultCongestionThreshold()) {
128 faceParams.
wantLocalFields = parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
129 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
130 faceParams.
wantLpReliability = parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) &&
131 parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
132 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
136 factory->
createFace({remoteUri, localUri, faceParams},
137 bind(&FaceManager::afterCreateFaceSuccess,
this, parameters, _1, done),
138 bind(&FaceManager::afterCreateFaceFailure,
this, _1, _2, done));
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"));
153 FaceManager::afterCreateFaceSuccess(
const ControlParameters& parameters,
154 const shared_ptr<Face>& face,
155 const ndn::mgmt::CommandContinuation& done)
158 NFD_LOG_TRACE(
"Attempted to create duplicate face of " << face->getId());
160 ControlParameters response = collectFaceProperties(*face,
true);
161 done(ControlResponse(409,
"Face with remote URI already exists").setBody(response.wireEncode()));
167 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
168 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
169 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
170 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
172 m_faceTable.
add(face);
174 ControlParameters response = collectFaceProperties(*face,
true);
175 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
179 FaceManager::afterCreateFaceFailure(uint32_t status,
180 const std::string& reason,
181 const ndn::mgmt::CommandContinuation& done)
185 done(ControlResponse(status, reason));
189 FaceManager::updateFace(
const Name& topPrefix,
const Interest& interest,
190 const ControlParameters& parameters,
191 const ndn::mgmt::CommandContinuation& done)
193 FaceId faceId = parameters.getFaceId();
196 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
197 if (incomingFaceIdTag ==
nullptr) {
199 done(ControlResponse(404,
"No FaceId specified and IncomingFaceId not available"));
202 faceId = *incomingFaceIdTag;
205 Face* face = m_faceTable.
get(faceId);
207 if (face ==
nullptr) {
209 done(ControlResponse(404,
"Specified face does not exist"));
214 ControlParameters response;
215 bool areParamsValid =
true;
217 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
218 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
219 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
220 NFD_LOG_TRACE(
"received request to enable local fields on non-local face");
221 areParamsValid =
false;
222 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
223 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
227 if (parameters.hasFacePersistency()) {
228 auto persistency = parameters.getFacePersistency();
229 if (!face->getTransport()->canChangePersistencyTo(persistency)) {
230 NFD_LOG_TRACE(
"cannot change face persistency to " << persistency);
231 areParamsValid =
false;
232 response.setFacePersistency(persistency);
236 if (!areParamsValid) {
237 done(ControlResponse(409,
"Invalid properties specified").setBody(response.wireEncode()));
242 if (parameters.hasFacePersistency()) {
243 face->setPersistency(parameters.getFacePersistency());
245 setLinkServiceOptions(*face, parameters);
248 response = collectFaceProperties(*face,
false);
250 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
254 FaceManager::destroyFace(
const Name& topPrefix,
const Interest& interest,
255 const ControlParameters& parameters,
256 const ndn::mgmt::CommandContinuation& done)
258 Face* face = m_faceTable.
get(parameters.getFaceId());
259 if (face !=
nullptr) {
263 done(ControlResponse(200,
"OK").setBody(parameters.wireEncode()));
267 FaceManager::setLinkServiceOptions(Face& face,
268 const ControlParameters& parameters)
271 BOOST_ASSERT(linkService !=
nullptr);
273 auto options = linkService->getOptions();
274 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
275 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
276 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
278 if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
279 options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
281 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
282 options.allowCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
284 if (parameters.hasBaseCongestionMarkingInterval()) {
285 options.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
287 if (parameters.hasDefaultCongestionThreshold()) {
288 options.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
290 linkService->setOptions(options);
294 FaceManager::collectFaceProperties(
const Face& face,
bool wantUris)
297 BOOST_ASSERT(linkService !=
nullptr);
298 auto options = linkService->getOptions();
300 ControlParameters params;
301 params.setFaceId(face.getId())
302 .setFacePersistency(face.getPersistency())
303 .setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
304 .setDefaultCongestionThreshold(options.defaultCongestionThreshold)
305 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields,
false)
306 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled,
false)
307 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking,
false);
309 params.setUri(face.getRemoteUri().toString())
310 .setLocalUri(face.getLocalUri().toString());
316 FaceManager::listFaces(
const Name& topPrefix,
const Interest& interest,
317 ndn::mgmt::StatusDatasetContext& context)
319 auto now = time::steady_clock::now();
320 for (
const Face& face : m_faceTable) {
321 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
322 context.append(status.wireEncode());
328 FaceManager::listChannels(
const Name& topPrefix,
const Interest& interest,
329 ndn::mgmt::StatusDatasetContext& context)
331 std::set<const face::ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
332 for (
const auto* factory : factories) {
333 for (
const auto& channel : factory->getChannels()) {
334 ndn::nfd::ChannelStatus entry;
335 entry.setLocalUri(channel->getUri().toString());
336 context.append(entry.wireEncode());
343 FaceManager::queryFaces(
const Name& topPrefix,
const Interest& interest,
344 ndn::mgmt::StatusDatasetContext& context)
346 ndn::nfd::FaceQueryFilter faceFilter;
347 const Name& query = interest.getName();
349 faceFilter.wireDecode(query[-1].blockFromValue());
351 catch (
const tlv::Error& e) {
353 return context.reject(ControlResponse(400,
"Malformed filter"));
356 auto now = time::steady_clock::now();
357 for (
const Face& face : m_faceTable) {
358 if (!matchFilter(faceFilter, face)) {
361 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
362 context.append(status.wireEncode());
369 FaceManager::matchFilter(
const ndn::nfd::FaceQueryFilter& filter,
const Face& face)
371 if (filter.hasFaceId() &&
372 filter.getFaceId() !=
static_cast<uint64_t
>(face.getId())) {
376 if (filter.hasUriScheme() &&
377 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
378 filter.getUriScheme() != face.getLocalUri().getScheme()) {
382 if (filter.hasRemoteUri() &&
383 filter.getRemoteUri() != face.getRemoteUri().toString()) {
387 if (filter.hasLocalUri() &&
388 filter.getLocalUri() != face.getLocalUri().toString()) {
392 if (filter.hasFaceScope() &&
393 filter.getFaceScope() != face.getScope()) {
397 if (filter.hasFacePersistency() &&
398 filter.getFacePersistency() != face.getPersistency()) {
402 if (filter.hasLinkType() &&
403 filter.getLinkType() != face.getLinkType()) {
411 FaceManager::collectFaceStatus(
const Face& face,
const time::steady_clock::TimePoint& now)
413 ndn::nfd::FaceStatus status;
415 collectFaceProperties(face, status);
417 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
418 if (expirationTime != time::steady_clock::TimePoint::max()) {
419 status.setExpirationPeriod(std::max(0_ms,
420 time::duration_cast<time::milliseconds>(expirationTime - now)));
425 if (linkService !=
nullptr) {
426 auto linkServiceOptions = linkService->
getOptions();
427 status.setBaseCongestionMarkingInterval(linkServiceOptions.baseCongestionMarkingInterval);
428 status.setDefaultCongestionThreshold(linkServiceOptions.defaultCongestionThreshold);
444 template<
typename FaceTraits>
446 FaceManager::collectFaceProperties(
const Face& face, FaceTraits& traits)
448 traits.setFaceId(face.getId())
449 .setRemoteUri(face.getRemoteUri().toString())
450 .setLocalUri(face.getLocalUri().toString())
451 .setFaceScope(face.getScope())
452 .setFacePersistency(face.getPersistency())
453 .setLinkType(face.getLinkType());
457 if (linkService !=
nullptr) {
458 auto linkServiceOptions = linkService->
getOptions();
459 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
460 traits.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED,
461 linkServiceOptions.reliabilityOptions.isEnabled);
462 traits.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED,
463 linkServiceOptions.allowCongestionMarking);
468 FaceManager::notifyFaceEvent(
const Face& face, ndn::nfd::FaceEventKind kind)
470 ndn::nfd::FaceEventNotification notification;
471 notification.setKind(kind);
472 collectFaceProperties(face, notification);
474 m_postNotification(notification.wireEncode());
478 FaceManager::connectFaceStateChangeSignal(
const Face& face)
480 FaceId faceId = face.getId();
481 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
483 const Face& face = *m_faceTable.
get(faceId);
486 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
489 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
492 m_faceStateChangeConn.erase(faceId);
Parameters used to set Transport properties or LinkService options on a newly created face...
void registerStatusDatasetHandler(const std::string &verb, const ndn::mgmt::StatusDatasetHandler &handler)
#define NFD_LOG_DEBUG(expression)
const PacketCounter & nOutInterests
configuration file parsing utility
TransportState
indicates the state of a transport
const Options & getOptions() const
get Options used by GenericLinkService
const PacketCounter & nOutData
ndn::nfd::FacePersistency persistency
GenericLinkService is a LinkService that implements the NDNLPv2 protocol.
Face * get(FaceId id) const
get face by FaceId
#define NFD_LOG_ERROR(expression)
FaceManager(FaceSystem &faceSystem, Dispatcher &dispatcher, CommandAuthenticator &authenticator)
provides ControlCommand authorization according to NFD configuration file
const ByteCounter & nInBytes
void add(shared_ptr< Face > face)
add a face
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
signal::Signal< FaceTable, Face & > beforeRemove
fires before a face is removed
the transport is closed, and can be safely deallocated
virtual void createFace(const CreateFaceRequest &req, const FaceCreatedCallback &onCreated, const FaceCreationFailedCallback &onFailure)=0
Try to create a unicast face using the supplied parameters.
ndn::mgmt::PostNotification registerNotificationStream(const std::string &verb)
ndn::optional< time::nanoseconds > baseCongestionMarkingInterval
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
const PacketCounter & nOutNacks
gives access to counters provided by Face
const PacketCounter & nInInterests
void setConfigFile(ConfigFile &configFile)
Subscribe to face_system section for the config file.
ndn::optional< uint64_t > defaultCongestionThreshold
const ByteCounter & nOutBytes
Provides support for an underlying protocol.
boost::logic::tribool wantCongestionMarking
#define NFD_LOG_INIT(name)
#define NFD_LOG_TRACE(expression)
the transport is up and can transmit packets
uint64_t FaceId
identifies a face
const FaceId INVALID_FACEID
indicates an invalid FaceId
const PacketCounter & nInData
const PacketCounter & nInNacks
the transport is temporarily down, and is being recovered