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
diff --git a/tests/rib/rib-manager.t.cpp b/tests/rib/rib-manager.t.cpp
index 1287284..0f1e3f7 100644
--- a/tests/rib/rib-manager.t.cpp
+++ b/tests/rib/rib-manager.t.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,
@@ -24,11 +24,12 @@
*/
#include "rib/rib-manager.hpp"
-#include <ndn-cxx/management/nfd-face-status.hpp>
-#include "rib/rib-status-publisher-common.hpp"
+#include "manager-common-fixture.hpp"
-#include "tests/test-common.hpp"
-#include <ndn-cxx/util/dummy-client-face.hpp>
+#include <ndn-cxx/management/nfd-rib-entry.hpp>
+#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/management/nfd-face-event-notification.hpp>
+#include <ndn-cxx/util/random.hpp>
namespace nfd {
namespace rib {
@@ -36,448 +37,587 @@
using namespace nfd::tests;
-class RibManagerFixture : public UnitTestTimeFixture
+struct ConfigurationStatus
{
-public:
- RibManagerFixture()
- {
- face = ndn::util::makeDummyClientFace(g_io);
-
- manager = make_shared<RibManager>(*face, keyChain);
- manager->registerWithNfd();
-
- advanceClocks(time::milliseconds(1));
- face->sentInterests.clear();
- }
-
- ~RibManagerFixture()
- {
- manager.reset();
- face.reset();
- }
-
- void
- extractParameters(Interest& interest, Name::Component& verb,
- ControlParameters& extractedParameters)
- {
- const Name& name = interest.getName();
- verb = name[COMMAND_PREFIX.size()];
- const Name::Component& parameterComponent = name[COMMAND_PREFIX.size() + 1];
-
- Block rawParameters = parameterComponent.blockFromValue();
- extractedParameters.wireDecode(rawParameters);
- }
-
- void
- receiveCommandInterest(const Name& name, ControlParameters& parameters,
- uint64_t incomingFaceId = DEFAULT_INCOMING_FACE_ID)
- {
- Name commandName = name;
- commandName.append(parameters.wireEncode());
-
- Interest commandInterest(commandName);
- commandInterest.setTag(make_shared<lp::IncomingFaceIdTag>(incomingFaceId));
-
- manager->m_managedRib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue,
- this, _1, parameters);
-
- face->receive(commandInterest);
- advanceClocks(time::milliseconds(1));
- }
-
- void
- onSendBatchFromQueue(const RibUpdateBatch& batch, const ControlParameters parameters)
- {
- BOOST_REQUIRE(batch.begin() != batch.end());
- RibUpdate update = *(batch.begin());
-
- Rib::UpdateSuccessCallback managerCallback =
- bind(&RibManager::onRibUpdateSuccess, manager, update);
-
- Rib& rib = manager->m_managedRib;
-
- // Simulate a successful response from NFD
- FibUpdater& updater = manager->m_fibUpdater;
- rib.onFibUpdateSuccess(batch, updater.m_inheritedRoutes, managerCallback);
- }
-
-
-public:
- shared_ptr<RibManager> manager;
- shared_ptr<ndn::util::DummyClientFace> face;
- ndn::KeyChain keyChain;
-
- static const uint64_t DEFAULT_INCOMING_FACE_ID;
-
- static const Name COMMAND_PREFIX;
- static const name::Component ADD_NEXTHOP_VERB;
- static const name::Component REMOVE_NEXTHOP_VERB;
-
- static const Name REGISTER_COMMAND;
- static const Name UNREGISTER_COMMAND;
+ bool isLocalhostConfigured;
+ bool isLocalhopConfigured;
};
-const uint64_t RibManagerFixture::DEFAULT_INCOMING_FACE_ID = 25122;
-const Name RibManagerFixture::COMMAND_PREFIX("/localhost/nfd/rib");
-const name::Component RibManagerFixture::ADD_NEXTHOP_VERB("add-nexthop");
-const name::Component RibManagerFixture::REMOVE_NEXTHOP_VERB("remove-nexthop");
-const Name RibManagerFixture::REGISTER_COMMAND("/localhost/nfd/rib/register");
-const Name RibManagerFixture::UNREGISTER_COMMAND("/localhost/nfd/rib/unregister");
-
-class AuthorizedRibManager : public RibManagerFixture
+class RibManagerFixture : public ManagerCommonFixture
{
public:
- AuthorizedRibManager()
+ explicit
+ RibManagerFixture(const ConfigurationStatus& status,
+ bool shouldClearRib)
+ : m_commands(m_face->sentInterests)
+ , m_status(status)
+ , m_manager(m_dispatcher, *m_face, m_keyChain)
+ , m_rib(m_manager.m_rib)
{
- ConfigFile config;
- manager->setConfigFile(config);
+ m_rib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue, this, _1);
- const std::string CONFIG_STRING =
- "rib\n"
- "{\n"
- " localhost_security\n"
+ const std::string prefix = "rib\n{\n";
+ const std::string suffix = "}";
+ const std::string localhostSection = " localhost_security\n"
" {\n"
" trust-anchor\n"
" {\n"
" type any\n"
" }\n"
- " }"
- "}";
+ " }\n";
+ const std::string localhopSection = " localhop_security\n"
+ " {\n"
+ " trust-anchor\n"
+ " {\n"
+ " type any\n"
+ " }\n"
+ " }\n";
- config.parse(CONFIG_STRING, true, "test-rib");
+ std::string ribSection = "";
+ if (m_status.isLocalhostConfigured) {
+ ribSection += localhostSection;
+ }
+ if (m_status.isLocalhopConfigured) {
+ ribSection += localhopSection;
+ }
+ const std::string CONFIG_STR = prefix + ribSection + suffix;
+
+ ConfigFile config;
+ m_manager.setConfigFile(config);
+ config.parse(CONFIG_STR, true, "test-rib");
+
+ registerWithNfd();
+
+ if (shouldClearRib) {
+ clearRib();
+ }
+ }
+
+private:
+ void
+ registerWithNfd()
+ {
+ m_manager.registerWithNfd();
+ advanceClocks(time::milliseconds(1));
+
+ auto replyFibAddCommand = [this] (const Interest& interest) {
+ nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
+ params.setFaceId(1).setCost(0);
+ nfd::ControlResponse resp;
+
+ resp.setCode(200).setBody(params.wireEncode());
+ shared_ptr<Data> data = make_shared<Data>(interest.getName());
+ data->setContent(resp.wireEncode());
+
+ m_keyChain.sign(*data, ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_SHA256));
+
+ m_face->getIoService().post([this, data] { m_face->receive(*data); });
+ };
+
+ Name commandPrefix("/localhost/nfd/fib/add-nexthop");
+ for (auto&& command : m_commands) {
+ if (commandPrefix.isPrefixOf(command.getName())) {
+ replyFibAddCommand(command);
+ advanceClocks(time::milliseconds(1));
+ }
+ }
+
+ // clear commands and responses
+ m_responses.clear();
+ m_commands.clear();
+ }
+
+ void clearRib()
+ {
+ while (!m_rib.empty()) {
+ auto& name = m_rib.begin()->first;
+ auto& routes = m_rib.begin()->second->getRoutes();
+ while (!routes.empty()) {
+ m_rib.erase(name, *routes.begin());
+ }
+ }
+ }
+
+public:
+ ControlParameters
+ makeRegisterParameters(const Name& name, uint64_t id = 0,
+ const time::milliseconds expiry = time::milliseconds::max())
+ {
+ return ControlParameters()
+ .setName(name)
+ .setFaceId(id)
+ .setOrigin(128)
+ .setCost(10)
+ .setFlags(0)
+ .setExpirationPeriod(expiry);
+ }
+
+ ControlParameters
+ makeUnregisterParameters(const Name& name, uint64_t id = 0)
+ {
+ return ControlParameters()
+ .setName(name)
+ .setFaceId(id)
+ .setOrigin(128);
+ }
+
+ void
+ onSendBatchFromQueue(const RibUpdateBatch& batch)
+ {
+ BOOST_ASSERT(batch.begin() != batch.end());
+ RibUpdate update = *(batch.begin());
+
+ // Simulate a successful response from NFD
+ FibUpdater& updater = m_manager.m_fibUpdater;
+ m_manager.m_rib.onFibUpdateSuccess(batch, updater.m_inheritedRoutes,
+ bind(&RibManager::onRibUpdateSuccess, &m_manager, update));
+ }
+
+public:
+ enum class CheckCommandResult {
+ OK,
+ OUT_OF_BOUNDARY,
+ WRONG_FORMAT,
+ WRONG_VERB,
+ WRONG_PARAMS_FORMAT,
+ WRONG_PARAMS_NAME,
+ WRONG_PARAMS_FACE
+ };
+
+ CheckCommandResult
+ checkCommand(size_t idx, const char* verbStr, ControlParameters expectedParams)
+ {
+ if (idx > m_commands.size()) {
+ return CheckCommandResult::OUT_OF_BOUNDARY;
+ }
+ const auto& name = m_commands[idx].getName();
+
+ if (!FIB_COMMAND_PREFIX.isPrefixOf(name) || FIB_COMMAND_PREFIX.size() >= name.size()) {
+ return CheckCommandResult::WRONG_FORMAT;
+ }
+ const auto& verb = name[FIB_COMMAND_PREFIX.size()];
+
+ Name::Component expectedVerb(verbStr);
+ if (verb != expectedVerb) {
+ return CheckCommandResult::WRONG_VERB;
+ }
+
+ ControlParameters parameters;
+ try {
+ Block rawParameters = name[FIB_COMMAND_PREFIX.size() + 1].blockFromValue();
+ parameters.wireDecode(rawParameters);
+ }
+ catch (...) {
+ return CheckCommandResult::WRONG_PARAMS_FORMAT;
+ }
+
+ if (parameters.getName() != expectedParams.getName()) {
+ return CheckCommandResult::WRONG_PARAMS_NAME;
+ }
+
+ if (parameters.getFaceId() != expectedParams.getFaceId()) {
+ return CheckCommandResult::WRONG_PARAMS_FACE;
+ }
+
+ return CheckCommandResult::OK;
+ }
+
+public:
+ std::vector<Interest>& m_commands;
+ ConfigurationStatus m_status;
+ static const Name FIB_COMMAND_PREFIX;
+
+protected:
+ RibManager m_manager;
+ Rib& m_rib;
+};
+
+const Name RibManagerFixture::FIB_COMMAND_PREFIX("/localhost/nfd/fib");
+
+std::ostream&
+operator<<(std::ostream& os, const RibManagerFixture::CheckCommandResult& result)
+{
+ switch (result) {
+ case RibManagerFixture::CheckCommandResult::OK:
+ os << "OK";
+ break;
+ case RibManagerFixture::CheckCommandResult::OUT_OF_BOUNDARY:
+ os << "OUT_OF_BOUNDARY";
+ break;
+ case RibManagerFixture::CheckCommandResult::WRONG_FORMAT:
+ os << "WRONG_FORMAT";
+ break;
+ case RibManagerFixture::CheckCommandResult::WRONG_VERB:
+ os << "WRONG_VERB";
+ break;
+ case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FORMAT:
+ os << "WRONG_COST";
+ break;
+ case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_NAME:
+ os << "WRONG_PARAMS_NAME";
+ break;
+ case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FACE:
+ os << "WRONG_PARAMS_FACE";
+ break;
+ default:
+ break;
+ };
+
+ return os;
+}
+
+BOOST_AUTO_TEST_SUITE(Rib)
+BOOST_AUTO_TEST_SUITE(TestRibManager)
+
+class AddTopPrefixFixture : public RibManagerFixture
+{
+public:
+ AddTopPrefixFixture()
+ : RibManagerFixture({true, true}, false)
+ {
}
};
-typedef RibManagerFixture UnauthorizedRibManager;
-
-BOOST_FIXTURE_TEST_SUITE(TestRibManager, RibManagerFixture)
-
-BOOST_FIXTURE_TEST_CASE(ShortName, AuthorizedRibManager)
+BOOST_FIXTURE_TEST_CASE(AddTopPrefix, AddTopPrefixFixture)
{
- Name commandName("/localhost/nfd/rib");
- ndn::nfd::ControlParameters parameters;
+ BOOST_CHECK_EQUAL(m_rib.size(), 2);
- receiveCommandInterest(commandName, parameters);
- // TODO verify error response
+ std::vector<Name> ribEntryNames;
+ for (auto&& entry : m_rib) {
+ ribEntryNames.push_back(entry.first);
+ }
+ BOOST_CHECK_EQUAL(ribEntryNames[0], "/localhop/nfd");
+ BOOST_CHECK_EQUAL(ribEntryNames[1], "/localhost/nfd");
}
-BOOST_FIXTURE_TEST_CASE(Basic, AuthorizedRibManager)
+class UnauthorizedRibManagerFixture : public RibManagerFixture
{
- ControlParameters parameters;
- parameters
- .setName("/hello")
- .setFaceId(1)
- .setCost(10)
- .setFlags(0)
- .setOrigin(128)
- .setExpirationPeriod(ndn::time::milliseconds::max());
+public:
+ UnauthorizedRibManagerFixture()
+ : RibManagerFixture({false, false}, true)
+ {
+ }
+};
- receiveCommandInterest(REGISTER_COMMAND, parameters);
+class LocalhostAuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+ LocalhostAuthorizedRibManagerFixture()
+ : RibManagerFixture({true, false}, true)
+ {
+ }
+};
- BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+class LocalhopAuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+ LocalhopAuthorizedRibManagerFixture()
+ : RibManagerFixture({false, true}, true)
+ {
+ }
+};
+
+class AuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+ AuthorizedRibManagerFixture()
+ : RibManagerFixture({true, true}, true)
+ {
+ }
+};
+
+typedef boost::mpl::vector<
+ UnauthorizedRibManagerFixture,
+ LocalhostAuthorizedRibManagerFixture,
+ LocalhopAuthorizedRibManagerFixture,
+ AuthorizedRibManagerFixture
+> AllFixtures;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(CommandAuthorization, T, AllFixtures, T)
+{
+ auto parameters = this->makeRegisterParameters("/test-authorization", 9527);
+ auto commandHost = this->makeControlCommandRequest("/localhost/nfd/rib/register", parameters);
+ auto commandHop = this->makeControlCommandRequest("/localhop/nfd/rib/register", parameters);
+ auto successResp = this->makeResponse(200, "Success", parameters);
+ auto failureResp = ControlResponse(403, "authorization rejected");
+
+ BOOST_CHECK_EQUAL(this->m_responses.size(), 0);
+ this->receiveInterest(commandHost);
+ this->receiveInterest(commandHop);
+
+ auto nExpectedResponses = this->m_status.isLocalhopConfigured ? 2 : 1;
+ auto expectedLocalhostResponse = this->m_status.isLocalhostConfigured ? successResp : failureResp;
+ auto expectedLocalhopResponse = this->m_status.isLocalhopConfigured ? successResp : failureResp;
+
+ BOOST_REQUIRE_EQUAL(this->m_responses.size(), nExpectedResponses);
+ BOOST_CHECK_EQUAL(this->checkResponse(0, commandHost->getName(), expectedLocalhostResponse),
+ ManagerCommonFixture::CheckResponseResult::OK);
+ if (nExpectedResponses == 2) {
+ BOOST_CHECK_EQUAL(this->checkResponse(1, commandHop->getName(), expectedLocalhopResponse),
+ ManagerCommonFixture::CheckResponseResult::OK);
+ }
}
-BOOST_FIXTURE_TEST_CASE(Register, AuthorizedRibManager)
+BOOST_FIXTURE_TEST_SUITE(RegisterUnregister, LocalhostAuthorizedRibManagerFixture)
+
+BOOST_AUTO_TEST_CASE(Basic)
{
- ControlParameters parameters;
- parameters
- .setName("/hello")
- .setFaceId(1)
- .setCost(10)
- .setFlags(0)
- .setOrigin(128)
- .setExpirationPeriod(ndn::time::milliseconds::max());
+ auto paramsRegister = makeRegisterParameters("/test-register-unregister", 9527);
+ auto paramsUnregister = makeUnregisterParameters("/test-register-unregister", 9527);
- receiveCommandInterest(REGISTER_COMMAND, parameters);
+ auto setInFaceId = [] (shared_ptr<Interest> commandInterest) {
+ commandInterest->setTag(make_shared<lp::IncomingFaceIdTag>(1234));
+ };
- BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+ auto commandRegister = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister, setInFaceId);
+ auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister, setInFaceId);
- Interest& request = face->sentInterests[0];
+ receiveInterest(commandRegister);
+ receiveInterest(commandUnregister);
- ControlParameters extractedParameters;
- Name::Component verb;
- extractParameters(request, verb, extractedParameters);
+ BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+ BOOST_CHECK_EQUAL(checkResponse(0, commandRegister->getName(), makeResponse(200, "Success", paramsRegister)),
+ CheckResponseResult::OK);
+ BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister->getName(), makeResponse(200, "Success", paramsUnregister)),
+ CheckResponseResult::OK);
- BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB);
- BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName());
- BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), parameters.getFaceId());
- BOOST_CHECK_EQUAL(extractedParameters.getCost(), parameters.getCost());
+ BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+ BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+ BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
}
-BOOST_FIXTURE_TEST_CASE(Unregister, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(SelfOperation)
{
- ControlParameters addParameters;
- addParameters
- .setName("/hello")
- .setFaceId(1)
- .setCost(10)
- .setFlags(0)
- .setOrigin(128)
- .setExpirationPeriod(ndn::time::milliseconds::max());
+ auto paramsRegister = makeRegisterParameters("/test-self-register-unregister");
+ auto paramsUnregister = makeUnregisterParameters("/test-self-register-unregister");
+ BOOST_CHECK_EQUAL(paramsRegister.getFaceId(), 0);
+ BOOST_CHECK_EQUAL(paramsUnregister.getFaceId(), 0);
- receiveCommandInterest(REGISTER_COMMAND, addParameters);
- face->sentInterests.clear();
+ const uint64_t inFaceId = 9527;
+ auto setInFaceId = [&inFaceId] (shared_ptr<Interest> commandInterest) {
+ commandInterest->setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));
+ };
+ auto commandRegister = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister, setInFaceId);
+ auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister, setInFaceId);
- ControlParameters removeParameters;
- removeParameters
- .setName("/hello")
- .setFaceId(1)
- .setOrigin(128);
+ receiveInterest(commandRegister);
+ receiveInterest(commandUnregister);
- receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
+ paramsRegister.setFaceId(inFaceId);
+ paramsUnregister.setFaceId(inFaceId);
- BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+ BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+ BOOST_CHECK_EQUAL(checkResponse(0, commandRegister->getName(), makeResponse(200, "Success", paramsRegister)),
+ CheckResponseResult::OK);
+ BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister->getName(), makeResponse(200, "Success", paramsUnregister)),
+ CheckResponseResult::OK);
- Interest& request = face->sentInterests[0];
-
- ControlParameters extractedParameters;
- Name::Component verb;
- extractParameters(request, verb, extractedParameters);
-
- BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB);
- BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName());
- BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), removeParameters.getFaceId());
+ BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+ BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+ BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
}
-BOOST_FIXTURE_TEST_CASE(SelfRegister, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(Expiration)
{
- ControlParameters parameters;
- parameters
- .setName("/hello");
+ auto paramsRegister = makeRegisterParameters("/test-expiry", 9527, time::milliseconds(50));
+ auto paramsUnregister = makeRegisterParameters("/test-expiry", 9527);
+ receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));
- receiveCommandInterest(REGISTER_COMMAND, parameters, 10129);
+ advanceClocks(time::milliseconds(55));
+ BOOST_REQUIRE_EQUAL(m_commands.size(), 2); // the registered route has expired
+ BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+ BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
- BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+ m_commands.clear();
+ paramsRegister.setExpirationPeriod(time::milliseconds(100));
+ receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));
- Interest& request = face->sentInterests[0];
-
- ControlParameters extractedParameters;
- Name::Component verb;
- extractParameters(request, verb, extractedParameters);
-
- BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB);
- BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName());
- BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), 10129);
+ advanceClocks(time::milliseconds(55));
+ BOOST_REQUIRE_EQUAL(m_commands.size(), 1); // the registered route is still active
+ BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
}
-BOOST_FIXTURE_TEST_CASE(SelfUnregister, AuthorizedRibManager)
+BOOST_AUTO_TEST_SUITE_END() // RegisterUnregister
+
+// @todo Remove when ndn::nfd::RibEntry implements operator!=
+class RibEntry : public ndn::nfd::RibEntry
{
- ControlParameters addParameters;
- addParameters
- .setName("/hello")
- .setFaceId(10129);
+public:
+ RibEntry() = default;
- receiveCommandInterest(REGISTER_COMMAND, addParameters);
- face->sentInterests.clear();
+ RibEntry(const ndn::nfd::RibEntry& entry)
+ : ndn::nfd::RibEntry(entry)
+ {
+ }
+};
- ControlParameters removeParameters;
- removeParameters
- .setName("/hello");
+bool
+operator!=(const RibEntry& left, const RibEntry& right)
+{
+ if (left.getName() != right.getName()) {
+ return true;
+ }
- receiveCommandInterest(UNREGISTER_COMMAND, removeParameters, 10129);
+ auto leftRoutes = left.getRoutes();
+ auto rightRoutes = right.getRoutes();
+ if (leftRoutes.size() != rightRoutes.size()) {
+ return true;
+ }
- BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+ for (auto&& route : leftRoutes) {
+ auto hitEntry =
+ std::find_if(rightRoutes.begin(), rightRoutes.end(), [&] (const ndn::nfd::Route& record) {
+ return route.getFaceId() == record.getFaceId() &&
+ route.getCost() == record.getCost() &&
+ route.getOrigin() == record.getOrigin() &&
+ route.getFlags() == record.getFlags() &&
+ route.getExpirationPeriod() == record.getExpirationPeriod();
+ });
- Interest& request = face->sentInterests[0];
+ if (hitEntry == rightRoutes.end()) {
+ return true;
+ }
+ }
- ControlParameters extractedParameters;
- Name::Component verb;
- extractParameters(request, verb, extractedParameters);
-
- BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB);
- BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName());
- BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), 10129);
+ return false;
}
-BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedRibManager)
+BOOST_FIXTURE_TEST_CASE(RibDataset, UnauthorizedRibManagerFixture)
{
- ControlParameters parameters;
- parameters
- .setName("/hello")
- .setFaceId(1)
- .setCost(10)
- .setFlags(0)
- .setOrigin(128)
- .setExpirationPeriod(ndn::time::milliseconds::max());
+ uint64_t faceId = 0;
+ auto generateRoute = [&faceId] () -> Route {
+ Route route;
+ route.faceId = ++faceId;
+ route.cost = ndn::random::generateWord64();
+ route.expires = time::steady_clock::TimePoint::max();
+ return route;
+ };
- BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
+ const size_t nEntries = 108;
+ std::set<Name> actualPrefixes;
+ for (size_t i = 0; i < nEntries; ++i) {
+ Name prefix = Name("/test-dataset").appendNumber(i);
+ actualPrefixes.insert(prefix);
+ m_rib.insert(prefix, generateRoute());
+ if (i & 0x1) {
+ m_rib.insert(prefix, generateRoute());
+ m_rib.insert(prefix, generateRoute());
+ }
+ }
- receiveCommandInterest(REGISTER_COMMAND, parameters);
+ receiveInterest(makeInterest("/localhost/nfd/rib/list"));
- BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
+ Block content;
+ BOOST_CHECK_NO_THROW(content = concatenateResponses());
+ BOOST_CHECK_NO_THROW(content.parse());
+ BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+ std::vector<RibEntry> receivedRecords, expectedRecords;
+ for (size_t idx = 0; idx < nEntries; ++idx) {
+ BOOST_TEST_MESSAGE("processing element: " << idx);
+
+ RibEntry decodedEntry;
+ BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
+ receivedRecords.push_back(decodedEntry);
+
+ actualPrefixes.erase(decodedEntry.getName());
+
+ auto matchedEntryIt = m_rib.find(decodedEntry.getName());
+ BOOST_REQUIRE(matchedEntryIt != m_rib.end());
+
+ auto matchedEntry = matchedEntryIt->second;
+ BOOST_REQUIRE(matchedEntry != nullptr);
+
+ RibEntry record;
+ record.setName(matchedEntry->getName());
+ const auto& routes = matchedEntry->getRoutes();
+ for (auto&& route : routes) {
+ ndn::nfd::Route routeRecord;
+ routeRecord.setFaceId(route.faceId);
+ routeRecord.setOrigin(route.origin);
+ routeRecord.setFlags(route.flags);
+ routeRecord.setCost(route.cost);
+ record.addRoute(routeRecord);
+ }
+ expectedRecords.push_back(record);
+ }
+
+ BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
+ expectedRecords.begin(), expectedRecords.end());
}
-BOOST_FIXTURE_TEST_CASE(RibStatusRequest, AuthorizedRibManager)
+BOOST_FIXTURE_TEST_SUITE(FaceMonitor, LocalhostAuthorizedRibManagerFixture)
+
+BOOST_AUTO_TEST_CASE(FetchActiveFacesEvent)
{
- Name prefix("/");
+ BOOST_CHECK_EQUAL(m_commands.size(), 0);
- Route route;
- route.faceId = 1;
- route.origin = 128;
- route.cost = 32;
- route.flags = ndn::nfd::ROUTE_FLAG_CAPTURE;
-
- manager->m_managedRib.insert(prefix, route);
-
- face->receive(Interest("/localhost/nfd/rib/list"));
- advanceClocks(time::milliseconds(1));
-
- BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
- RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], prefix, route);
+ advanceClocks(time::seconds(301)); // RibManager::ACTIVE_FACE_FETCH_INTERVAL = 300s
+ BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+ BOOST_CHECK_EQUAL(m_commands[0].getName(), "/localhost/nfd/faces/events");
+ BOOST_CHECK_EQUAL(m_commands[1].getName(), "/localhost/nfd/faces/list");
}
-BOOST_FIXTURE_TEST_CASE(CancelExpirationEvent, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(RemoveInvalidFaces)
{
- // Register route
- ControlParameters addParameters;
- addParameters
- .setName("/expire")
- .setFaceId(1)
- .setCost(10)
- .setFlags(0)
- .setOrigin(128)
- .setExpirationPeriod(ndn::time::milliseconds(500));
+ auto parameters1 = makeRegisterParameters("/test-remove-invalid-faces-1");
+ auto parameters2 = makeRegisterParameters("/test-remove-invalid-faces-2");
+ receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(1)));
+ receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(2)));
+ receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2.setFaceId(2)));
+ BOOST_REQUIRE_EQUAL(m_rib.size(), 3);
- receiveCommandInterest(REGISTER_COMMAND, addParameters);
- face->sentInterests.clear();
-
- // Unregister route
- ControlParameters removeParameters;
- removeParameters
- .setName("/expire")
- .setFaceId(1)
- .setOrigin(128);
-
- receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
-
- // Reregister route
- addParameters.setExpirationPeriod(ndn::time::milliseconds::max());
- receiveCommandInterest(REGISTER_COMMAND, addParameters);
-
- advanceClocks(time::milliseconds(100), time::seconds(1));
-
- BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-}
-
-BOOST_FIXTURE_TEST_CASE(RemoveInvalidFaces, AuthorizedRibManager)
-{
- // Register valid face
- ControlParameters validParameters;
- validParameters
- .setName("/test")
- .setFaceId(1);
-
- receiveCommandInterest(REGISTER_COMMAND, validParameters);
-
- // Register invalid face
- ControlParameters invalidParameters;
- invalidParameters
- .setName("/test")
- .setFaceId(2);
-
- receiveCommandInterest(REGISTER_COMMAND, invalidParameters);
-
- BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 2);
-
- // Receive status with only faceId: 1
ndn::nfd::FaceStatus status;
status.setFaceId(1);
- shared_ptr<Data> data = nfd::tests::makeData("/localhost/nfd/faces/list");
+ auto data = makeData("/localhost/nfd/faces/list");
data->setContent(status.wireEncode());
- shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>();
+ auto buffer = make_shared<ndn::OBufferStream>();
buffer->write(reinterpret_cast<const char*>(data->getContent().value()),
data->getContent().value_size());
- manager->removeInvalidFaces(buffer);
+ m_manager.removeInvalidFaces(buffer);
+ advanceClocks(time::milliseconds(100));
+ BOOST_REQUIRE_EQUAL(m_rib.size(), 1);
- // Run scheduler
- advanceClocks(time::milliseconds(100), time::seconds(1));
-
- BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-
- Rib::const_iterator it = manager->m_managedRib.find("/test");
- BOOST_REQUIRE(it != manager->m_managedRib.end());
-
- shared_ptr<RibEntry> entry = it->second;
- BOOST_CHECK_EQUAL(entry->hasFaceId(1), true);
- BOOST_CHECK_EQUAL(entry->hasFaceId(2), false);
+ auto it1 = m_rib.find("/test-remove-invalid-faces-1");
+ auto it2 = m_rib.find("/test-remove-invalid-faces-2");
+ BOOST_CHECK(it2 == m_rib.end());
+ BOOST_REQUIRE(it1 != m_rib.end());
+ BOOST_CHECK(it1->second->hasFaceId(1));
+ BOOST_CHECK(!it1->second->hasFaceId(2));
}
-BOOST_FIXTURE_TEST_CASE(LocalHopInherit, AuthorizedRibManager)
+BOOST_AUTO_TEST_CASE(OnNotification)
{
- using nfd::rib::RibManager;
+ auto parameters1 = makeRegisterParameters("/test-face-event-notification-1", 1);
+ auto parameters2 = makeRegisterParameters("/test-face-event-notification-2", 1);
+ receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1));
+ receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2));
+ BOOST_REQUIRE_EQUAL(m_rib.size(), 2);
- // Simulate NFD response
- ControlParameters result;
- result.setFaceId(261);
+ auto makeNotification = [] (ndn::nfd::FaceEventKind eventKind, uint64_t faceId) -> ndn::nfd::FaceEventNotification {
+ ndn::nfd::FaceEventNotification notification;
+ notification.setKind(eventKind).setFaceId(faceId);
+ return notification;
+ };
- manager->onNrdCommandPrefixAddNextHopSuccess(RibManager::REMOTE_COMMAND_PREFIX, result);
+ m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_DESTROYED, 1));
+ advanceClocks(time::milliseconds(100));
+ BOOST_CHECK_EQUAL(m_rib.size(), 0);
- // Register route that localhop prefix should inherit
- ControlParameters parameters;
- parameters
- .setName("/localhop/nfd")
- .setFaceId(262)
- .setCost(25)
- .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
-
- Name commandName("/localhost/nfd/rib/register");
-
- receiveCommandInterest(commandName, parameters);
-
- // REMOTE_COMMAND_PREFIX should have its original route and the inherited route
- auto it = manager->m_managedRib.find(RibManager::REMOTE_COMMAND_PREFIX);
-
- BOOST_REQUIRE(it != manager->m_managedRib.end());
- const RibEntry::RouteList& inheritedRoutes = (*(it->second)).getInheritedRoutes();
-
- BOOST_CHECK_EQUAL(inheritedRoutes.size(), 1);
- auto routeIt = inheritedRoutes.begin();
-
- BOOST_CHECK_EQUAL(routeIt->faceId, 262);
- BOOST_CHECK_EQUAL(routeIt->cost, 25);
+ m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_CREATED, 2));
+ advanceClocks(time::milliseconds(100));
+ BOOST_CHECK_EQUAL(m_rib.size(), 0);
}
-BOOST_FIXTURE_TEST_CASE(RouteExpiration, AuthorizedRibManager)
-{
- // Register route
- ControlParameters parameters;
- parameters.setName("/expire")
- .setExpirationPeriod(ndn::time::milliseconds(500));
+BOOST_AUTO_TEST_SUITE_END() // FaceMonitor
- receiveCommandInterest(REGISTER_COMMAND, parameters);
- face->sentInterests.clear();
-
- BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-
- // Route should expire
- advanceClocks(time::milliseconds(100), time::seconds(1));
-
- BOOST_CHECK_EQUAL(manager->m_managedRib.size(), 0);
-}
-
-BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, AuthorizedRibManager)
-{
- uint64_t faceToDestroy = 128;
-
- // Register valid face
- ControlParameters parameters;
- parameters.setName("/test")
- .setFaceId(faceToDestroy);
-
- receiveCommandInterest(REGISTER_COMMAND, parameters);
- BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
-
- // Don't respond with a success message from the FIB
- manager->m_managedRib.m_onSendBatchFromQueue = nullptr;
-
- manager->onFaceDestroyedEvent(faceToDestroy);
- BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestRibManager
+BOOST_AUTO_TEST_SUITE_END() // Rib
} // namespace tests
} // namespace rib