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_remoteRegistrator(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 isRemoteRegisterEnabled =
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 ==
"remote_register") {
160 isRemoteRegisterEnabled =
true;
167 m_remoteRegistrator.
enable();
170 BOOST_THROW_EXCEPTION(
Error(
"Unrecognized rib property: " + item.first));
174 if (!isRemoteRegisterEnabled) {
180 RibManager::sendResponse(
const Name&
name,
183 const Block& encodedControl = response.wireEncode();
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) {
283 parameters.
setFaceId(request->getIncomingFaceId());
287 sendSuccessResponse(request, parameters);
305 " with EventId: " << eventId);
311 route.
expires = time::steady_clock::TimePoint::max();
315 <<
" origin=" << route.
origin 316 <<
" cost=" << route.
cost);
327 m_registeredFaces.insert(route.
faceId);
331 RibManager::unregisterEntry(
const shared_ptr<const Interest>& request,
349 if (!validateParameters(command, parameters)) {
352 if (static_cast<bool>(request)) {
353 sendResponse(request->getName(), 400,
"Malformed command");
360 if (isSelfRegistration) {
361 parameters.
setFaceId(request->getIncomingFaceId());
365 sendSuccessResponse(request, parameters);
372 <<
" origin=" << route.
origin);
385 RibManager::onCommandValidationFailed(
const shared_ptr<const Interest>& request,
386 const std::string& failureInfo)
388 NFD_LOG_DEBUG(
"RibRequestValidationFailed: " << failureInfo);
390 if (static_cast<bool>(request)) {
391 sendResponse(request->getName(), 403, failureInfo);
397 RibManager::extractParameters(
const Name::Component& parameterComponent,
402 extractedParameters.
wireDecode(rawParameters);
429 RibManager::onCommandError(uint32_t code,
const std::string& error,
430 const shared_ptr<const Interest>& request,
433 NFD_LOG_ERROR(
"NFD returned an error: " << error <<
" (code: " << code <<
")");
443 std::ostringstream os;
444 os <<
"Failure to update NFD " <<
"(NFD Error: " << code <<
" " << error <<
")";
448 if (static_cast<bool>(request)) {
449 sendResponse(request->getName(), response);
454 RibManager::onRegSuccess(
const shared_ptr<const Interest>& request,
466 if (static_cast<bool>(request)) {
467 sendResponse(request->getName(), response);
473 RibManager::onUnRegSuccess(
const shared_ptr<const Interest>& request,
485 if (static_cast<bool>(request)) {
486 sendResponse(request->getName(), response);
491 RibManager::sendSuccessResponse(
const shared_ptr<const Interest>& request,
494 if (!static_cast<bool>(request)) {
504 if (static_cast<bool>(request)) {
505 sendResponse(request->getName(), response);
510 RibManager::sendErrorResponse(uint32_t code,
const std::string& error,
511 const shared_ptr<const Interest>& request)
513 NFD_LOG_ERROR(
"NFD returned an error: " << error <<
" (code: " << code <<
")");
515 if (!static_cast<bool>(request)) {
527 std::ostringstream os;
528 os <<
"Failure to update NFD " <<
"(NFD Error: " << code <<
" " << error <<
")";
532 if (static_cast<bool>(request)) {
533 sendResponse(request->getName(), response);
546 NFD_LOG_DEBUG(
"RIB update failed for " << update <<
" (code: " << code
547 <<
", error: " << error <<
")");
550 scheduleActiveFaceFetch(time::seconds(1));
554 RibManager::onNrdCommandPrefixAddNextHopSuccess(
const Name& prefix,
563 route.expires = time::steady_clock::TimePoint::max();
566 m_managedRib.
insert(prefix, route);
568 m_registeredFaces.insert(route.faceId);
572 RibManager::onNrdCommandPrefixAddNextHopError(
const Name& name,
const std::string& msg)
574 BOOST_THROW_EXCEPTION(
Error(
"Error in setting interest filter (" + name.
toUri() +
"): " + msg));
578 RibManager::onControlHeaderSuccess()
584 RibManager::onControlHeaderError(uint32_t code,
const std::string& reason)
586 std::ostringstream os;
587 os <<
"Couldn't enable local control header " 588 <<
"(code: " << code <<
", info: " << reason <<
")";
589 BOOST_THROW_EXCEPTION(
Error(os.str()));
598 bind(&RibManager::onControlHeaderSuccess,
this),
599 bind(&RibManager::onControlHeaderError,
this, _1, _2));
611 bind(&RibManager::onFaceDestroyedEvent,
this, notification.
getFaceId()));
616 RibManager::onFaceDestroyedEvent(uint64_t faceId)
619 m_registeredFaces.erase(faceId);
623 RibManager::listEntries(
const Interest& request)
626 const size_t commandNComps = command.
size();
628 if (commandNComps < LIST_COMMAND_NCOMPS || !LIST_COMMAND_PREFIX.
isPrefixOf(command)) {
631 sendResponse(command, 400,
"Malformed command");
635 m_ribStatusPublisher.
publish();
639 RibManager::scheduleActiveFaceFetch(
const time::seconds& timeToWait)
644 bind(&RibManager::fetchActiveFaces,
this));
648 RibManager::fetchActiveFaces()
652 Interest interest(FACES_LIST_DATASET_PREFIX);
656 shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>();
659 bind(&RibManager::fetchSegments,
this, _2, buffer),
660 bind(&RibManager::onFetchFaceStatusTimeout,
this));
664 RibManager::fetchSegments(
const Data& data, shared_ptr<ndn::OBufferStream> buffer)
666 buffer->write(reinterpret_cast<const char*>(data.
getContent().
value()),
673 if (finalBlockId.
empty() || finalBlockId.
toSegment() > currentSegment) {
675 bind(&RibManager::fetchSegments,
this, _2, buffer),
676 bind(&RibManager::onFetchFaceStatusTimeout,
this));
679 removeInvalidFaces(buffer);
684 RibManager::removeInvalidFaces(shared_ptr<ndn::OBufferStream> buffer)
692 FaceIdSet activeFaces;
694 while (offset < buf->size()) {
698 std::cerr <<
"ERROR: cannot decode FaceStatus TLV" << std::endl;
702 offset += block.
size();
710 for (uint64_t faceId : m_registeredFaces) {
711 if (activeFaces.find(faceId) == activeFaces.end()) {
715 bind(&RibManager::onFaceDestroyedEvent,
this, faceId));
720 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
724 RibManager::onFetchFaceStatusTimeout()
726 std::cerr <<
"Face Status Dataset request timed out" << std::endl;
727 scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
uint64_t getFlags() const
void start(const ControlParameters ¶meters, const CommandSucceedCallback &onSuccess, const CommandFailCallback &onFailure, const CommandOptions &options=CommandOptions())
start command execution
ControlParameters & setFaceId(uint64_t faceId)
virtual void wireDecode(const Block &wire) final
const Name & getName() const
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
void cancel(const EventId &eventId)
cancel a scheduled event
static time_point now() noexcept
void disable()
disable remote registration/unregistration.
base class of NFD ControlCommand
void loadConfig(const ConfigSection &configSection)
load the "remote_register" section from config file
uint64_t getOrigin() const
virtual void validateRequest(const ControlParameters ¶meters) const
validate request parameters
represents a Face status change notification
bool hasExpirationPeriod() const
Class representing a wire element of NDN-TLV packet format.
represents an Interest packet
#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.
std::shared_ptr< ns3::EventId > EventId
void onRibUpdateSuccess(const RibUpdate &update)
const MetaInfo & getMetaInfo() const
Get MetaInfo block from Data packet.
signal::Signal< NotificationSubscriber, Notification > onNotification
fires when a Notification is received
const Name & getName() const
Get name of the Data packet.
represents a faces/enable-local-control command
std::string toUri() const
Encode this name as a URI.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
ndn::mgmt::ControlResponse ControlResponse
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.
Block blockFromValue() const
uint64_t toSegment() const
Interpret as segment number component using NDN naming conventions.
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)
represents a route for a name prefix
const Name & getName() const
Abstraction to communicate with local or remote NDN forwarder.
uint64_t getFaceId() const
size_t size() const
Get the number of components.
boost::property_tree::ptree ConfigSection
EventId schedule(const time::nanoseconds &after, const std::function< void()> &event)
schedule an event
Name abstraction to represent an absolute name.
const PendingInterestId * expressInterest(const Interest &interest, const OnData &onData, const OnTimeout &onTimeout=OnTimeout())
Express Interest.
size_t value_size() const
represents a rib/unregister command
void beginRemoveFace(uint64_t faceId)
starts the FIB update process when a face has been destroyed
represents a rib/register command
uint64_t getFaceId() const
ControlResponse & setText(const std::string &text)
Component holds a read-only name component value.
ControlResponse & setBody(const Block &body)
const time::milliseconds & getExpirationPeriod() const
void enable()
enable remote registration/unregistration.
FaceEventKind getKind() const
#define NFD_LOG_INIT(name)
const Block & getContent() const
Get content Block.
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)
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...
const uint8_t * value() const
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
virtual void applyDefaultsToRequest(ControlParameters ¶meters) const
apply default values to missing fields in request
represents an error in ControlParameters
shared_ptr< const Buffer > ConstBufferPtr
void onRibUpdateFailure(const RibUpdate &update, uint32_t code, const std::string &error)
const Component & get(ssize_t i) const
Get the component at the given index.
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)