rib: refactor RibManager to use ManagementDispatcher
Change-Id: I3f689de7d043e85531f0b3f4accf65345cde5d9e
refs: #2857
diff --git a/rib/nrd.cpp b/rib/nrd.cpp
index bcee83c..d723a3f 100644
--- a/rib/nrd.cpp
+++ b/rib/nrd.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -63,10 +63,11 @@
Nrd::initialize()
{
m_face.reset(new ndn::Face(getLocalNfdTransport(), getGlobalIoService(), m_keyChain));
+ m_dispatcher.reset(new ndn::mgmt::Dispatcher(*m_face, m_keyChain));
initializeLogging();
- m_ribManager.reset(new RibManager(*m_face, m_keyChain));
+ m_ribManager.reset(new RibManager(*m_dispatcher, *m_face, m_keyChain));
ConfigFile config([] (const std::string& filename, const std::string& sectionName,
const ConfigSection& section, bool isDryRun) {
diff --git a/rib/nrd.hpp b/rib/nrd.hpp
index e861422..0d8743d 100644
--- a/rib/nrd.hpp
+++ b/rib/nrd.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,6 +32,7 @@
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/transport/transport.hpp>
+#include <ndn-cxx/mgmt/dispatcher.hpp>
namespace nfd {
namespace rib {
@@ -98,6 +99,7 @@
ndn::KeyChain& m_keyChain;
unique_ptr<ndn::Face> m_face;
+ unique_ptr<ndn::mgmt::Dispatcher> m_dispatcher;
unique_ptr<RibManager> m_ribManager;
};
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index 03faf21..edd6c5d 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,69 +28,41 @@
#include "core/logger.hpp"
#include "core/scheduler.hpp"
#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/management/nfd-rib-entry.hpp>
namespace nfd {
namespace rib {
NFD_LOG_INIT("RibManager");
-const Name RibManager::COMMAND_PREFIX = "/localhost/nfd/rib";
-const Name RibManager::REMOTE_COMMAND_PREFIX = "/localhop/nfd/rib";
+const Name RibManager::LOCAL_HOST_TOP_PREFIX = "/localhost/nfd";
+const Name RibManager::LOCAL_HOP_TOP_PREFIX = "/localhop/nfd";
const Name RibManager::FACES_LIST_DATASET_PREFIX = "/localhost/nfd/faces/list";
-
-const size_t RibManager::COMMAND_UNSIGNED_NCOMPS =
- RibManager::COMMAND_PREFIX.size() +
- 1 + // verb
- 1; // verb options
-
-const size_t RibManager::COMMAND_SIGNED_NCOMPS =
- RibManager::COMMAND_UNSIGNED_NCOMPS +
- 4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const RibManager::SignedVerbAndProcessor RibManager::SIGNED_COMMAND_VERBS[] =
- {
- SignedVerbAndProcessor(
- Name::Component("register"),
- &RibManager::registerEntry
- ),
-
- SignedVerbAndProcessor(
- Name::Component("unregister"),
- &RibManager::unregisterEntry
- ),
- };
-
-const RibManager::UnsignedVerbAndProcessor RibManager::UNSIGNED_COMMAND_VERBS[] =
- {
- UnsignedVerbAndProcessor(
- Name::Component("list"),
- &RibManager::listEntries
- ),
- };
-
-const Name RibManager::LIST_COMMAND_PREFIX("/localhost/nfd/rib/list");
-const size_t RibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
-
const time::seconds RibManager::ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
-RibManager::RibManager(ndn::Face& face, ndn::KeyChain& keyChain)
- : m_face(face)
+RibManager::RibManager(Dispatcher& dispatcher,
+ ndn::Face& face,
+ ndn::KeyChain& keyChain)
+ : ManagerBase(dispatcher, "rib")
+ , m_face(face)
, m_keyChain(keyChain)
, m_nfdController(m_face, m_keyChain)
+ , m_faceMonitor(m_face)
, m_localhostValidator(m_face)
, m_localhopValidator(m_face)
- , m_faceMonitor(m_face)
, m_isLocalhopEnabled(false)
- , m_prefixPropagator(m_nfdController, m_keyChain, m_managedRib)
- , m_ribStatusPublisher(m_managedRib, face, LIST_COMMAND_PREFIX, m_keyChain)
- , m_fibUpdater(m_managedRib, m_nfdController)
- , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
- SIGNED_COMMAND_VERBS +
- (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
- , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
- UNSIGNED_COMMAND_VERBS +
- (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
+ , m_prefixPropagator(m_nfdController, m_keyChain, m_rib)
+ , m_fibUpdater(m_rib, m_nfdController)
+ , m_addTopPrefix([&dispatcher] (const Name& topPrefix) {
+ dispatcher.addTopPrefix(topPrefix, false);
+ })
{
+ registerCommandHandler<ndn::nfd::RibRegisterCommand>("register",
+ bind(&RibManager::registerEntry, this, _2, _3, _4, _5));
+ registerCommandHandler<ndn::nfd::RibUnregisterCommand>("unregister",
+ bind(&RibManager::unregisterEntry, this, _2, _3, _4, _5));
+
+ registerStatusDatasetHandler("list", bind(&RibManager::listEntries, this, _1, _2, _3));
}
RibManager::~RibManager()
@@ -99,31 +71,12 @@
}
void
-RibManager::startListening(const Name& commandPrefix, const ndn::OnInterest& onRequest)
-{
- NFD_LOG_INFO("Listening on: " << commandPrefix);
-
- m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
- ControlParameters()
- .setName(commandPrefix)
- .setFaceId(0),
- bind(&RibManager::onNrdCommandPrefixAddNextHopSuccess, this, cref(commandPrefix), _1),
- bind(&RibManager::onNrdCommandPrefixAddNextHopError, this, cref(commandPrefix), _2));
-
- m_face.setInterestFilter(commandPrefix, onRequest);
-}
-
-void
RibManager::registerWithNfd()
{
- //check whether the components of localhop and localhost prefixes are same
- BOOST_ASSERT(COMMAND_PREFIX.size() == REMOTE_COMMAND_PREFIX.size());
-
- this->startListening(COMMAND_PREFIX, bind(&RibManager::onLocalhostRequest, this, _2));
+ registerTopPrefix(LOCAL_HOST_TOP_PREFIX);
if (m_isLocalhopEnabled) {
- this->startListening(REMOTE_COMMAND_PREFIX,
- bind(&RibManager::onLocalhopRequest, this, _2));
+ registerTopPrefix(LOCAL_HOP_TOP_PREFIX);
}
NFD_LOG_INFO("Start monitoring face create/destroy events");
@@ -134,6 +87,16 @@
}
void
+RibManager::enableLocalControlHeader()
+{
+ m_nfdController.start<ndn::nfd::FaceEnableLocalControlCommand>(
+ ControlParameters()
+ .setLocalControlFeature(ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
+ bind(&RibManager::onControlHeaderSuccess, this),
+ bind(&RibManager::onControlHeaderError, this, _1, _2));
+}
+
+void
RibManager::setConfigFile(ConfigFile& configFile)
{
configFile.addSectionHandler("rib",
@@ -141,6 +104,22 @@
}
void
+RibManager::onRibUpdateSuccess(const RibUpdate& update)
+{
+ NFD_LOG_DEBUG("RIB update succeeded for " << update);
+}
+
+void
+RibManager::onRibUpdateFailure(const RibUpdate& update, uint32_t code, const std::string& error)
+{
+ NFD_LOG_DEBUG("RIB update failed for " << update << " (code: " << code
+ << ", error: " << error << ")");
+
+ // Since the FIB rejected the update, clean up invalid routes
+ scheduleActiveFaceFetch(time::seconds(1));
+}
+
+void
RibManager::onConfig(const ConfigSection& configSection,
bool isDryRun,
const std::string& filename)
@@ -177,120 +156,29 @@
}
void
-RibManager::sendResponse(const Name& name,
- const ControlResponse& response)
+RibManager::registerTopPrefix(const Name& topPrefix)
{
- const Block& encodedControl = response.wireEncode();
+ // register entry to the FIB
+ m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
+ ControlParameters()
+ .setName(topPrefix)
+ .setFaceId(0),
+ bind(&RibManager::onNrdCommandPrefixAddNextHopSuccess, this, cref(topPrefix), _1),
+ bind(&RibManager::onNrdCommandPrefixAddNextHopError, this, cref(topPrefix), _2));
- shared_ptr<Data> responseData = make_shared<Data>(name);
- responseData->setContent(encodedControl);
-
- m_keyChain.sign(*responseData);
- m_face.put(*responseData);
+ // add top prefix to the dispatcher
+ m_addTopPrefix(topPrefix);
}
void
-RibManager::sendResponse(const Name& name,
- uint32_t code,
- const std::string& text)
+RibManager::registerEntry(const Name& topPrefix, const Interest& interest,
+ ControlParameters parameters,
+ const ndn::mgmt::CommandContinuation& done)
{
- ControlResponse response(code, text);
- sendResponse(name, response);
-}
-
-void
-RibManager::onLocalhostRequest(const Interest& request)
-{
- const Name& command = request.getName();
- const Name::Component& verb = command.get(COMMAND_PREFIX.size());
-
- UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
-
- if (unsignedVerbProcessor != m_unsignedVerbDispatch.end()) {
- NFD_LOG_DEBUG("command result: processing unsigned verb: " << verb);
- (unsignedVerbProcessor->second)(this, request);
- }
- else {
- m_localhostValidator.validate(request,
- bind(&RibManager::onCommandValidated, this, _1),
- bind(&RibManager::onCommandValidationFailed, this, _1, _2));
- }
-}
-
-void
-RibManager::onLocalhopRequest(const Interest& request)
-{
- m_localhopValidator.validate(request,
- bind(&RibManager::onCommandValidated, this, _1),
- bind(&RibManager::onCommandValidationFailed, this, _1, _2));
-}
-
-void
-RibManager::onCommandValidated(const shared_ptr<const Interest>& request)
-{
- // REMOTE_COMMAND_PREFIX number of componenets are same as
- // NRD_COMMAND_PREFIX's so no extra checks are required.
-
- const Name& command = request->getName();
- const Name::Component& verb = command[COMMAND_PREFIX.size()];
- const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
-
- SignedVerbDispatchTable::const_iterator verbProcessor = m_signedVerbDispatch.find(verb);
-
- if (verbProcessor != m_signedVerbDispatch.end()) {
-
- ControlParameters parameters;
- if (!extractParameters(parameterComponent, parameters)) {
- NFD_LOG_DEBUG("command result: malformed verb: " << verb);
-
- if (static_cast<bool>(request)) {
- sendResponse(command, 400, "Malformed command");
- }
-
- return;
- }
-
- NFD_LOG_DEBUG("command result: processing verb: " << verb);
- (verbProcessor->second)(this, request, parameters);
- }
- else {
- NFD_LOG_DEBUG("Unsupported command: " << verb);
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), 501, "Unsupported command");
- }
- }
-}
-
-void
-RibManager::registerEntry(const shared_ptr<const Interest>& request,
- ControlParameters& parameters)
-{
- ndn::nfd::RibRegisterCommand command;
-
- if (!validateParameters(command, parameters)) {
- NFD_LOG_DEBUG("register result: FAIL reason: malformed");
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), 400, "Malformed command");
- }
-
- return;
- }
-
- bool isSelfRegistration = (!parameters.hasFaceId() || parameters.getFaceId() == 0);
- if (isSelfRegistration) {
- shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request->getTag<lp::IncomingFaceIdTag>();
- if (incomingFaceIdTag == nullptr) {
- sendResponse(request->getName(), 503,
- "requested self-registration, but IncomingFaceId is unavailable");
- return;
- }
- parameters.setFaceId(*incomingFaceIdTag);
- }
+ setFaceForSelfRegistration(interest, parameters);
// Respond since command is valid and authorized
- sendSuccessResponse(request, parameters);
+ done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
Route route;
route.faceId = parameters.getFaceId();
@@ -305,7 +193,7 @@
// Schedule a new event, the old one will be cancelled during rib insertion.
scheduler::EventId eventId = scheduler::schedule(parameters.getExpirationPeriod(),
- bind(&Rib::onRouteExpiration, &m_managedRib, parameters.getName(), route));
+ bind(&Rib::onRouteExpiration, &m_rib, parameters.getName(), route));
NFD_LOG_TRACE("Scheduled unregistration at: " << route.expires <<
" with EventId: " << eventId);
@@ -326,7 +214,7 @@
.setName(parameters.getName())
.setRoute(route);
- m_managedRib.beginApplyUpdate(update,
+ m_rib.beginApplyUpdate(update,
bind(&RibManager::onRibUpdateSuccess, this, update),
bind(&RibManager::onRibUpdateFailure, this, update, _1, _2));
@@ -334,47 +222,14 @@
}
void
-RibManager::unregisterEntry(const shared_ptr<const Interest>& request,
- ControlParameters& params)
+RibManager::unregisterEntry(const Name& topPrefix, const Interest& interest,
+ ControlParameters parameters,
+ const ndn::mgmt::CommandContinuation& done)
{
- ndn::nfd::RibUnregisterCommand command;
-
- // Passing all parameters gives error in validation,
- // so passing only the required arguments.
- ControlParameters parameters;
- parameters.setName(params.getName());
-
- if (params.hasFaceId()) {
- parameters.setFaceId(params.getFaceId());
- }
-
- if (params.hasOrigin()) {
- parameters.setOrigin(params.getOrigin());
- }
-
- if (!validateParameters(command, parameters)) {
- NFD_LOG_DEBUG("unregister result: FAIL reason: malformed");
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), 400, "Malformed command");
- }
-
- return;
- }
-
- bool isSelfRegistration = (!parameters.hasFaceId() || parameters.getFaceId() == 0);
- if (isSelfRegistration) {
- shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request->getTag<lp::IncomingFaceIdTag>();
- if (incomingFaceIdTag == nullptr) {
- sendResponse(request->getName(), 503,
- "requested self-registration, but IncomingFaceId is unavailable");
- return;
- }
- parameters.setFaceId(*incomingFaceIdTag);
- }
+ setFaceForSelfRegistration(interest, parameters);
// Respond since command is valid and authorized
- sendSuccessResponse(request, parameters);
+ done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
Route route;
route.faceId = parameters.getFaceId();
@@ -388,272 +243,72 @@
.setName(parameters.getName())
.setRoute(route);
- m_managedRib.beginApplyUpdate(update,
+ m_rib.beginApplyUpdate(update,
bind(&RibManager::onRibUpdateSuccess, this, update),
bind(&RibManager::onRibUpdateFailure, this, update, _1, _2));
}
void
-RibManager::onCommandValidationFailed(const shared_ptr<const Interest>& request,
- const std::string& failureInfo)
+RibManager::listEntries(const Name& topPrefix, const Interest& interest,
+ ndn::mgmt::StatusDatasetContext& context)
{
- NFD_LOG_DEBUG("RibRequestValidationFailed: " << failureInfo);
+ for (auto&& ribTableEntry : m_rib) {
+ const auto& ribEntry = *ribTableEntry.second;
+ ndn::nfd::RibEntry record;
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), 403, failureInfo);
- }
-}
+ for (auto&& route : ribEntry) {
+ ndn::nfd::Route routeElement;
+ routeElement.setFaceId(route.faceId)
+ .setOrigin(route.origin)
+ .setCost(route.cost)
+ .setFlags(route.flags);
+ if (route.expires < time::steady_clock::TimePoint::max()) {
+ routeElement.setExpirationPeriod(time::duration_cast<time::milliseconds>(
+ route.expires - time::steady_clock::now()));
+ }
-bool
-RibManager::extractParameters(const Name::Component& parameterComponent,
- ControlParameters& extractedParameters)
-{
- try {
- Block rawParameters = parameterComponent.blockFromValue();
- extractedParameters.wireDecode(rawParameters);
- }
- catch (const tlv::Error&) {
- return false;
+ record.addRoute(routeElement);
+ }
+
+ record.setName(ribEntry.getName());
+ context.append(record.wireEncode());
}
- NFD_LOG_DEBUG("Parameters parsed OK");
- return true;
-}
-
-bool
-RibManager::validateParameters(const ControlCommand& command,
- ControlParameters& parameters)
-{
- try {
- command.validateRequest(parameters);
- }
- catch (const ControlCommand::ArgumentError&) {
- return false;
- }
-
- command.applyDefaultsToRequest(parameters);
-
- return true;
+ context.end();
}
void
-RibManager::onCommandError(uint32_t code, const std::string& error,
- const shared_ptr<const Interest>& request,
- const Route& route)
+RibManager::setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters)
{
- NFD_LOG_ERROR("NFD returned an error: " << error << " (code: " << code << ")");
-
- ControlResponse response;
-
- if (code == 404) {
- response.setCode(code);
- response.setText(error);
- }
- else {
- response.setCode(533);
- std::ostringstream os;
- os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
- response.setText(os.str());
- }
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), response);
+ bool isSelfRegistration = (parameters.getFaceId() == 0);
+ if (isSelfRegistration) {
+ shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
+ // NDNLPv2 says "application MUST be prepared to receive a packet without IncomingFaceId field",
+ // but it's fine to assert IncomingFaceId is available, because InternalFace lives inside NFD
+ // and is initialized synchronously with IncomingFaceId field enabled.
+ BOOST_ASSERT(incomingFaceIdTag != nullptr);
+ parameters.setFaceId(*incomingFaceIdTag);
}
}
void
-RibManager::onRegSuccess(const shared_ptr<const Interest>& request,
- const ControlParameters& parameters,
- const Route& route)
+RibManager::authorize(const Name& prefix, const Interest& interest,
+ const ndn::mgmt::ControlParameters* params,
+ ndn::mgmt::AcceptContinuation accept,
+ ndn::mgmt::RejectContinuation reject)
{
- ControlResponse response;
+ BOOST_ASSERT(params != nullptr);
+ BOOST_ASSERT(typeid(*params) == typeid(ndn::nfd::ControlParameters));
+ BOOST_ASSERT(prefix == LOCAL_HOST_TOP_PREFIX || prefix == LOCAL_HOP_TOP_PREFIX);
- response.setCode(200);
- response.setText("Success");
- response.setBody(parameters.wireEncode());
+ auto& validator = [this, &prefix] () -> ndn::ValidatorConfig & {
+ return prefix == LOCAL_HOST_TOP_PREFIX ? m_localhostValidator : m_localhopValidator;
+ }();
- NFD_LOG_TRACE("onRegSuccess: registered " << route);
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), response);
- }
-}
-
-
-void
-RibManager::onUnRegSuccess(const shared_ptr<const Interest>& request,
- const ControlParameters& parameters,
- const Route& route)
-{
- ControlResponse response;
-
- response.setCode(200);
- response.setText("Success");
- response.setBody(parameters.wireEncode());
-
- NFD_LOG_TRACE("onUnRegSuccess: unregistered " << route);
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), response);
- }
-}
-
-void
-RibManager::sendSuccessResponse(const shared_ptr<const Interest>& request,
- const ControlParameters& parameters)
-{
- if (!static_cast<bool>(request)) {
- return;
- }
-
- ControlResponse response;
-
- response.setCode(200);
- response.setText("Success");
- response.setBody(parameters.wireEncode());
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), response);
- }
-}
-
-void
-RibManager::sendErrorResponse(uint32_t code, const std::string& error,
- const shared_ptr<const Interest>& request)
-{
- NFD_LOG_ERROR("NFD returned an error: " << error << " (code: " << code << ")");
-
- if (!static_cast<bool>(request)) {
- return;
- }
-
- ControlResponse response;
-
- if (code == 404) {
- response.setCode(code);
- response.setText(error);
- }
- else {
- response.setCode(533);
- std::ostringstream os;
- os << "Failure to update NFD " << "(NFD Error: " << code << " " << error << ")";
- response.setText(os.str());
- }
-
- if (static_cast<bool>(request)) {
- sendResponse(request->getName(), response);
- }
-}
-
-void
-RibManager::onRibUpdateSuccess(const RibUpdate& update)
-{
- NFD_LOG_DEBUG("RIB update succeeded for " << update);
-}
-
-void
-RibManager::onRibUpdateFailure(const RibUpdate& update, uint32_t code, const std::string& error)
-{
- NFD_LOG_DEBUG("RIB update failed for " << update << " (code: " << code
- << ", error: " << error << ")");
-
- // Since the FIB rejected the update, clean up invalid routes
- scheduleActiveFaceFetch(time::seconds(1));
-}
-
-void
-RibManager::onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
- const ndn::nfd::ControlParameters& result)
-{
- NFD_LOG_DEBUG("Successfully registered " + prefix.toUri() + " with NFD");
-
- // Routes must be inserted into the RIB so route flags can be applied
- Route route;
- route.faceId = result.getFaceId();
- route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
- route.expires = time::steady_clock::TimePoint::max();
- route.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
-
- m_managedRib.insert(prefix, route);
-
- m_registeredFaces.insert(route.faceId);
-}
-
-void
-RibManager::onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg)
-{
- BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() + "): " + msg));
-}
-
-void
-RibManager::onControlHeaderSuccess()
-{
- NFD_LOG_DEBUG("Local control header enabled");
-}
-
-void
-RibManager::onControlHeaderError(uint32_t code, const std::string& reason)
-{
- std::ostringstream os;
- os << "Couldn't enable local control header "
- << "(code: " << code << ", info: " << reason << ")";
- BOOST_THROW_EXCEPTION(Error(os.str()));
-}
-
-void
-RibManager::enableLocalControlHeader()
-{
- m_nfdController.start<ndn::nfd::FaceEnableLocalControlCommand>(
- ControlParameters()
- .setLocalControlFeature(ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
- bind(&RibManager::onControlHeaderSuccess, this),
- bind(&RibManager::onControlHeaderError, this, _1, _2));
-}
-
-void
-RibManager::onNotification(const FaceEventNotification& notification)
-{
- NFD_LOG_TRACE("onNotification: " << notification);
-
- if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
- NFD_LOG_DEBUG("Received notification for destroyed faceId: " << notification.getFaceId());
-
- scheduler::schedule(time::seconds(0),
- bind(&RibManager::onFaceDestroyedEvent, this, notification.getFaceId()));
- }
-}
-
-void
-RibManager::onFaceDestroyedEvent(uint64_t faceId)
-{
- m_managedRib.beginRemoveFace(faceId);
- m_registeredFaces.erase(faceId);
-}
-
-void
-RibManager::listEntries(const Interest& request)
-{
- const Name& command = request.getName();
- const size_t commandNComps = command.size();
-
- if (commandNComps < LIST_COMMAND_NCOMPS || !LIST_COMMAND_PREFIX.isPrefixOf(command)) {
- NFD_LOG_DEBUG("command result: malformed");
-
- sendResponse(command, 400, "Malformed command");
- return;
- }
-
- m_ribStatusPublisher.publish();
-}
-
-void
-RibManager::scheduleActiveFaceFetch(const time::seconds& timeToWait)
-{
- scheduler::cancel(m_activeFaceFetchEvent);
-
- m_activeFaceFetchEvent = scheduler::schedule(timeToWait,
- bind(&RibManager::fetchActiveFaces, this));
+ validator.validate(interest,
+ bind([&interest, this, accept] { extractRequester(interest, accept); }),
+ bind([reject] { reject(ndn::mgmt::RejectReply::STATUS403); }));
}
void
@@ -693,6 +348,29 @@
}
void
+RibManager::onFetchFaceStatusTimeout()
+{
+ std::cerr << "Face Status Dataset request timed out" << std::endl;
+ scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
+}
+
+void
+RibManager::onFaceDestroyedEvent(uint64_t faceId)
+{
+ m_rib.beginRemoveFace(faceId);
+ m_registeredFaces.erase(faceId);
+}
+
+void
+RibManager::scheduleActiveFaceFetch(const time::seconds& timeToWait)
+{
+ scheduler::cancel(m_activeFaceFetchEvent);
+
+ m_activeFaceFetchEvent = scheduler::schedule(timeToWait,
+ bind(&RibManager::fetchActiveFaces, this));
+}
+
+void
RibManager::removeInvalidFaces(shared_ptr<ndn::OBufferStream> buffer)
{
NFD_LOG_DEBUG("Checking for invalid face registrations");
@@ -719,7 +397,7 @@
// Look for face IDs that were registered but not active to find missed
// face destroyed events
- for (uint64_t faceId : m_registeredFaces) {
+ for (auto&& faceId : m_registeredFaces) {
if (activeFaces.find(faceId) == activeFaces.end()) {
NFD_LOG_DEBUG("Removing invalid face ID: " << faceId);
@@ -733,10 +411,55 @@
}
void
-RibManager::onFetchFaceStatusTimeout()
+RibManager::onNotification(const FaceEventNotification& notification)
{
- std::cerr << "Face Status Dataset request timed out" << std::endl;
- scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
+ NFD_LOG_TRACE("onNotification: " << notification);
+
+ if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
+ NFD_LOG_DEBUG("Received notification for destroyed faceId: " << notification.getFaceId());
+
+ scheduler::schedule(time::seconds(0),
+ bind(&RibManager::onFaceDestroyedEvent, this, notification.getFaceId()));
+ }
+}
+
+void
+RibManager::onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
+ const ndn::nfd::ControlParameters& result)
+{
+ NFD_LOG_DEBUG("Successfully registered " + prefix.toUri() + " with NFD");
+
+ // Routes must be inserted into the RIB so route flags can be applied
+ Route route;
+ route.faceId = result.getFaceId();
+ route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
+ route.expires = time::steady_clock::TimePoint::max();
+ route.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
+
+ m_rib.insert(prefix, route);
+
+ m_registeredFaces.insert(route.faceId);
+}
+
+void
+RibManager::onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg)
+{
+ BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() + "): " + msg));
+}
+
+void
+RibManager::onControlHeaderSuccess()
+{
+ NFD_LOG_DEBUG("Local control header enabled");
+}
+
+void
+RibManager::onControlHeaderError(uint32_t code, const std::string& reason)
+{
+ std::ostringstream os;
+ os << "Couldn't enable local control header "
+ << "(code: " << code << ", info: " << reason << ")";
+ BOOST_THROW_EXCEPTION(Error(os.str()));
}
} // namespace rib
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
index d7c6819..0e5d68d 100644
--- a/rib/rib-manager.hpp
+++ b/rib/rib-manager.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,6 +28,7 @@
#include "rib.hpp"
#include "core/config-file.hpp"
+#include "core/manager-base.hpp"
#include "rib-status-publisher.hpp"
#include "auto-prefix-propagator.hpp"
#include "fib-updater.hpp"
@@ -48,7 +49,7 @@
using ndn::nfd::FaceEventNotification;
-class RibManager : noncopyable
+class RibManager : public nfd::ManagerBase
{
public:
class Error : public std::runtime_error
@@ -61,7 +62,8 @@
}
};
- RibManager(ndn::Face& face, ndn::KeyChain& keyChain);
+public:
+ RibManager(Dispatcher& dispatcher, ndn::Face& face, ndn::KeyChain& keyChain);
~RibManager();
@@ -80,107 +82,55 @@
void
onRibUpdateFailure(const RibUpdate& update, uint32_t code, const std::string& error);
-private:
+private: // initialization helpers
void
- onConfig(const ConfigSection& configSection,
- bool isDryRun,
- const std::string& filename);
+ onConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
void
- startListening(const Name& commandPrefix, const ndn::OnInterest& onRequest);
+ registerTopPrefix(const Name& topPrefix);
+
+private: // ControlCommand and StatusDataset
+ void
+ registerEntry(const Name& topPrefix, const Interest& interest,
+ ControlParameters parameters,
+ const ndn::mgmt::CommandContinuation& done);
void
- onLocalhopRequest(const Interest& request);
+ unregisterEntry(const Name& topPrefix, const Interest& interest,
+ ControlParameters parameters,
+ const ndn::mgmt::CommandContinuation& done);
void
- onLocalhostRequest(const Interest& request);
+ listEntries(const Name& topPrefix, const Interest& interest,
+ ndn::mgmt::StatusDatasetContext& context);
void
- sendResponse(const Name& name,
- const ControlResponse& response);
+ setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
- void
- sendResponse(const Name& name,
- uint32_t code,
- const std::string& text);
+private: // command validation
+ /**
+ * @brief validate a request for ControlCommand.
+ *
+ * This is called by the dispatcher.
+ *
+ * @pre params != null
+ * @pre typeid(*params) == typeid(ndn::nfd::ControlParameters)
+ *
+ * @param prefix the top prefix
+ * @param interest a request for ControlCommand
+ * @param params the parameters for ControlCommand
+ * @param accept callback of successful validation, take the requester string as a argument
+ * @param reject callback of failure in validation, take the action code as a argument
+ *
+ * use m_localhostValidator / m_localhopValidator to validate commands according to @p prefix.
+ */
+ virtual void
+ authorize(const Name& prefix, const Interest& interest,
+ const ndn::mgmt::ControlParameters* params,
+ ndn::mgmt::AcceptContinuation accept,
+ ndn::mgmt::RejectContinuation reject) override;
- void
- sendSuccessResponse(const shared_ptr<const Interest>& request,
- const ControlParameters& parameters);
-
- void
- sendErrorResponse(uint32_t code, const std::string& error,
- const shared_ptr<const Interest>& request);
-
- void
- registerEntry(const shared_ptr<const Interest>& request,
- ControlParameters& parameters);
-
- void
- unregisterEntry(const shared_ptr<const Interest>& request,
- ControlParameters& parameters);
-
-private:
- void
- onCommandValidated(const shared_ptr<const Interest>& request);
-
- void
- onCommandValidationFailed(const shared_ptr<const Interest>& request,
- const std::string& failureInfo);
-
-
- void
- onCommandError(uint32_t code, const std::string& error,
- const shared_ptr<const Interest>& request,
- const Route& route);
-
- void
- onRegSuccess(const shared_ptr<const Interest>& request,
- const ControlParameters& parameters,
- const Route& route);
-
- void
- onUnRegSuccess(const shared_ptr<const Interest>& request,
- const ControlParameters& parameters,
- const Route& route);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- void
- onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
- const ndn::nfd::ControlParameters& result);
-
-private:
- void
- onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg);
-
- void
- onControlHeaderSuccess();
-
- void
- onControlHeaderError(uint32_t code, const std::string& reason);
-
- static bool
- extractParameters(const Name::Component& parameterComponent,
- ControlParameters& extractedParameters);
-
- bool
- validateParameters(const ControlCommand& command,
- ControlParameters& parameters);
-
- void
- onNotification(const FaceEventNotification& notification);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- void
- onFaceDestroyedEvent(uint64_t faceId);
-
-private:
- void
- listEntries(const Interest& request);
-
- void
- scheduleActiveFaceFetch(const time::seconds& timeToWait);
-
+private: // Face monitor
void
fetchActiveFaces();
@@ -190,70 +140,61 @@
void
onFetchFaceStatusTimeout();
+ void
+ onFaceDestroyedEvent(uint64_t faceId);
+
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- /** \param buffer Face dataset contents
+ void
+ scheduleActiveFaceFetch(const time::seconds& timeToWait);
+
+ /**
+ * @brief remove invalid faces
+ *
+ * @param buffer Face dataset contents
*/
void
removeInvalidFaces(shared_ptr<ndn::OBufferStream> buffer);
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- Rib m_managedRib;
+ /**
+ * @brief response to face events
+ *
+ * @param notification
+ */
+ void
+ onNotification(const FaceEventNotification& notification);
+
+private:
+ void
+ onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
+ const ndn::nfd::ControlParameters& result);
+
+ void
+ onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg);
+
+ void
+ onControlHeaderSuccess();
+
+ void
+ onControlHeaderError(uint32_t code, const std::string& reason);
private:
ndn::Face& m_face;
ndn::KeyChain& m_keyChain;
ndn::nfd::Controller m_nfdController;
+ ndn::nfd::FaceMonitor m_faceMonitor;
ndn::ValidatorConfig m_localhostValidator;
ndn::ValidatorConfig m_localhopValidator;
- ndn::nfd::FaceMonitor m_faceMonitor;
bool m_isLocalhopEnabled;
AutoPrefixPropagator m_prefixPropagator;
- RibStatusPublisher m_ribStatusPublisher;
-
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+ Rib m_rib;
FibUpdater m_fibUpdater;
private:
- typedef function<void(RibManager*,
- const shared_ptr<const Interest>& request,
- ControlParameters& parameters)> SignedVerbProcessor;
-
- typedef std::map<name::Component, SignedVerbProcessor> SignedVerbDispatchTable;
-
- typedef std::pair<name::Component, SignedVerbProcessor> SignedVerbAndProcessor;
-
-
- const SignedVerbDispatchTable m_signedVerbDispatch;
-
- static const Name COMMAND_PREFIX; // /localhost/nrd
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- static const Name REMOTE_COMMAND_PREFIX; // /localhop/nrd
-
-private:
- // number of components in an invalid, but not malformed, unsigned command.
- // (/localhost/nrd + verb + options) = 4
- static const size_t COMMAND_UNSIGNED_NCOMPS;
-
- // number of components in a valid signed Interest.
- // 8 with signed Interest support.
- static const size_t COMMAND_SIGNED_NCOMPS;
-
- static const SignedVerbAndProcessor SIGNED_COMMAND_VERBS[];
-
- typedef function<void(RibManager*, const Interest&)> UnsignedVerbProcessor;
- typedef std::map<Name::Component, UnsignedVerbProcessor> UnsignedVerbDispatchTable;
- typedef std::pair<Name::Component, UnsignedVerbProcessor> UnsignedVerbAndProcessor;
-
- const UnsignedVerbDispatchTable m_unsignedVerbDispatch;
- static const UnsignedVerbAndProcessor UNSIGNED_COMMAND_VERBS[];
-
- static const Name LIST_COMMAND_PREFIX;
- static const size_t LIST_COMMAND_NCOMPS;
-
+ static const Name LOCAL_HOST_TOP_PREFIX;
+ static const Name LOCAL_HOP_TOP_PREFIX;
static const Name FACES_LIST_DATASET_PREFIX;
-
static const time::seconds ACTIVE_FACE_FETCH_INTERVAL;
scheduler::EventId m_activeFaceFetchEvent;
@@ -261,6 +202,8 @@
/** \brief contains FaceIds with one or more Routes in the RIB
*/
FaceIdSet m_registeredFaces;
+
+ std::function<void(const Name& topPrefix)> m_addTopPrefix;
};
} // namespace rib