33 #include <ndn-cxx/lp/tags.hpp> 34 #include <ndn-cxx/mgmt/nfd/face-status.hpp> 35 #include <ndn-cxx/mgmt/nfd/rib-entry.hpp> 36 #include <ndn-cxx/security/certificate-fetcher-direct-fetch.hpp> 52 ndn::nfd::Controller& nfdController, Dispatcher& dispatcher)
55 , m_keyChain(keyChain)
56 , m_nfdController(nfdController)
57 , m_dispatcher(dispatcher)
59 , m_localhostValidator(face)
60 , m_localhopValidator(make_unique<
ndn::security::CertificateFetcherDirectFetch>(face))
61 , m_paValidator(make_unique<
ndn::security::CertificateFetcherDirectFetch>(face))
62 , m_isLocalhopEnabled(false)
64 registerCommandHandler<ndn::nfd::RibRegisterCommand>(
"register",
65 bind(&RibManager::registerEntry,
this, _2, _3, _4, _5));
66 registerCommandHandler<ndn::nfd::RibUnregisterCommand>(
"unregister",
67 bind(&RibManager::unregisterEntry,
this, _2, _3, _4, _5));
75 m_localhostValidator.load(section, filename);
81 m_localhopValidator.load(section, filename);
82 m_isLocalhopEnabled =
true;
88 m_isLocalhopEnabled =
false;
94 m_paValidator.load(section, filename);
100 registerTopPrefix(LOCALHOST_TOP_PREFIX);
102 if (m_isLocalhopEnabled) {
106 NFD_LOG_INFO(
"Start monitoring face create/destroy events");
107 m_faceMonitor.onNotification.connect(bind(&RibManager::onNotification,
this, _1));
108 m_faceMonitor.start();
110 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
116 m_nfdController.start<ndn::nfd::FaceUpdateCommand>(
117 ControlParameters().setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
true),
118 [] (
const ControlParameters&) {
121 [] (
const ControlResponse& res) {
122 NDN_THROW(
Error(
"Couldn't enable local fields (" + to_string(res.getCode()) +
123 " " + res.getText() +
")"));
128 RibManager::beginAddRoute(
const Name& name,
Route route, optional<time::nanoseconds> expires,
129 const std::function<
void(RibUpdateResult)>& done)
132 route.
expires = time::steady_clock::now() + *expires;
135 expires = *route.
expires - time::steady_clock::now();
138 if (expires && *expires <= 0_s) {
140 return done(RibUpdateResult::EXPIRED);
144 " origin=" << route.
origin <<
" cost=" << route.
cost);
156 beginRibUpdate(update, done);
160 RibManager::beginRemoveRoute(
const Name& name,
const Route& route,
161 const std::function<
void(RibUpdateResult)>& done)
164 " origin=" << route.
origin);
170 beginRibUpdate(update, done);
174 RibManager::beginRibUpdate(
const RibUpdate& update,
175 const std::function<
void(RibUpdateResult)>& done)
180 done(RibUpdateResult::OK);
182 [=] (uint32_t code,
const std::string& error) {
183 NFD_LOG_DEBUG(
"RIB update failed for " << update <<
" (" << code <<
" " << error <<
")");
186 scheduleActiveFaceFetch(1_s);
188 done(RibUpdateResult::ERROR);
193 RibManager::registerTopPrefix(
const Name& topPrefix)
196 m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
197 ControlParameters().setName(Name(topPrefix).append(MGMT_MODULE_NAME))
199 [=] (
const ControlParameters& res) {
200 NFD_LOG_DEBUG(
"Successfully registered " << topPrefix <<
" with NFD");
204 route.
faceId = res.getFaceId();
205 route.
origin = ndn::nfd::ROUTE_ORIGIN_APP;
206 route.
flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
208 m_rib.
insert(topPrefix, route);
210 [=] (
const ControlResponse& res) {
211 NDN_THROW(
Error(
"Cannot add FIB entry " + topPrefix.toUri() +
" (" +
212 to_string(res.getCode()) +
" " + res.getText() +
")"));
216 m_dispatcher.addTopPrefix(topPrefix,
false);
220 RibManager::registerEntry(
const Name& topPrefix,
const Interest& interest,
221 ControlParameters parameters,
222 const ndn::mgmt::CommandContinuation& done)
225 done(ControlResponse(414,
"Route prefix cannot exceed " + to_string(
Fib::getMaxDepth()) +
230 setFaceForSelfRegistration(interest, parameters);
233 done(ControlResponse(200,
"Success").setBody(parameters.wireEncode()));
236 route.
faceId = parameters.getFaceId();
237 route.
origin = parameters.getOrigin();
238 route.
cost = parameters.getCost();
239 route.
flags = parameters.getFlags();
241 optional<time::nanoseconds> expires;
242 if (parameters.hasExpirationPeriod() &&
243 parameters.getExpirationPeriod() != time::milliseconds::max()) {
244 expires = time::duration_cast<time::nanoseconds>(parameters.getExpirationPeriod());
247 beginAddRoute(parameters.getName(), std::move(route), expires, [] (RibUpdateResult) {});
251 RibManager::unregisterEntry(
const Name& topPrefix,
const Interest& interest,
252 ControlParameters parameters,
253 const ndn::mgmt::CommandContinuation& done)
255 setFaceForSelfRegistration(interest, parameters);
258 done(ControlResponse(200,
"Success").setBody(parameters.wireEncode()));
261 route.
faceId = parameters.getFaceId();
262 route.
origin = parameters.getOrigin();
264 beginRemoveRoute(parameters.getName(), route, [] (RibUpdateResult) {});
268 RibManager::listEntries(
const Name& topPrefix,
const Interest& interest,
269 ndn::mgmt::StatusDatasetContext& context)
271 auto now = time::steady_clock::now();
272 for (
const auto& kv : m_rib) {
274 ndn::nfd::RibEntry item;
278 r.setFaceId(route.
faceId);
279 r.setOrigin(route.
origin);
280 r.setCost(route.
cost);
281 r.setFlags(route.
flags);
283 r.setExpirationPeriod(time::duration_cast<time::milliseconds>(*route.
expires - now));
287 context.append(item.wireEncode());
293 RibManager::setFaceForSelfRegistration(
const Interest& request, ControlParameters& parameters)
295 bool isSelfRegistration = (parameters.getFaceId() == 0);
296 if (isSelfRegistration) {
297 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
301 BOOST_ASSERT(incomingFaceIdTag !=
nullptr);
302 parameters.setFaceId(*incomingFaceIdTag);
306 ndn::mgmt::Authorization
307 RibManager::makeAuthorization(
const std::string& verb)
309 return [
this] (
const Name& prefix,
const Interest& interest,
310 const ndn::mgmt::ControlParameters* params,
311 const ndn::mgmt::AcceptContinuation& accept,
312 const ndn::mgmt::RejectContinuation& reject) {
313 BOOST_ASSERT(params !=
nullptr);
314 BOOST_ASSERT(
typeid(*params) ==
typeid(ndn::nfd::ControlParameters));
317 auto& validator = prefix == LOCALHOST_TOP_PREFIX ? m_localhostValidator : m_localhopValidator;
318 validator.validate(interest,
320 bind([reject] { reject(ndn::mgmt::RejectReply::STATUS403); }));
331 return os <<
"ERROR";
333 return os <<
"VALIDATION_FAILURE";
335 return os <<
"EXPIRED";
337 return os <<
"NOT_FOUND";
339 NDN_THROW(std::invalid_argument(
"Unknown SlAnnounceResult"));
343 RibManager::getSlAnnounceResultFromRibUpdateResult(RibUpdateResult r)
346 case RibUpdateResult::OK:
348 case RibUpdateResult::ERROR:
350 case RibUpdateResult::EXPIRED:
360 BOOST_ASSERT(pa.getData());
362 m_paValidator.validate(*pa.getData(),
364 Route route(pa, faceId);
365 route.
expires = std::min(route.
annExpires, time::steady_clock::now() + maxLifetime);
366 beginAddRoute(pa.getAnnouncedName(), route, nullopt,
367 [=] (RibUpdateResult ribRes) {
368 auto res = getSlAnnounceResultFromRibUpdateResult(ribRes);
369 NFD_LOG_INFO(
"slAnnounce " << pa.getAnnouncedName() <<
" " << faceId <<
": " << res);
373 [=] (
const Data&, ndn::security::ValidationError err) {
374 NFD_LOG_INFO(
"slAnnounce " << pa.getAnnouncedName() <<
" " << faceId <<
375 " validation error: " << err);
386 routeQuery.
faceId = faceId;
387 routeQuery.
origin = ndn::nfd::ROUTE_ORIGIN_PREFIXANN;
391 NFD_LOG_DEBUG(
"slRenew " << name <<
" " << faceId <<
": not found");
394 Name routeName = oldRoute->
announcement->getAnnouncedName();
396 Route route = *oldRoute;
397 route.
expires = std::min(route.
annExpires, time::steady_clock::now() + maxLifetime);
398 beginAddRoute(routeName, route, nullopt,
399 [=] (RibUpdateResult ribRes) {
400 auto res = getSlAnnounceResultFromRibUpdateResult(ribRes);
401 NFD_LOG_INFO(
"slRenew " << name <<
" " << faceId <<
": " << res <<
" " << routeName);
409 shared_ptr<rib::RibEntry> entry;
410 auto exactMatch = m_rib.
find(name);
411 if (exactMatch != m_rib.
end()) {
412 entry = exactMatch->second;
417 if (entry ==
nullptr) {
421 auto pa = entry->getPrefixAnnouncement();
422 pa.toData(m_keyChain);
427 RibManager::fetchActiveFaces()
431 m_nfdController.fetch<ndn::nfd::FaceDataset>(
432 bind(&RibManager::removeInvalidFaces,
this, _1),
433 bind(&RibManager::onFetchActiveFacesFailure,
this, _1, _2),
434 ndn::nfd::CommandOptions());
438 RibManager::onFetchActiveFacesFailure(uint32_t code,
const std::string& reason)
440 NFD_LOG_DEBUG(
"Face Status Dataset request failure " << code <<
" " << reason);
441 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
445 RibManager::scheduleActiveFaceFetch(
const time::seconds& timeToWait)
447 m_activeFaceFetchEvent =
getScheduler().schedule(timeToWait, [
this] { fetchActiveFaces(); });
451 RibManager::removeInvalidFaces(
const std::vector<ndn::nfd::FaceStatus>& activeFaces)
455 std::set<uint64_t> activeFaceIds;
456 for (
const auto& faceStatus : activeFaces) {
457 activeFaceIds.insert(faceStatus.getFaceId());
462 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
466 RibManager::onNotification(
const ndn::nfd::FaceEventNotification& notification)
470 if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
471 NFD_LOG_DEBUG(
"Received notification for destroyed FaceId " << notification.getFaceId());
const_iterator end() const
void registerStatusDatasetHandler(const std::string &verb, const ndn::mgmt::StatusDatasetHandler &handler)
Copyright (c) 2014-2017, Regents of the University of California, Arizona Board of Regents...
RibUpdate & setRoute(const Route &route)
represents the Routing Information Base
shared_ptr< RibEntry > findParent(const Name &prefix) const
void disableLocalhop()
Disallow accepting commands on /localhop/nfd/rib prefix.
std::function< void(SlAnnounceResult res)> SlAnnounceCallback
void slAnnounce(const ndn::PrefixAnnouncement &pa, uint64_t faceId, time::milliseconds maxLifetime, const SlAnnounceCallback &cb)
Insert a route by prefix announcement from self-learning strategy.
optional< ndn::PrefixAnnouncement > announcement
The prefix announcement that caused the creation of this route.
RibUpdate & setAction(Action action)
Route * findLongestPrefix(const Name &prefix, const Route &route) const
void enableLocalhop(const ConfigSection §ion, const std::string &filename)
Apply localhop_security configuration and allow accepting commands on /localhop/nfd/rib prefix...
const Name & getName() const
void setName(const Name &prefix)
RibManager(rib::Rib &rib, ndn::Face &face, ndn::KeyChain &keyChain, ndn::nfd::Controller &nfdController, Dispatcher &dispatcher)
std::function< void(optional< ndn::PrefixAnnouncement >)> SlFindAnnCallback
void slRenew(const Name &name, uint64_t faceId, time::milliseconds maxLifetime, const SlAnnounceCallback &cb)
Renew a route created by prefix announcement from self-learning strategy.
the announcement cannot be verified against the trust schema
void applyLocalhostConfig(const ConfigSection §ion, const std::string &filename)
Apply localhost_security configuration.
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
RibUpdate & setName(const Name &name)
void setExpirationEvent(const scheduler::EventId &eid)
A collection of common functions shared by all NFD managers, such as communicating with the dispatche...
const RouteList & getRoutes() const
void registerWithNfd()
Start accepting commands and dataset requests.
boost::property_tree::ptree ConfigSection
a config file section
std::ostream & operator<<(std::ostream &os, const Network &network)
optional< time::steady_clock::TimePoint > expires
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
void slFindAnn(const Name &name, const SlFindAnnCallback &cb) const
Retrieve an outgoing prefix announcement for self-learning strategy.
void applyPaConfig(const ConfigSection §ion, const std::string &filename)
Apply prefix_announcement_validation configuration.
static const std::string MGMT_MODULE_NAME
time::steady_clock::TimePoint annExpires
Expiration time of the prefix announcement.
ndn::nfd::RouteOrigin origin
void insert(const Name &prefix, const Route &route)
represents a route for a name prefix
static const time::seconds ACTIVE_FACE_FETCH_INTERVAL
static constexpr size_t getMaxDepth()
Maximum number of components in a FIB entry prefix.
void extractRequester(const Interest &interest, ndn::mgmt::AcceptContinuation accept)
Extracts the requester from a ControlCommand request.
static const Name LOCALHOP_TOP_PREFIX
#define NFD_LOG_INIT(name)
Represents a RIB entry, which contains one or more Routes with the same prefix.
void beginRemoveFace(uint64_t faceId)
starts the FIB update process when a face has been destroyed
void enableLocalFields()
Enable NDNLP IncomingFaceId field in order to support self-registration commands. ...
RIB and FIB have been updated.
the announcement has expired
void onRouteExpiration(const Name &prefix, const Route &route)
const_iterator find(const Name &prefix) const
void beginRemoveFailedFaces(const std::set< uint64_t > &activeFaceIds)
std::underlying_type_t< ndn::nfd::RouteFlags > flags
void beginApplyUpdate(const RibUpdate &update, const UpdateSuccessCallback &onSuccess, const UpdateFailureCallback &onFailure)
passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
static const Name LOCALHOST_TOP_PREFIX
route does not exist (slRenew only)
boost::asio::io_service & getGlobalIoService()
Returns the global io_service instance for the calling thread.