33 #include <boost/logic/tribool.hpp> 35 #include <ndn-cxx/lp/tags.hpp> 36 #include <ndn-cxx/mgmt/nfd/channel-status.hpp> 43 Dispatcher& dispatcher,
46 , m_faceSystem(faceSystem)
47 , m_faceTable(faceSystem.getFaceTable())
50 registerCommandHandler<ndn::nfd::FaceCreateCommand>(
"create",
51 bind(&FaceManager::createFace,
this, _2, _3, _4, _5));
53 registerCommandHandler<ndn::nfd::FaceUpdateCommand>(
"update",
54 bind(&FaceManager::updateFace,
this, _2, _3, _4, _5));
56 registerCommandHandler<ndn::nfd::FaceDestroyCommand>(
"destroy",
57 bind(&FaceManager::destroyFace,
this, _2, _3, _4, _5));
66 m_faceAddConn = m_faceTable.
afterAdd.connect([
this] (
const Face& face) {
67 connectFaceStateChangeSignal(face);
68 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_CREATED);
70 m_faceRemoveConn = m_faceTable.
beforeRemove.connect([
this] (
const Face& face) {
71 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DESTROYED);
76 FaceManager::createFace(
const Name& topPrefix,
const Interest& interest,
77 const ControlParameters& parameters,
78 const ndn::mgmt::CommandContinuation& done)
81 if (!remoteUri.parse(parameters.getUri())) {
82 NFD_LOG_TRACE(
"failed to parse remote URI: " << parameters.getUri());
83 done(ControlResponse(400,
"Malformed command"));
87 if (!remoteUri.isCanonical()) {
88 NFD_LOG_TRACE(
"received non-canonical remote URI: " << remoteUri.toString());
89 done(ControlResponse(400,
"Non-canonical remote URI"));
93 optional<FaceUri> localUri;
94 if (parameters.hasLocalUri()) {
97 if (!localUri->parse(parameters.getLocalUri())) {
98 NFD_LOG_TRACE(
"failed to parse local URI: " << parameters.getLocalUri());
99 done(ControlResponse(400,
"Malformed command"));
103 if (!localUri->isCanonical()) {
104 NFD_LOG_TRACE(
"received non-canonical local URI: " << localUri->toString());
105 done(ControlResponse(400,
"Non-canonical local URI"));
111 if (factory ==
nullptr) {
112 NFD_LOG_TRACE(
"received create request for unsupported protocol: " << remoteUri.getScheme());
113 done(ControlResponse(406,
"Unsupported protocol"));
118 faceParams.
persistency = parameters.getFacePersistency();
119 if (parameters.hasBaseCongestionMarkingInterval()) {
122 if (parameters.hasDefaultCongestionThreshold()) {
125 if (parameters.hasMtu()) {
126 faceParams.
mtu = parameters.getMtu();
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);
251 done(ControlResponse(200,
"OK").setBody(response.wireEncode()));
255 FaceManager::destroyFace(
const Name& topPrefix,
const Interest& interest,
256 const ControlParameters& parameters,
257 const ndn::mgmt::CommandContinuation& done)
259 Face* face = m_faceTable.
get(parameters.getFaceId());
260 if (face !=
nullptr) {
264 done(ControlResponse(200,
"OK").setBody(parameters.wireEncode()));
268 FaceManager::setLinkServiceOptions(Face& face,
269 const ControlParameters& parameters)
272 BOOST_ASSERT(linkService !=
nullptr);
274 auto options = linkService->getOptions();
275 if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
276 face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
277 options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
279 if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
280 options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
282 if (parameters.hasFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
283 options.allowCongestionMarking = parameters.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED);
285 if (parameters.hasBaseCongestionMarkingInterval()) {
286 options.baseCongestionMarkingInterval = parameters.getBaseCongestionMarkingInterval();
288 if (parameters.hasDefaultCongestionThreshold()) {
289 options.defaultCongestionThreshold = parameters.getDefaultCongestionThreshold();
291 linkService->setOptions(options);
295 FaceManager::collectFaceProperties(
const Face& face,
bool wantUris)
298 BOOST_ASSERT(linkService !=
nullptr);
299 auto options = linkService->getOptions();
301 auto transport = face.getTransport();
302 BOOST_ASSERT(transport !=
nullptr);
304 ControlParameters params;
305 params.setFaceId(face.getId())
306 .setFacePersistency(face.getPersistency())
307 .setBaseCongestionMarkingInterval(options.baseCongestionMarkingInterval)
308 .setDefaultCongestionThreshold(options.defaultCongestionThreshold)
309 .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields,
false)
310 .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled,
false)
311 .setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, options.allowCongestionMarking,
false);
313 if (transport->getMtu() > 0) {
314 params.setMtu(std::min<uint64_t>(transport->getMtu(), ndn::MAX_NDN_PACKET_SIZE));
317 params.setMtu(ndn::MAX_NDN_PACKET_SIZE);
321 params.setUri(face.getRemoteUri().toString())
322 .setLocalUri(face.getLocalUri().toString());
328 FaceManager::listFaces(
const Name& topPrefix,
const Interest& interest,
329 ndn::mgmt::StatusDatasetContext& context)
331 auto now = time::steady_clock::now();
332 for (
const Face& face : m_faceTable) {
333 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
334 context.append(status.wireEncode());
340 FaceManager::listChannels(
const Name& topPrefix,
const Interest& interest,
341 ndn::mgmt::StatusDatasetContext& context)
343 std::set<const face::ProtocolFactory*> factories = m_faceSystem.listProtocolFactories();
344 for (
const auto* factory : factories) {
345 for (
const auto& channel : factory->getChannels()) {
346 ndn::nfd::ChannelStatus entry;
347 entry.setLocalUri(channel->getUri().toString());
348 context.append(entry.wireEncode());
355 FaceManager::queryFaces(
const Name& topPrefix,
const Interest& interest,
356 ndn::mgmt::StatusDatasetContext& context)
358 ndn::nfd::FaceQueryFilter faceFilter;
359 const Name& query = interest.getName();
361 faceFilter.wireDecode(query[-1].blockFromValue());
363 catch (
const tlv::Error& e) {
365 return context.reject(ControlResponse(400,
"Malformed filter"));
368 auto now = time::steady_clock::now();
369 for (
const Face& face : m_faceTable) {
370 if (!matchFilter(faceFilter, face)) {
373 ndn::nfd::FaceStatus status = collectFaceStatus(face, now);
374 context.append(status.wireEncode());
381 FaceManager::matchFilter(
const ndn::nfd::FaceQueryFilter& filter,
const Face& face)
383 if (filter.hasFaceId() &&
384 filter.getFaceId() !=
static_cast<uint64_t
>(face.getId())) {
388 if (filter.hasUriScheme() &&
389 filter.getUriScheme() != face.getRemoteUri().getScheme() &&
390 filter.getUriScheme() != face.getLocalUri().getScheme()) {
394 if (filter.hasRemoteUri() &&
395 filter.getRemoteUri() != face.getRemoteUri().toString()) {
399 if (filter.hasLocalUri() &&
400 filter.getLocalUri() != face.getLocalUri().toString()) {
404 if (filter.hasFaceScope() &&
405 filter.getFaceScope() != face.getScope()) {
409 if (filter.hasFacePersistency() &&
410 filter.getFacePersistency() != face.getPersistency()) {
414 if (filter.hasLinkType() &&
415 filter.getLinkType() != face.getLinkType()) {
423 FaceManager::collectFaceStatus(
const Face& face,
const time::steady_clock::TimePoint& now)
425 ndn::nfd::FaceStatus status;
427 collectFaceProperties(face, status);
429 time::steady_clock::TimePoint expirationTime = face.getExpirationTime();
430 if (expirationTime != time::steady_clock::TimePoint::max()) {
431 status.setExpirationPeriod(std::max(0_ms,
432 time::duration_cast<time::milliseconds>(expirationTime - now)));
437 if (linkService !=
nullptr) {
438 auto linkServiceOptions = linkService->
getOptions();
439 status.setBaseCongestionMarkingInterval(linkServiceOptions.baseCongestionMarkingInterval);
440 status.setDefaultCongestionThreshold(linkServiceOptions.defaultCongestionThreshold);
456 template<
typename FaceTraits>
458 FaceManager::collectFaceProperties(
const Face& face, FaceTraits& traits)
460 traits.setFaceId(face.getId())
461 .setRemoteUri(face.getRemoteUri().toString())
462 .setLocalUri(face.getLocalUri().toString())
463 .setFaceScope(face.getScope())
464 .setFacePersistency(face.getPersistency())
465 .setLinkType(face.getLinkType());
469 if (linkService !=
nullptr) {
470 auto linkServiceOptions = linkService->
getOptions();
471 traits.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, linkServiceOptions.allowLocalFields);
472 traits.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED,
473 linkServiceOptions.reliabilityOptions.isEnabled);
474 traits.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED,
475 linkServiceOptions.allowCongestionMarking);
480 FaceManager::notifyFaceEvent(
const Face& face, ndn::nfd::FaceEventKind kind)
482 ndn::nfd::FaceEventNotification notification;
483 notification.setKind(kind);
484 collectFaceProperties(face, notification);
486 m_postNotification(notification.wireEncode());
490 FaceManager::connectFaceStateChangeSignal(
const Face& face)
494 FaceId faceId = face.getId();
495 m_faceStateChangeConn[faceId] = face.afterStateChange.connect(
497 if (newState == FaceState::UP) {
498 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_UP);
500 else if (newState == FaceState::DOWN) {
501 notifyFaceEvent(face, ndn::nfd::FACE_EVENT_DOWN);
503 else if (newState == FaceState::CLOSED) {
505 m_faceStateChangeConn.erase(faceId);
void registerStatusDatasetHandler(const std::string &verb, const ndn::mgmt::StatusDatasetHandler &handler)
const PacketCounter & nOutInterests
const ssize_t MTU_UNLIMITED
indicates the transport has no limit on payload size
const Options & getOptions() const
get Options used by GenericLinkService
const PacketCounter & nOutData
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.
const ByteCounter & nInBytes
optional< time::nanoseconds > baseCongestionMarkingInterval
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
ndn::nfd::FacePersistency persistency
const ByteCounter & nOutBytes
Provides support for an underlying protocol.
#define NFD_LOG_INIT(name)
uint64_t FaceId
identifies a face
const FaceId INVALID_FACEID
indicates an invalid FaceId
const PacketCounter & nInData
const PacketCounter & nInNacks