30 #include <ndn-cxx/management/nfd-face-status.hpp> 37 const Name RibManager::COMMAND_PREFIX =
"/localhost/nfd/rib";
38 const Name RibManager::REMOTE_COMMAND_PREFIX =
"/localhop/nfd/rib";
39 const Name RibManager::FACES_LIST_DATASET_PREFIX =
"/localhost/nfd/faces/list";
41 const size_t RibManager::COMMAND_UNSIGNED_NCOMPS =
42 RibManager::COMMAND_PREFIX.
size() +
46 const size_t RibManager::COMMAND_SIGNED_NCOMPS =
47 RibManager::COMMAND_UNSIGNED_NCOMPS +
50 const RibManager::SignedVerbAndProcessor RibManager::SIGNED_COMMAND_VERBS[] =
52 SignedVerbAndProcessor(
54 &RibManager::registerEntry
57 SignedVerbAndProcessor(
59 &RibManager::unregisterEntry
63 const RibManager::UnsignedVerbAndProcessor RibManager::UNSIGNED_COMMAND_VERBS[] =
65 UnsignedVerbAndProcessor(
67 &RibManager::listEntries
71 const Name RibManager::LIST_COMMAND_PREFIX(
"/localhost/nfd/rib/list");
72 const size_t RibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
74 const time::seconds RibManager::ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
78 , m_keyChain(keyChain)
79 , m_nfdController(m_face, m_keyChain)
80 , m_localhostValidator(m_face)
81 , m_localhopValidator(m_face)
82 , m_faceMonitor(m_face)
83 , m_isLocalhopEnabled(false)
84 , m_prefixPropagator(m_nfdController, m_keyChain, m_managedRib)
85 , m_ribStatusPublisher(m_managedRib, face, LIST_COMMAND_PREFIX, m_keyChain)
86 , m_fibUpdater(m_managedRib, m_nfdController)
87 , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
88 SIGNED_COMMAND_VERBS +
89 (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
90 , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
91 UNSIGNED_COMMAND_VERBS +
92 (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
108 .setName(commandPrefix)
110 bind(&RibManager::onNrdCommandPrefixAddNextHopSuccess,
this, cref(commandPrefix), _1),
111 bind(&RibManager::onNrdCommandPrefixAddNextHopError,
this, cref(commandPrefix), _2));
120 BOOST_ASSERT(COMMAND_PREFIX.
size() == REMOTE_COMMAND_PREFIX.
size());
122 this->startListening(COMMAND_PREFIX, bind(&RibManager::onLocalhostRequest,
this, _2));
124 if (m_isLocalhopEnabled) {
125 this->startListening(REMOTE_COMMAND_PREFIX,
126 bind(&RibManager::onLocalhopRequest,
this, _2));
129 NFD_LOG_INFO(
"Start monitoring face create/destroy events");
130 m_faceMonitor.
onNotification.connect(bind(&RibManager::onNotification,
this, _1));
131 m_faceMonitor.
start();
133 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
140 bind(&RibManager::onConfig,
this, _1, _2, _3));
146 const std::string& filename)
148 bool isAutoPrefixPropagatorEnabled =
false;
150 for (
const auto& item : configSection) {
151 if (item.first ==
"localhost_security") {
152 m_localhostValidator.
load(item.second, filename);
154 else if (item.first ==
"localhop_security") {
155 m_localhopValidator.
load(item.second, filename);
156 m_isLocalhopEnabled =
true;
158 else if (item.first ==
"auto_prefix_propagate") {
160 isAutoPrefixPropagatorEnabled =
true;
167 m_prefixPropagator.
enable();
170 BOOST_THROW_EXCEPTION(
Error(
"Unrecognized rib property: " + item.first));
174 if (!isAutoPrefixPropagatorEnabled) {
180 RibManager::sendResponse(
const Name&
name,
185 shared_ptr<Data> responseData = make_shared<Data>(name);
186 responseData->setContent(encodedControl);
188 m_keyChain.
sign(*responseData);
189 m_face.
put(*responseData);
193 RibManager::sendResponse(
const Name& name,
195 const std::string& text)
198 sendResponse(name, response);
202 RibManager::onLocalhostRequest(
const Interest& request)
207 UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
209 if (unsignedVerbProcessor != m_unsignedVerbDispatch.end()) {
210 NFD_LOG_DEBUG(
"command result: processing unsigned verb: " << verb);
211 (unsignedVerbProcessor->second)(
this, request);
214 m_localhostValidator.
validate(request,
215 bind(&RibManager::onCommandValidated,
this, _1),
216 bind(&RibManager::onCommandValidationFailed,
this, _1, _2));
221 RibManager::onLocalhopRequest(
const Interest& request)
223 m_localhopValidator.
validate(request,
224 bind(&RibManager::onCommandValidated,
this, _1),
225 bind(&RibManager::onCommandValidationFailed,
this, _1, _2));
229 RibManager::onCommandValidated(
const shared_ptr<const Interest>& request)
234 const Name& command = request->getName();
238 SignedVerbDispatchTable::const_iterator verbProcessor = m_signedVerbDispatch.find(verb);
240 if (verbProcessor != m_signedVerbDispatch.end()) {
243 if (!extractParameters(parameterComponent, parameters)) {
246 if (static_cast<bool>(request)) {
247 sendResponse(command, 400,
"Malformed command");
254 (verbProcessor->second)(
this, request, parameters);
259 if (static_cast<bool>(request)) {
260 sendResponse(request->getName(), 501,
"Unsupported command");
266 RibManager::registerEntry(
const shared_ptr<const Interest>& request,
271 if (!validateParameters(command, parameters)) {
274 if (static_cast<bool>(request)) {
275 sendResponse(request->getName(), 400,
"Malformed command");
282 if (isSelfRegistration) {
284 if (incomingFaceIdTag ==
nullptr) {
285 sendResponse(request->getName(), 503,
286 "requested self-registration, but IncomingFaceId is unavailable");
289 parameters.
setFaceId(*incomingFaceIdTag);
293 sendSuccessResponse(request, parameters);
311 " with EventId: " << eventId);
317 route.
expires = time::steady_clock::TimePoint::max();
321 <<
" origin=" << route.
origin 322 <<
" cost=" << route.
cost);
333 m_registeredFaces.insert(route.
faceId);
337 RibManager::unregisterEntry(
const shared_ptr<const Interest>& request,
355 if (!validateParameters(command, parameters)) {
358 if (static_cast<bool>(request)) {
359 sendResponse(request->getName(), 400,
"Malformed command");
366 if (isSelfRegistration) {
368 if (incomingFaceIdTag ==
nullptr) {
369 sendResponse(request->getName(), 503,
370 "requested self-registration, but IncomingFaceId is unavailable");
373 parameters.
setFaceId(*incomingFaceIdTag);
377 sendSuccessResponse(request, parameters);
384 <<
" origin=" << route.
origin);
397 RibManager::onCommandValidationFailed(
const shared_ptr<const Interest>& request,
398 const std::string& failureInfo)
400 NFD_LOG_DEBUG(
"RibRequestValidationFailed: " << failureInfo);
402 if (static_cast<bool>(request)) {
403 sendResponse(request->getName(), 403, failureInfo);
409 RibManager::extractParameters(
const Name::Component& parameterComponent,
414 extractedParameters.
wireDecode(rawParameters);
441 RibManager::onCommandError(uint32_t code,
const std::string& error,
442 const shared_ptr<const Interest>& request,
445 NFD_LOG_ERROR(
"NFD returned an error: " << error <<
" (code: " << code <<
")");
455 std::ostringstream os;
456 os <<
"Failure to update NFD " <<
"(NFD Error: " << code <<
" " << error <<
")";
460 if (static_cast<bool>(request)) {
461 sendResponse(request->getName(), response);
466 RibManager::onRegSuccess(
const shared_ptr<const Interest>& request,
478 if (static_cast<bool>(request)) {
479 sendResponse(request->getName(), response);
485 RibManager::onUnRegSuccess(
const shared_ptr<const Interest>& request,
497 if (static_cast<bool>(request)) {
498 sendResponse(request->getName(), response);
503 RibManager::sendSuccessResponse(
const shared_ptr<const Interest>& request,
506 if (!static_cast<bool>(request)) {
516 if (static_cast<bool>(request)) {
517 sendResponse(request->getName(), response);
522 RibManager::sendErrorResponse(uint32_t code,
const std::string& error,
523 const shared_ptr<const Interest>& request)
525 NFD_LOG_ERROR(
"NFD returned an error: " << error <<
" (code: " << code <<
")");
527 if (!static_cast<bool>(request)) {
539 std::ostringstream os;
540 os <<
"Failure to update NFD " <<
"(NFD Error: " << code <<
" " << error <<
")";
544 if (static_cast<bool>(request)) {
545 sendResponse(request->getName(), response);
558 NFD_LOG_DEBUG(
"RIB update failed for " << update <<
" (code: " << code
559 <<
", error: " << error <<
")");
562 scheduleActiveFaceFetch(time::seconds(1));
566 RibManager::onNrdCommandPrefixAddNextHopSuccess(
const Name& prefix,
575 route.expires = time::steady_clock::TimePoint::max();
578 m_managedRib.
insert(prefix, route);
580 m_registeredFaces.insert(route.faceId);
584 RibManager::onNrdCommandPrefixAddNextHopError(
const Name& name,
const std::string& msg)
586 BOOST_THROW_EXCEPTION(
Error(
"Error in setting interest filter (" + name.
toUri() +
"): " + msg));
590 RibManager::onControlHeaderSuccess()
596 RibManager::onControlHeaderError(uint32_t code,
const std::string& reason)
598 std::ostringstream os;
599 os <<
"Couldn't enable local control header " 600 <<
"(code: " << code <<
", info: " << reason <<
")";
601 BOOST_THROW_EXCEPTION(
Error(os.str()));
610 bind(&RibManager::onControlHeaderSuccess,
this),
611 bind(&RibManager::onControlHeaderError,
this, _1, _2));
623 bind(&RibManager::onFaceDestroyedEvent,
this, notification.
getFaceId()));
628 RibManager::onFaceDestroyedEvent(uint64_t faceId)
631 m_registeredFaces.erase(faceId);
635 RibManager::listEntries(
const Interest& request)
638 const size_t commandNComps = command.
size();
640 if (commandNComps < LIST_COMMAND_NCOMPS || !LIST_COMMAND_PREFIX.
isPrefixOf(command)) {
643 sendResponse(command, 400,
"Malformed command");
647 m_ribStatusPublisher.
publish();
651 RibManager::scheduleActiveFaceFetch(
const time::seconds& timeToWait)
656 bind(&RibManager::fetchActiveFaces,
this));
660 RibManager::fetchActiveFaces()
664 Interest interest(FACES_LIST_DATASET_PREFIX);
668 shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>();
671 bind(&RibManager::fetchSegments,
this, _2, buffer),
672 bind(&RibManager::onFetchFaceStatusTimeout,
this));
676 RibManager::fetchSegments(
const Data& data, shared_ptr<ndn::OBufferStream> buffer)
678 buffer->write(reinterpret_cast<const char*>(data.
getContent().
value()),
685 if (finalBlockId.
empty() || finalBlockId.
toSegment() > currentSegment) {
687 bind(&RibManager::fetchSegments,
this, _2, buffer),
688 bind(&RibManager::onFetchFaceStatusTimeout,
this));
691 removeInvalidFaces(buffer);
696 RibManager::removeInvalidFaces(shared_ptr<ndn::OBufferStream> buffer)
704 FaceIdSet activeFaces;
706 while (offset < buf->size()) {
710 std::cerr <<
"ERROR: cannot decode FaceStatus TLV" << std::endl;
714 offset += block.
size();
722 for (uint64_t faceId : m_registeredFaces) {
723 if (activeFaces.find(faceId) == activeFaces.end()) {
727 bind(&RibManager::onFaceDestroyedEvent,
this, faceId));
732 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
736 RibManager::onFetchFaceStatusTimeout()
738 std::cerr <<
"Face Status Dataset request timed out" << std::endl;
739 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
void start(const ControlParameters ¶meters, const CommandSucceedCallback &onSuccess, const CommandFailCallback &onFailure, const CommandOptions &options=CommandOptions())
start command execution
uint64_t getFlags() const
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
ControlParameters & setFaceId(uint64_t faceId)
virtual void wireDecode(const Block &wire) final
std::string toUri() const
Encode this name as a URI.
void load(const std::string &filename)
#define NFD_LOG_DEBUG(expression)
static std::tuple< bool, Block > fromBuffer(ConstBufferPtr buffer, size_t offset)
Try to construct block from Buffer.
represents a fib/add-nexthop command
void setExpirationEvent(const scheduler::EventId eid)
void beginApplyUpdate(const RibUpdate &update, const UpdateSuccessCallback &onSuccess, const UpdateFailureCallback &onFailure)
passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
RibManager(ndn::Face &face, ndn::KeyChain &keyChain)
Interest & setMustBeFresh(bool mustBeFresh)
represents parameters in a ControlCommand request or response
time::steady_clock::TimePoint expires
const Block & getContent() const
Get content Block.
void cancel(const EventId &eventId)
cancel a scheduled event
const Component & get(ssize_t i) const
Get the component at the given index.
static time_point now() noexcept
size_t value_size() const
const Name & getName() const
Get name of the Data packet.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
The packet signing interface.
base class of NFD ControlCommand
represents a Face status change notification
Class representing a wire element of NDN-TLV packet format.
represents an Interest packet
virtual void validateRequest(const ControlParameters ¶meters) const
validate request parameters
const Block & wireEncode() const
#define NFD_LOG_ERROR(expression)
void start()
start or resume receiving notifications
function< void(const InterestFilter &, const Interest &)> OnInterest
Callback called when incoming Interest matches the specified InterestFilter.
void sign(Data &data, const SigningInfo ¶ms=DEFAULT_SIGNING_INFO)
Sign data according to the supplied signing information.
void disable()
disable automatic prefix propagation
const uint8_t * value() const
void onRibUpdateSuccess(const RibUpdate &update)
virtual void applyDefaultsToRequest(ControlParameters ¶meters) const
apply default values to missing fields in request
signal::Signal< NotificationSubscriber, Notification > onNotification
fires when a Notification is received
uint64_t getOrigin() const
provides a tag type for simple types
std::shared_ptr< ns3::EventId > EventId
represents a faces/enable-local-control command
const Name & getName() const
void insert(const Name &prefix, const Route &route)
void enableLocalControlHeader()
#define NFD_LOG_INFO(expression)
void validate(const Data &data, const OnDataValidated &onValidated, const OnDataValidationFailed &onValidationFailed)
Validate Data and call either onValidated or onValidationFailed.
Copyright (c) 2011-2015 Regents of the University of California.
void addSectionHandler(const std::string §ionName, ConfigSectionHandler subscriber)
setup notification of configuration file sections
const RegisteredPrefixId * setInterestFilter(const InterestFilter &interestFilter, const OnInterest &onInterest, const RegisterPrefixFailureCallback &onFailure, const security::SigningInfo &signingInfo=security::SigningInfo(), uint64_t flags=nfd::ROUTE_FLAG_CHILD_INHERIT)
Set InterestFilter to dispatch incoming matching interest to onInterest callback and register the fil...
Interest & setChildSelector(int childSelector)
Name & appendSegment(uint64_t segmentNo)
Append segment number (sequential) using NDN naming conventions.
RibUpdate & setAction(Action action)
void loadConfig(const ConfigSection &configSection)
load the "auto_prefix_propagate" section from config file
represents a route for a name prefix
Abstraction to communicate with local or remote NDN forwarder.
bool hasExpirationPeriod() const
FaceEventKind getKind() const
const MetaInfo & getMetaInfo() const
Get MetaInfo block from Data packet.
boost::property_tree::ptree ConfigSection
Name abstraction to represent an absolute name.
bool isPrefixOf(const Name &name) const
Check if the N components of this name are the same as the first N components of the given name...
represents a rib/unregister command
void beginRemoveFace(uint64_t faceId)
starts the FIB update process when a face has been destroyed
uint64_t getFaceId() const
represents a rib/register command
size_t size() const
Get the number of components.
ControlResponse & setText(const std::string &text)
void enable()
enable automatic prefix propagation
Component holds a read-only name component value.
ControlResponse & setBody(const Block &body)
Block blockFromValue() const
#define NFD_LOG_INIT(name)
uint64_t toSegment() const
Interpret as segment number component using NDN naming conventions.
EventId schedule(const time::nanoseconds &after, const Scheduler::Event &event)
schedule an event
const time::milliseconds & getExpirationPeriod() const
RibUpdate & setName(const Name &name)
ControlParameters & setOrigin(uint64_t origin)
#define NFD_LOG_TRACE(expression)
ControlParameters & setName(const Name &name)
void onRouteExpiration(const Name &prefix, const Route &route)
const PendingInterestId * expressInterest(const Interest &interest, const DataCallback &afterSatisfied, const NackCallback &afterNacked, const TimeoutCallback &afterTimeout)
Express Interest.
represents an error in ControlParameters
shared_ptr< const Buffer > ConstBufferPtr
uint64_t getFaceId() const
void onRibUpdateFailure(const RibUpdate &update, uint32_t code, const std::string &error)
ControlResponse & setCode(uint32_t code)
represents an error in TLV encoding or decoding
void put(const Data &data)
Publish data packet.
void setConfigFile(ConfigFile &configFile)
const Name & getName() const