31 #include <boost/logic/tribool.hpp> 33 #include <ndn-cxx/lp/tags.hpp> 34 #include <ndn-cxx/mgmt/nfd/channel-status.hpp> 41 Dispatcher& dispatcher,
44 , m_faceSystem(faceSystem)
45 , m_faceTable(faceSystem.getFaceTable())
48 registerCommandHandler<ndn::nfd::FaceCreateCommand>(
"create",
49 bind(&FaceManager::createFace,
this, _2, _3, _4, _5));
51 registerCommandHandler<ndn::nfd::FaceUpdateCommand>(
"update",
52 bind(&FaceManager::updateFace,
this, _2, _3, _4, _5));
54 registerCommandHandler<ndn::nfd::FaceDestroyCommand>(
"destroy",
55 bind(&FaceManager::destroyFace,
this, _2, _3, _4, _5));
64 m_faceAddConn = m_faceTable.
afterAdd.connect([
this] (
const Face& face) {
65 connectFaceStateChangeSignal(face);
66 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
68 m_faceRemoveConn = m_faceTable.
beforeRemove.connect([
this] (
const Face& face) {
69 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
74 FaceManager::createFace(
const Name& topPrefix,
const Interest& interest,
75 const ControlParameters& parameters,
76 const ndn::mgmt::CommandContinuation& done)
79 if (!remoteUri.parse(parameters.getUri())) {
80 NFD_LOG_TRACE(
"failed to parse remote URI: " << parameters.getUri());
81 done(ControlResponse(400,
"Malformed command"));
85 if (!remoteUri.isCanonical()) {
86 NFD_LOG_TRACE(
"received non-canonical remote URI: " << remoteUri.toString());
87 done(ControlResponse(400,
"Non-canonical remote URI"));
91 optional<FaceUri> localUri;
92 if (parameters.hasLocalUri()) {
95 if (!localUri->parse(parameters.getLocalUri())) {
96 NFD_LOG_TRACE(
"failed to parse local URI: " << parameters.getLocalUri());
97 done(ControlResponse(400,
"Malformed command"));
101 if (!localUri->isCanonical()) {
102 NFD_LOG_TRACE(
"received non-canonical local URI: " << localUri->toString());
103 done(ControlResponse(400,
"Non-canonical local URI"));
109 if (factory ==
nullptr) {
110 NFD_LOG_TRACE(
"received create request for unsupported protocol: " << remoteUri.getScheme());
111 done(ControlResponse(406,
"Unsupported protocol"));
116 faceParams.
persistency = parameters.getFacePersistency();
117 if (parameters.hasBaseCongestionMarkingInterval()) {
120 if (parameters.hasDefaultCongestionThreshold()) {
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 bind(&FaceManager::afterCreateFaceSuccess,
this, parameters, _1, done),
133 bind(&FaceManager::afterCreateFaceFailure,
this, _1, _2, done));
135 catch (
const std::runtime_error& error) {
137 done(ControlResponse(500,
"Face creation failed due to internal error"));
140 catch (
const std::logic_error& error) {
142 done(ControlResponse(500,
"Face creation failed due to internal error"));
148 FaceManager::afterCreateFaceSuccess(
const ControlParameters& parameters,
149 const shared_ptr<Face>& face,
150 const ndn::mgmt::CommandContinuation& done)
153 NFD_LOG_TRACE(
"Attempted to create duplicate face of " << face->getId());
155 ControlParameters response = collectFaceProperties(*face,
true);
156 done(ControlResponse(409,
"Face with remote URI already exists").setBody(response.wireEncode()));
162 BOOST_ASSERT(face->getScope() == ndn::nfd::FACE_SCOPE_LOCAL ||
163 !parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) ||
164 (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
165 !parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)));
167 m_faceTable.
add(face);
169 ControlParameters response = collectFaceProperties(*face,
true);
170 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
174 FaceManager::afterCreateFaceFailure(uint32_t status,
175 const std::string& reason,
176 const ndn::mgmt::CommandContinuation& done)
180 done(ControlResponse(status, reason));
184 FaceManager::updateFace(
const Name& topPrefix,
const Interest& interest,
185 const ControlParameters& parameters,
186 const ndn::mgmt::CommandContinuation& done)
188 FaceId faceId = parameters.getFaceId();
191 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
192 if (incomingFaceIdTag ==
nullptr) {
194 done(ControlResponse(404,
"No FaceId specified and IncomingFaceId not available"));
197 faceId = *incomingFaceIdTag;
200 Face* face = m_faceTable.
get(faceId);
202 if (face ==
nullptr) {
204 done(ControlResponse(404,
"Specified face does not exist"));
209 ControlParameters response;
210 bool areParamsValid =
true;
212 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
213 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
214 face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
215 NFD_LOG_TRACE(
"received request to enable local fields on non-local face");
216 areParamsValid =
false;
217 response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
218 parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
222 if (parameters.hasFacePersistency()) {
223 auto persistency = parameters.getFacePersistency();
224 if (!face->getTransport()->canChangePersistencyTo(persistency)) {
225 NFD_LOG_TRACE(
"cannot change face persistency to " << persistency);
226 areParamsValid =
false;
227 response.setFacePersistency(persistency);
231 if (!areParamsValid) {
232 done(ControlResponse(409,
"Invalid properties specified").setBody(response.wireEncode()));
237 if (parameters.hasFacePersistency()) {
238 face->setPersistency(parameters.getFacePersistency());
240 setLinkServiceOptions(*face, parameters);
243 response = collectFaceProperties(*face,
false);
245 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
249 FaceManager::destroyFace(
const Name& topPrefix,
const Interest& interest,
250 const ControlParameters& parameters,
251 const ndn::mgmt::CommandContinuation& done)
253 Face* face = m_faceTable.
get(parameters.getFaceId());
254 if (face !=
nullptr) {
258 done(ControlResponse(200,
"OK").setBody(parameters.wireEncode()));
262 FaceManager::setLinkServiceOptions(Face& face,
263 const ControlParameters& parameters)
266 BOOST_ASSERT(linkService !=
nullptr);
268 auto options = linkService->getOptions();
269 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
270 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
271 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
273 if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
274 options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
276 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
277 options.allowCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
279 if (parameters.hasBaseCongestionMarkingInterval()) {
280 options.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
282 if (parameters.hasDefaultCongestionThreshold()) {
283 options.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
285 linkService->setOptions(options);
289 FaceManager::collectFaceProperties(
const Face& face,
bool wantUris)
292 BOOST_ASSERT(linkService !=
nullptr);
293 auto options = linkService->getOptions();
295 ControlParameters params;
296 params.setFaceId(face.getId())
297 .setFacePersistency(face.getPersistency())
298 .setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
299 .setDefaultCongestionThreshold(options.defaultCongestionThreshold)
300 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields,
false)
301 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled,
false)
302 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking,
false);
304 params.setUri(face.getRemoteUri().toString())
305 .setLocalUri(face.getLocalUri().toString());
311 FaceManager::listFaces(
const Name& topPrefix,
const Interest& interest,
312 ndn::mgmt::StatusDatasetContext& context)
314 auto now = time::steady_clock::now();
315 for (
const Face& face : m_faceTable) {
316 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
317 context.append(status.wireEncode());
323 FaceManager::listChannels(
const Name& topPrefix,
const Interest& interest,
324 ndn::mgmt::StatusDatasetContext& context)
326 std::set<const face::ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
327 for (
const auto* factory : factories) {
328 for (
const auto& channel : factory->getChannels()) {
329 ndn::nfd::ChannelStatus entry;
330 entry.setLocalUri(channel->getUri().toString());
331 context.append(entry.wireEncode());
338 FaceManager::queryFaces(
const Name& topPrefix,
const Interest& interest,
339 ndn::mgmt::StatusDatasetContext& context)
341 ndn::nfd::FaceQueryFilter faceFilter;
342 const Name& query = interest.getName();
344 faceFilter.wireDecode(query[-1].blockFromValue());
346 catch (
const tlv::Error& e) {
348 return context.reject(ControlResponse(400,
"Malformed filter"));
351 auto now = time::steady_clock::now();
352 for (
const Face& face : m_faceTable) {
353 if (!matchFilter(faceFilter, face)) {
356 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
357 context.append(status.wireEncode());
364 FaceManager::matchFilter(
const ndn::nfd::FaceQueryFilter& filter,
const Face& face)
366 if (filter.hasFaceId() &&
367 filter.getFaceId() !=
static_cast<uint64_t
>(face.getId())) {
371 if (filter.hasUriScheme() &&
372 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
373 filter.getUriScheme() != face.getLocalUri().getScheme()) {
377 if (filter.hasRemoteUri() &&
378 filter.getRemoteUri() != face.getRemoteUri().toString()) {
382 if (filter.hasLocalUri() &&
383 filter.getLocalUri() != face.getLocalUri().toString()) {
387 if (filter.hasFaceScope() &&
388 filter.getFaceScope() != face.getScope()) {
392 if (filter.hasFacePersistency() &&
393 filter.getFacePersistency() != face.getPersistency()) {
397 if (filter.hasLinkType() &&
398 filter.getLinkType() != face.getLinkType()) {
406 FaceManager::collectFaceStatus(
const Face& face,
const time::steady_clock::TimePoint& now)
408 ndn::nfd::FaceStatus status;
410 collectFaceProperties(face, status);
412 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
413 if (expirationTime != time::steady_clock::TimePoint::max()) {
414 status.setExpirationPeriod(std::max(0_ms,
415 time::duration_cast<time::milliseconds>(expirationTime - now)));
420 if (linkService !=
nullptr) {
421 auto linkServiceOptions = linkService->
getOptions();
422 status.setBaseCongestionMarkingInterval(linkServiceOptions.baseCongestionMarkingInterval);
423 status.setDefaultCongestionThreshold(linkServiceOptions.defaultCongestionThreshold);
439 template<
typename FaceTraits>
441 FaceManager::collectFaceProperties(
const Face& face, FaceTraits& traits)
443 traits.setFaceId(face.getId())
444 .setRemoteUri(face.getRemoteUri().toString())
445 .setLocalUri(face.getLocalUri().toString())
446 .setFaceScope(face.getScope())
447 .setFacePersistency(face.getPersistency())
448 .setLinkType(face.getLinkType());
452 if (linkService !=
nullptr) {
453 auto linkServiceOptions = linkService->
getOptions();
454 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
455 traits.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED,
456 linkServiceOptions.reliabilityOptions.isEnabled);
457 traits.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED,
458 linkServiceOptions.allowCongestionMarking);
463 FaceManager::notifyFaceEvent(
const Face& face, ndn::nfd::FaceEventKind kind)
465 ndn::nfd::FaceEventNotification notification;
466 notification.setKind(kind);
467 collectFaceProperties(face, notification);
469 m_postNotification(notification.wireEncode());
473 FaceManager::connectFaceStateChangeSignal(
const Face& face)
477 FaceId faceId = face.getId();
478 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
480 if (newState == FaceState::UP) {
481 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
483 else if (newState == FaceState::DOWN) {
484 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
486 else if (newState == FaceState::CLOSED) {
488 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)
optional< uint64_t > defaultCongestionThreshold
#define NFD_LOG_DEBUG(expression)
const PacketCounter & nOutInterests
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...
TransportState FaceState
indicates the state of a face
signal::Signal< FaceTable, Face & > beforeRemove
fires before a face is removed
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)
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
const ByteCounter & nOutBytes
Provides support for an underlying protocol.
boost::logic::tribool wantCongestionMarking
#define NFD_LOG_INIT(name)
#define NFD_LOG_TRACE(expression)
uint64_t FaceId
identifies a face
const FaceId INVALID_FACEID
indicates an invalid FaceId
const PacketCounter & nInData
const PacketCounter & nInNacks
optional< time::nanoseconds > baseCongestionMarkingInterval