rib: reimplement auto prefix propagation based on readvertise
Change-Id: I6c4d81b829cf78084d26121c81d977d0a86c9a0c
Refs: #3819
diff --git a/rib/auto-prefix-propagator.cpp b/rib/auto-prefix-propagator.cpp
deleted file mode 100644
index a03302a..0000000
--- a/rib/auto-prefix-propagator.cpp
+++ /dev/null
@@ -1,482 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2018, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "auto-prefix-propagator.hpp"
-#include "core/logger.hpp"
-
-#include <ndn-cxx/security/pib/identity.hpp>
-#include <ndn-cxx/security/pib/identity-container.hpp>
-#include <ndn-cxx/security/pib/pib.hpp>
-#include <ndn-cxx/security/signing-helpers.hpp>
-
-namespace nfd {
-namespace rib {
-
-NFD_LOG_INIT(AutoPrefixPropagator);
-
-using ndn::nfd::ControlParameters;
-using ndn::nfd::CommandOptions;
-using ndn::util::scheduler::EventCallback;
-
-const Name LOCAL_REGISTRATION_PREFIX("/localhost");
-const Name LINK_LOCAL_NFD_PREFIX("/localhop/nfd");
-const name::Component IGNORE_COMMPONENT("nrd");
-const time::seconds PREFIX_PROPAGATION_DEFAULT_REFRESH_INTERVAL = time::seconds(25);
-const time::seconds PREFIX_PROPAGATION_MAX_REFRESH_INTERVAL = time::seconds(600);
-const time::seconds PREFIX_PROPAGATION_DEFAULT_BASE_RETRY_WAIT = time::seconds(50);
-const time::seconds PREFIX_PROPAGATION_DEFAULT_MAX_RETRY_WAIT = time::seconds(3600);
-const uint64_t PREFIX_PROPAGATION_DEFAULT_COST = 15;
-const time::milliseconds PREFIX_PROPAGATION_DEFAULT_TIMEOUT = time::milliseconds(10000);
-
-AutoPrefixPropagator::AutoPrefixPropagator(ndn::nfd::Controller& controller,
- ndn::KeyChain& keyChain,
- ndn::util::Scheduler& scheduler,
- Rib& rib)
- : m_nfdController(controller)
- , m_keyChain(keyChain)
- , m_scheduler(scheduler)
- , m_rib(rib)
- , m_refreshInterval(PREFIX_PROPAGATION_DEFAULT_REFRESH_INTERVAL)
- , m_baseRetryWait(PREFIX_PROPAGATION_DEFAULT_BASE_RETRY_WAIT)
- , m_maxRetryWait(PREFIX_PROPAGATION_DEFAULT_MAX_RETRY_WAIT)
- , m_hasConnectedHub(false)
-{
-}
-
-void
-AutoPrefixPropagator::loadConfig(const ConfigSection& configSection)
-{
- m_refreshInterval = PREFIX_PROPAGATION_DEFAULT_REFRESH_INTERVAL;
- m_baseRetryWait = PREFIX_PROPAGATION_DEFAULT_BASE_RETRY_WAIT;
- m_maxRetryWait = PREFIX_PROPAGATION_DEFAULT_MAX_RETRY_WAIT;
-
- m_controlParameters
- .setCost(PREFIX_PROPAGATION_DEFAULT_COST)
- .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT)// set origin to client.
- .setFaceId(0);// the remote hub will take the input face as the faceId.
-
- m_commandOptions
- .setPrefix(LINK_LOCAL_NFD_PREFIX)
- .setTimeout(PREFIX_PROPAGATION_DEFAULT_TIMEOUT);
-
- NFD_LOG_INFO("Load auto_prefix_propagate section in rib section");
-
- for (auto&& i : configSection) {
- if (i.first == "cost") {
- m_controlParameters.setCost(i.second.get_value<uint64_t>());
- }
- else if (i.first == "timeout") {
- m_commandOptions.setTimeout(time::milliseconds(i.second.get_value<size_t>()));
- }
- else if (i.first == "refresh_interval") {
- m_refreshInterval = std::min(PREFIX_PROPAGATION_MAX_REFRESH_INTERVAL,
- time::seconds(i.second.get_value<size_t>()));
- }
- else if (i.first == "base_retry_wait") {
- m_baseRetryWait = time::seconds(i.second.get_value<size_t>());
- }
- else if (i.first == "max_retry_wait") {
- m_maxRetryWait = time::seconds(i.second.get_value<size_t>());
- }
- else {
- BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i.first +
- "\" in \"auto_prefix_propagate\" section"));
- }
- }
-}
-
-void
-AutoPrefixPropagator::enable()
-{
- m_afterInsertConnection =
- m_rib.afterInsertEntry.connect(bind(&AutoPrefixPropagator::afterInsertRibEntry, this, _1));
- m_afterEraseConnection =
- m_rib.afterEraseEntry.connect(bind(&AutoPrefixPropagator::afterEraseRibEntry, this, _1));
-}
-
-void
-AutoPrefixPropagator::disable()
-{
- m_afterInsertConnection.disconnect();
- m_afterEraseConnection.disconnect();
-}
-
-AutoPrefixPropagator::PrefixPropagationParameters
-AutoPrefixPropagator::getPrefixPropagationParameters(const Name& localRibPrefix)
-{
- // shortest prefix matching to all identies.
- Name propagatedPrefix;
- ndn::security::pib::Identity signingIdentity;
- bool isFound = false;
- for (auto&& identity : m_keyChain.getPib().getIdentities()) {
- Name idName = identity.getName();
- Name prefix = !idName.empty() && IGNORE_COMMPONENT == idName.at(-1) ?
- idName.getPrefix(-1) : idName;
- if (prefix.isPrefixOf(localRibPrefix) && (!isFound || prefix.size() < propagatedPrefix.size())) {
- isFound = true;
- propagatedPrefix = prefix;
- signingIdentity = identity;
- }
- }
-
- PrefixPropagationParameters propagateParameters;
- if (!isFound) {
- propagateParameters.isValid = false;
- }
- else {
- propagateParameters.isValid = true;
- propagateParameters.parameters = m_controlParameters;
- propagateParameters.options = m_commandOptions;
- propagateParameters.parameters.setName(propagatedPrefix);
- propagateParameters.options.setSigningInfo(ndn::security::signingByIdentity(signingIdentity));
- }
-
- return propagateParameters;
-}
-
-void
-AutoPrefixPropagator::afterInsertRibEntry(const Name& prefix)
-{
- if (LOCAL_REGISTRATION_PREFIX.isPrefixOf(prefix)) {
- NFD_LOG_INFO("local registration only for " << prefix);
- return;
- }
-
- if (prefix == LINK_LOCAL_NFD_PREFIX) {
- NFD_LOG_INFO("this is a prefix registered by some hub: " << prefix);
-
- m_hasConnectedHub = true;
- return afterHubConnect();
- }
-
- auto propagateParameters = getPrefixPropagationParameters(prefix);
- if (!propagateParameters.isValid) {
- NFD_LOG_INFO("no signing identity available for: " << prefix);
- return;
- }
-
- auto entryIt = m_propagatedEntries.find(propagateParameters.parameters.getName());
- if (entryIt != m_propagatedEntries.end()) {
- // in addition to PROPAGATED and PROPAGATE_FAIL, the state may also be NEW,
- // if there is no hub connected to propagate this prefix.
- if (entryIt->second.isNew()) {
- NFD_LOG_INFO("no hub connected to propagate "
- << propagateParameters.parameters.getName());
- }
- else {
- NFD_LOG_INFO("prefix has already been propagated: "
- << propagateParameters.parameters.getName());
- }
- return;
- }
-
- afterRibInsert(propagateParameters.parameters, propagateParameters.options);
-}
-
-void
-AutoPrefixPropagator::afterEraseRibEntry(const Name& prefix)
-{
- if (LOCAL_REGISTRATION_PREFIX.isPrefixOf(prefix)) {
- NFD_LOG_INFO("local unregistration only for " << prefix);
- return;
- }
-
- if (prefix == LINK_LOCAL_NFD_PREFIX) {
- NFD_LOG_INFO("disconnected to hub with prefix: " << prefix);
-
- m_hasConnectedHub = false;
- return afterHubDisconnect();
- }
-
- auto propagateParameters = getPrefixPropagationParameters(prefix);
- if (!propagateParameters.isValid) {
- NFD_LOG_INFO("no signing identity available for: " << prefix);
- return;
- }
-
- auto entryIt = m_propagatedEntries.find(propagateParameters.parameters.getName());
- if (entryIt == m_propagatedEntries.end()) {
- NFD_LOG_INFO("prefix has not been propagated yet: "
- << propagateParameters.parameters.getName());
- return;
- }
-
- for (auto&& ribTableEntry : m_rib) {
- if (propagateParameters.parameters.getName().isPrefixOf(ribTableEntry.first) &&
- propagateParameters.options.getSigningInfo().getSignerName() ==
- getPrefixPropagationParameters(ribTableEntry.first)
- .options.getSigningInfo().getSignerName()) {
- NFD_LOG_INFO("should be kept for another RIB entry: " << ribTableEntry.first);
- return;
- }
- }
-
- afterRibErase(propagateParameters.parameters.unsetCost(), propagateParameters.options);
-}
-
-bool
-AutoPrefixPropagator::doesCurrentPropagatedPrefixWork(const Name& prefix)
-{
- auto propagateParameters = getPrefixPropagationParameters(prefix);
- if (!propagateParameters.isValid) {
- // no identity can sign the input prefix
- return false;
- }
-
- // there is at least one identity can sign the input prefix, so the prefix selected for
- // propagation (i.e., propagateParameters.parameters.getName()) must be a prefix of the input
- // prefix. Namely it's either equal to the input prefix or a better choice.
- return propagateParameters.parameters.getName().size() == prefix.size();
-}
-
-void
-AutoPrefixPropagator::redoPropagation(PropagatedEntryIt entryIt,
- const ControlParameters& parameters,
- const CommandOptions& options,
- time::seconds retryWaitTime)
-{
- if (doesCurrentPropagatedPrefixWork(parameters.getName())) {
- // PROPAGATED / PROPAGATE_FAIL --> PROPAGATING
- entryIt->second.startPropagation();
- return advertise(parameters, options, retryWaitTime);
- }
-
- NFD_LOG_INFO("current propagated prefix does not work any more");
- m_propagatedEntries.erase(entryIt);
-
- // re-handle all locally RIB entries that can be covered by this propagated prefix
- for (auto&& ribTableEntry : m_rib) {
- if (parameters.getName().isPrefixOf(ribTableEntry.first)) {
- afterInsertRibEntry(ribTableEntry.first);
- }
- }
-}
-
-void
-AutoPrefixPropagator::advertise(const ControlParameters& parameters,
- const CommandOptions& options,
- time::seconds retryWaitTime)
-{
- NFD_LOG_INFO("advertise " << parameters.getName());
-
- EventCallback refreshEvent =
- bind(&AutoPrefixPropagator::onRefreshTimer, this, parameters, options);
- EventCallback retryEvent =
- bind(&AutoPrefixPropagator::onRetryTimer, this, parameters, options,
- std::min(m_maxRetryWait, retryWaitTime * 2));
-
- m_nfdController.start<ndn::nfd::RibRegisterCommand>(
- parameters,
- bind(&AutoPrefixPropagator::afterPropagateSucceed, this, parameters, options, refreshEvent),
- bind(&AutoPrefixPropagator::afterPropagateFail,
- this, _1, parameters, options, retryWaitTime, retryEvent),
- options);
-}
-
-void
-AutoPrefixPropagator::withdraw(const ControlParameters& parameters,
- const CommandOptions& options,
- time::seconds retryWaitTime)
-{
- NFD_LOG_INFO("withdraw " << parameters.getName());
-
- m_nfdController.start<ndn::nfd::RibUnregisterCommand>(
- parameters,
- bind(&AutoPrefixPropagator::afterRevokeSucceed, this, parameters, options, retryWaitTime),
- bind(&AutoPrefixPropagator::afterRevokeFail, this, _1, parameters, options),
- options);
-}
-
-void
-AutoPrefixPropagator::afterRibInsert(const ControlParameters& parameters,
- const CommandOptions& options)
-{
- BOOST_ASSERT(m_propagatedEntries.find(parameters.getName()) == m_propagatedEntries.end());
-
- // keep valid entries although there is no connectivity to hub
- auto& entry = m_propagatedEntries[parameters.getName()]
- .setSigningIdentity(options.getSigningInfo().getSignerName());
-
- if (!m_hasConnectedHub) {
- NFD_LOG_INFO("no hub connected to propagate " << parameters.getName());
- return;
- }
-
- // NEW --> PROPAGATING
- entry.startPropagation();
- advertise(parameters, options, m_baseRetryWait);
-}
-
-void
-AutoPrefixPropagator::afterRibErase(const ControlParameters& parameters,
- const CommandOptions& options)
-{
- auto entryIt = m_propagatedEntries.find(parameters.getName());
- BOOST_ASSERT(entryIt != m_propagatedEntries.end());
-
- bool hasPropagationSucceeded = entryIt->second.isPropagated();
-
- // --> "RELEASED"
- m_propagatedEntries.erase(entryIt);
-
- if (!m_hasConnectedHub) {
- NFD_LOG_INFO("no hub connected to revoke propagation of " << parameters.getName());
- return;
- }
-
- if (!hasPropagationSucceeded) {
- NFD_LOG_INFO("propagation has not succeeded: " << parameters.getName());
- return;
- }
-
- withdraw(parameters, options, m_baseRetryWait);
-}
-
-void
-AutoPrefixPropagator::afterHubConnect()
-{
- NFD_LOG_INFO("redo " << m_propagatedEntries.size()
- << " propagations when new Hub connectivity is built.");
-
- std::vector<PropagatedEntryIt> regEntryIterators;
- for (auto it = m_propagatedEntries.begin() ; it != m_propagatedEntries.end() ; it ++) {
- BOOST_ASSERT(it->second.isNew());
- regEntryIterators.push_back(it);
- }
-
- for (auto&& it : regEntryIterators) {
- auto parameters = m_controlParameters;
- auto options = m_commandOptions;
-
- redoPropagation(it,
- parameters.setName(it->first),
- options.setSigningInfo(signingByIdentity(it->second.getSigningIdentity())),
- m_baseRetryWait);
- }
-}
-
-void
-AutoPrefixPropagator::afterHubDisconnect()
-{
- for (auto&& entry : m_propagatedEntries) {
- // --> NEW
- BOOST_ASSERT(!entry.second.isNew());
- entry.second.initialize();
- }
-}
-
-void
-AutoPrefixPropagator::afterPropagateSucceed(const ControlParameters& parameters,
- const CommandOptions& options,
- const EventCallback& refreshEvent)
-{
- NFD_LOG_TRACE("success to propagate " << parameters.getName());
-
- auto entryIt = m_propagatedEntries.find(parameters.getName());
- if (entryIt == m_propagatedEntries.end()) {
- // propagation should be revoked if this entry has been erased (i.e., be in RELEASED state)
- NFD_LOG_DEBUG("Already erased!");
- ControlParameters newParameters = parameters;
- return withdraw(newParameters.unsetCost(), options, m_baseRetryWait);
- }
-
- // PROPAGATING --> PROPAGATED
- BOOST_ASSERT(entryIt->second.isPropagating());
- entryIt->second.succeed(m_scheduler, m_scheduler.scheduleEvent(m_refreshInterval, refreshEvent));
-}
-
-void
-AutoPrefixPropagator::afterPropagateFail(const ndn::nfd::ControlResponse& response,
- const ControlParameters& parameters,
- const CommandOptions& options,
- time::seconds retryWaitTime,
- const EventCallback& retryEvent)
-{
- NFD_LOG_TRACE("fail to propagate " << parameters.getName()
- << "\n\t reason:" << response.getText()
- << "\n\t retry wait time: " << retryWaitTime);
-
- auto entryIt = m_propagatedEntries.find(parameters.getName());
- if (entryIt == m_propagatedEntries.end()) {
- // current state is RELEASED
- return;
- }
-
- // PROPAGATING --> PROPAGATE_FAIL
- BOOST_ASSERT(entryIt->second.isPropagating());
- entryIt->second.fail(m_scheduler, m_scheduler.scheduleEvent(retryWaitTime, retryEvent));
-}
-
-void
-AutoPrefixPropagator::afterRevokeSucceed(const ControlParameters& parameters,
- const CommandOptions& options,
- time::seconds retryWaitTime)
-{
- NFD_LOG_TRACE("success to revoke propagation of " << parameters.getName());
-
- auto entryIt = m_propagatedEntries.find(parameters.getName());
- if (m_propagatedEntries.end() != entryIt && !entryIt->second.isPropagateFail()) {
- // if is not RELEASED or PROPAGATE_FAIL
- NFD_LOG_DEBUG("propagated entry still exists");
-
- // PROPAGATING / PROPAGATED --> PROPAGATING
- BOOST_ASSERT(!entryIt->second.isNew());
- entryIt->second.startPropagation();
-
- ControlParameters newParameters = parameters;
- advertise(newParameters.setCost(m_controlParameters.getCost()), options, retryWaitTime);
- }
-}
-
-void
-AutoPrefixPropagator::afterRevokeFail(const ndn::nfd::ControlResponse& response,
- const ControlParameters& parameters,
- const CommandOptions& options)
-{
- NFD_LOG_INFO("fail to revoke the propagation of " << parameters.getName()
- << "\n\t reason:" << response.getText());
-}
-
-void
-AutoPrefixPropagator::onRefreshTimer(const ControlParameters& parameters,
- const CommandOptions& options)
-{
- auto entryIt = m_propagatedEntries.find(parameters.getName());
- BOOST_ASSERT(entryIt != m_propagatedEntries.end() && entryIt->second.isPropagated());
- redoPropagation(entryIt, parameters, options, m_baseRetryWait);
-}
-
-void
-AutoPrefixPropagator::onRetryTimer(const ControlParameters& parameters,
- const CommandOptions& options,
- time::seconds retryWaitTime)
-{
- auto entryIt = m_propagatedEntries.find(parameters.getName());
- BOOST_ASSERT(entryIt != m_propagatedEntries.end() && entryIt->second.isPropagateFail());
- redoPropagation(entryIt, parameters, options, retryWaitTime);
-}
-
-} // namespace rib
-} // namespace nfd
diff --git a/rib/auto-prefix-propagator.hpp b/rib/auto-prefix-propagator.hpp
deleted file mode 100644
index 802a105..0000000
--- a/rib/auto-prefix-propagator.hpp
+++ /dev/null
@@ -1,418 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2018, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_RIB_AUTO_PREFIX_PROPAGATOR_HPP
-#define NFD_RIB_AUTO_PREFIX_PROPAGATOR_HPP
-
-#include "propagated-entry.hpp"
-#include "rib.hpp"
-#include "core/config-file.hpp"
-
-#include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/mgmt/nfd/controller.hpp>
-#include <ndn-cxx/mgmt/nfd/control-command.hpp>
-#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
-#include <ndn-cxx/mgmt/nfd/command-options.hpp>
-#include <ndn-cxx/util/scheduler.hpp>
-#include <ndn-cxx/util/signal.hpp>
-
-namespace nfd {
-namespace rib {
-
-/** @brief provides automatic prefix propagation feature
- *
- * The AutoPrefixPropagator monitors changes to local RIB, and registers prefixes onto a
- * connected gateway router (HUB), so that Interests under propagated prefixes will be forwarded
- * toward the local host by the HUB.
- *
- * The route origin of propagated prefix is CLIENT, as shown on the HUB.
- *
- * Connectivity to a HUB is indicated with a special RIB entry "ndn:/localhop/nfd".
- * Currently, the AutoPrefixPropagator can process the connection to at most one HUB.
- *
- * For every RIB entry except "ndn:/localhop/nfd" and those starting with "ndn:/localhost", the
- * AutoPrefixPropagator queries the local KeyChain for signing identities that is authorized
- * to sign a prefix registration command of a prefix of the RIB prefix.
- *
- * If one or more signing identities are found, the identity that can sign a prefix registration
- * command of the shortest prefix is chosen, and the AutoPrefixPropagator will attempt to
- * propagte a prefix to the HUB using the shortest prefix. It's noteworthy that no route flags will
- * be inherited from the local registration.
- * If no signing identity is available, no prefix of the RIB entry is propagated to the HUB.
- *
- * When a RIB entry is erased, the corresponding propagated entry would be revoked,
- * unless another local RIB entry is causing the propagation of that prefix.
- *
- * After a successful propagation, the AutoPrefixPropagator will refresh the propagation
- * periodically by resending the registration command.
- *
- * In case of a failure or timeout in a registration command, the command will be retried with an
- * exponential back-off strategy.
- *
- * The AutoPrefixPropagator can be configured in NFD configuration file, at the
- * rib.auto_prefix_propagate section.
- */
-class AutoPrefixPropagator : noncopyable
-{
-public:
- class Error : public std::runtime_error
- {
- public:
- explicit
- Error(const std::string& what)
- : std::runtime_error(what)
- {
- }
- };
-
- AutoPrefixPropagator(ndn::nfd::Controller& controller,
- ndn::KeyChain& keyChain,
- ndn::util::Scheduler& scheduler,
- Rib& rib);
- /**
- * @brief load the "auto_prefix_propagate" section from config file
- *
- * @param configSection the sub section in "rib" section.
- */
- void
- loadConfig(const ConfigSection& configSection);
-
- /**
- * @brief enable automatic prefix propagation
- */
- void
- enable();
-
- /**
- * @brief disable automatic prefix propagation
- */
- void
- disable();
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers
- /**
- * When a local RIB prefix triggers prefix propagation, we propagate the shortest identity that
- * can sign this prefix to the HUB.
- *
- * Thus, the propagated prefix does not equal to local RIB prefix.
- * So it needs separate storage instead of storing within the RIB.
- *
- * the propagated prefix is used as the key to retrive the corresponding entry.
- */
- typedef std::unordered_map<Name, PropagatedEntry> PropagatedEntryList;
- typedef PropagatedEntryList::iterator PropagatedEntryIt;
-
- /**
- * @brief parameters used by the registration commands for prefix propagation
- *
- * consists of a ControlParameters and a CommandOptions, as well as a bool variable indicates
- * whether this set of parameters is valid (i.e., the signing identity exists)
- */
- struct PrefixPropagationParameters
- {
- bool isValid;
- ndn::nfd::ControlParameters parameters;
- ndn::nfd::CommandOptions options;
- };
-
- /**
- * @brief get the required parameters for prefix propagation.
- *
- * given a local RIB prefix @p localRibPrefix, find out, in local KeyChain, a proper identity
- * whose namespace covers the input prefix. If there is no desired identity, return a invalid
- * PrefixPropagationParameters.
- *
- * Otherwise, set the selected identity as the signing identity in CommandOptions. Meanwhile,
- * set this identity (or its prefix with the last component eliminated if it ends with "nrd")
- * as the name of ControlParameters.
- *
- * @return the PrefixPropagationParameters.
- */
- PrefixPropagationParameters
- getPrefixPropagationParameters(const Name& localRibPrefix);
-
- /**
- * @brief check whether current propagated prefix still works
- *
- * the current propagated prefix @p prefix will still work if and only if its corresponding
- * signing identity still exists and there is no better signing identity covering it.
- *
- * @return true if current propagated prefix still works, otherwise false
- */
- bool
- doesCurrentPropagatedPrefixWork(const Name& prefix);
-
- /**
- * @brief process re-propagation for the given propagated entry
- *
- * This function may be invoked in 3 cases:
- * 1. After the hub is connected to redo some propagations.
- * 2. On refresh timer to handle refresh requests.
- * 3. On retry timer to handle retry requests.
- *
- * @param entryIt the propagated entry need to do re-propagation
- * @param parameters the ControlParameters used by registration commands for propagation
- * @param options the CommandOptions used for registration commands for propagation
- * @param retryWaitTime the current wait time before retrying propagation
- */
- void
- redoPropagation(PropagatedEntryIt entryIt,
- const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options,
- time::seconds retryWaitTime);
-
-private:
- /**
- * @brief send out the registration command for propagation
- *
- * Before sending out the command, two events, for refresh and retry respectively, are
- * established (but not scheduled) and assigned to two callbacks, afterPropagateSucceed and
- * afterPropagateFail respectively.
- *
- * The retry event requires an argument to define the retry wait time, which is calculated
- * according to the back-off policy based on current retry wait time @p retryWaitTime and the
- * maxRetryWait.
- *
- * The baseRetryWait and maxRetryWait used in back-off strategy are all configured at
- * rib.auto_prefix_propagate.base_retry_wait and
- * rib.auto_prefix_propagate.max_retry_wait respectively
-
- * @param parameters the ControlParameters used by the registration command for propagation
- * @param options the CommandOptions used by the registration command for propagation
- * @param retryWaitTime the current wait time before retrying propagation
- */
- void
- advertise(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options,
- time::seconds retryWaitTime);
-
- /**
- * @brief send out the unregistration command to revoke the corresponding propagation.
- *
- * @param parameters the ControlParameters used by the unregistration command for revocation
- * @param options the CommandOptions used by the unregistration command for revocation
- * @param retryWaitTime the current wait time before retrying propagation
- */
- void
- withdraw(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options,
- time::seconds retryWaitTime);
-
- /**
- * @brief invoked when Rib::afterInsertEntry signal is emitted
- *
- * step1: if the local RIB prefix @param prefix is for local use only, return
- * step2: if the local RIB prefix @param prefix is a hub prefix, invoke afterHubConnect
- * step3: if no valid PrefixPropagationParameters can be found for the local RIB prefix
- * @param prefix, or the propagated prefix has already been processed, return
- * step4: invoke afterRibInsert
- */
- void
- afterInsertRibEntry(const Name& prefix);
-
- /**
- * @brief invoked when Rib::afterEraseEntry signal is emitted
- *
- * step1: if local RIB prefix @param prefix is for local use only, return
- * step2: if local RIB prefix @param prefix is a hub prefix, invoke afterHubDisconnect
- * step3: if no valid PrefixPropagationParameters can be found for local RIB prefix
- * @param prefix, or there are other local RIB prefixes can be covered by the propagated
- * prefix, return
- * step4: invoke afterRibErase
- */
- void
- afterEraseRibEntry(const Name& prefix);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE: // PropagatedEntry state changes
- /**
- * @brief invoked after rib insertion for non-hub prefixes
- * @pre the PropagatedEntry is in RELEASED state
- * @post the PropagatedEntry will be in NEW state
- *
- * @param parameters the ControlParameters used by registration commands for propagation
- * @param options the CommandOptions used by registration commands for propagation
- */
- void
- afterRibInsert(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options);
-
- /**
- * @brief invoked after rib deletion for non-hub prefixes
- * @pre the PropagatedEntry is not in RELEASED state
- * @post the PropagatedEntry will be in RELEASED state
- *
- * @param parameters the ControlParameters used by registration commands for propagation
- * @param options the CommandOptions used by registration commands for propagation
- */
- void
- afterRibErase(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options);
-
- /**
- * @brief invoked after the hub is connected
- * @pre the PropagatedEntry is in NEW state or RELEASED state
- * @post the PropagatedEntry will be in PROPAGATING state or keep in RELEASED state
- *
- * call redoPropagation for each propagated entry.
- */
- void
- afterHubConnect();
-
- /**
- * @brief invoked after the hub is disconnected
- * @pre the PropagatedEntry is not in NEW state
- * @post the PropagatedEntry will be in NEW state or keep in RELEASED state
- *
- * for each propagated entry, switch its state to NEW and cancel its event.
- */
- void
- afterHubDisconnect();
-
- /**
- * @brief invoked after propagation succeeds
- * @pre the PropagatedEntry is in PROPAGATING state or RELEASED state
- * @post the PropagatedEntry will be in PROPAGATED state or keep in RELEASED state
- *
- * If the PropagatedEntry does not exist (in RELEASED state), an unregistration command is
- * sent immediately for revocation.
- *
- * If the PropagatedEntry is in PROPAGATING state, switch it to PROPAGATED, and schedule a
- * refresh timer to redo propagation after a duration, which is configured at
- * rib.auto_prefix_propagate.refresh_interval.
- *
- * Otherwise, make a copy of the ControlParameters @p parameters, unset its Cost field, and then
- * invoke withdraw with this new ControlParameters.
- *
- * @param parameters the ControlParameters used by the registration command for propagation
- * @param options the CommandOptions used by the registration command for propagation
- * @param refreshEvent the event of refreshing propagation
- */
- void
- afterPropagateSucceed(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options,
- const ndn::util::scheduler::EventCallback& refreshEvent);
-
- /**
- * @brief invoked after propagation fails.
- * @pre the PropagatedEntry is in PROPAGATING state or RELEASED state
- * @post the PropagatedEntry will be in PROPAGATE_FAIL state or keep in RELEASED state
- *
- * If the PropagatedEntry still exists, schedule a retry timer to redo propagation
- * after a duration defined by current retry time @p retryWaitTime
- *
- * @param response ControlResponse from remote NFD-RIB
- * @param parameters the ControlParameters used by the registration command for propagation
- * @param options the CommandOptions used by registration command for propagation
- * @param retryWaitTime the current wait time before retrying propagation
- * @param retryEvent the event of retrying propagation
- */
- void
- afterPropagateFail(const ndn::nfd::ControlResponse& response,
- const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options,
- time::seconds retryWaitTime,
- const ndn::util::scheduler::EventCallback& retryEvent);
-
- /**
- * @brief invoked after revocation succeeds
- * @pre the PropagatedEntry is not in NEW state
- * @post the PropagatedEntry will be in PROPAGATING state, or keep in PROPAGATE_FAIL state,
- * or keep in RELEASED state
- *
- * If the PropagatedEntry still exists and is not in PROPAGATE_FAIL state, switch it to
- * PROPAGATING. Then make a copy of the ControlParameters @p parameters, reset its Cost, and
- * invoke advertise with this new ControlParameters.
- *
- * @param parameters the ControlParameters used by the unregistration command for revocation
- * @param options the CommandOptions used by the unregistration command for revocation
- * @param retryWaitTime the current wait time before retrying propagation
- */
- void
- afterRevokeSucceed(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options,
- time::seconds retryWaitTime);
-
- /**
- * @brief invoked after revocation fails.
- *
- * @param response ControlResponse from remote NFD-RIB
- * @param parameters the ControlParameters used by the unregistration command for revocation
- * @param options the CommandOptions used by the unregistration command for revocation
- */
- void
- afterRevokeFail(const ndn::nfd::ControlResponse& response,
- const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options);
-
- /**
- * @brief invoked when the refresh timer is triggered.
- * @pre the PropagatedEntry is in PROPAGATED state
- * @post the PropagatedEntry will be in PROPAGATING state
- *
- * call redoPropagation to handle this refresh request
- *
- * @param parameters the ControlParameters used by registration commands for propagation
- * @param options the CommandOptions used by registration commands for propagation
- */
- void
- onRefreshTimer(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options);
-
- /**
- * @brief invoked when the retry timer is triggered.
- * @pre the PropagatedEntry is in PROPAGATE_FAIL state
- * @post the PropagatedEntry will be in PROPAGATING state
- *
- * call redoPropagation to handle this retry request
- *
- * @param parameters the ControlParameters used by registration commands for propagation
- * @param options the CommandOptions used by registration commands for propagation
- * @param retryWaitTime the current wait time before retrying propagation
- */
- void
- onRetryTimer(const ndn::nfd::ControlParameters& parameters,
- const ndn::nfd::CommandOptions& options,
- time::seconds retryWaitTime);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- ndn::nfd::Controller& m_nfdController;
- ndn::KeyChain& m_keyChain;
- ndn::util::Scheduler& m_scheduler;
- Rib& m_rib;
- ndn::util::signal::ScopedConnection m_afterInsertConnection;
- ndn::util::signal::ScopedConnection m_afterEraseConnection;
- ndn::nfd::ControlParameters m_controlParameters;
- ndn::nfd::CommandOptions m_commandOptions;
- time::seconds m_refreshInterval;
- time::seconds m_baseRetryWait;
- time::seconds m_maxRetryWait;
- bool m_hasConnectedHub;
- PropagatedEntryList m_propagatedEntries;
-};
-
-} // namespace rib
-} // namespace nfd
-
-#endif // NFD_RIB_AUTO_PREFIX_PROPAGATOR_HPP
diff --git a/rib/propagated-entry.cpp b/rib/propagated-entry.cpp
deleted file mode 100644
index 34a8976..0000000
--- a/rib/propagated-entry.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2018, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "propagated-entry.hpp"
-
-namespace nfd {
-namespace rib {
-
-void
-operator<<(std::ostream& out, PropagationStatus status)
-{
- switch (status) {
- case PropagationStatus::NEW:
- out << "NEW";
- break;
- case PropagationStatus::PROPAGATING:
- out << "PROPAGATING";
- break;
- case PropagationStatus::PROPAGATED:
- out << "PROPAGATED";
- break;
- case PropagationStatus::PROPAGATE_FAIL:
- out << "PROPAGATE_FAIL";
- break;
- default:
- out << "undefined status";
- break;
- }
-}
-
-PropagatedEntry::PropagatedEntry(const PropagatedEntry& other)
- : m_signingIdentity(other.m_signingIdentity)
- , m_propagationStatus(other.m_propagationStatus)
-{
- BOOST_ASSERT(!other.isPropagated() && !other.isPropagateFail());
-}
-
-PropagatedEntry&
-PropagatedEntry::setSigningIdentity(const Name& identity)
-{
- m_signingIdentity = identity;
- return *this;
-}
-
-const Name&
-PropagatedEntry::getSigningIdentity() const
-{
- return m_signingIdentity;
-}
-
-void
-PropagatedEntry::startPropagation()
-{
- m_propagationStatus = PropagationStatus::PROPAGATING;
-}
-
-void
-PropagatedEntry::succeed(ndn::util::Scheduler& scheduler, const ndn::util::scheduler::EventId& event)
-{
- m_propagationStatus = PropagationStatus::PROPAGATED;
- m_rePropagateEvent = ndn::util::scheduler::ScopedEventId(scheduler);
- *m_rePropagateEvent = event;
-}
-
-void
-PropagatedEntry::fail(ndn::util::Scheduler& scheduler, const ndn::util::scheduler::EventId& event)
-{
- m_propagationStatus = PropagationStatus::PROPAGATE_FAIL;
- m_rePropagateEvent = ndn::util::scheduler::ScopedEventId(scheduler);
- *m_rePropagateEvent = event;
-}
-
-void
-PropagatedEntry::initialize()
-{
- m_propagationStatus = PropagationStatus::NEW;
- if (m_rePropagateEvent)
- m_rePropagateEvent->cancel();
-}
-
-bool
-PropagatedEntry::isNew() const
-{
- return PropagationStatus::NEW == m_propagationStatus;
-}
-
-bool
-PropagatedEntry::isPropagating() const
-{
- return PropagationStatus::PROPAGATING == m_propagationStatus;
-}
-
-bool
-PropagatedEntry::isPropagated() const
-{
- return PropagationStatus::PROPAGATED == m_propagationStatus;
-}
-
-bool
-PropagatedEntry::isPropagateFail() const
-{
- return PropagationStatus::PROPAGATE_FAIL == m_propagationStatus;
-}
-
-} // namespace rib
-} // namespace nfd
diff --git a/rib/propagated-entry.hpp b/rib/propagated-entry.hpp
deleted file mode 100644
index c4b0601..0000000
--- a/rib/propagated-entry.hpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2018, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_RIB_PROPAGATED_ENTRY_HPP
-#define NFD_RIB_PROPAGATED_ENTRY_HPP
-
-#include "core/common.hpp"
-
-#include <ndn-cxx/util/scheduler-scoped-event-id.hpp>
-
-namespace nfd {
-namespace rib {
-
-enum class PropagationStatus {
- /// initial status
- NEW,
- /// is being propagated
- PROPAGATING,
- /// has been propagated successfully
- PROPAGATED,
- /// has failed in propagation
- PROPAGATE_FAIL
-};
-
-void
-operator<<(std::ostream& out, PropagationStatus status);
-
-/**
- * @brief represents an entry for prefix propagation.
- *
- * it consists of a PropagationStatus indicates current state of the state machine, as
- * well as an event scheduled for refresh or retry (i.e., the RefreshTimer and the RetryTimer of
- * the state machine respectively). Besides, it stores a copy of signing identity for this entry.
- */
-class PropagatedEntry
-{
-public:
- PropagatedEntry() = default;
-
- /**
- * @pre other is not in PROPAGATED or PROPAGATE_FAIL state
- */
- PropagatedEntry(const PropagatedEntry& other);
-
- PropagatedEntry&
- operator=(const PropagatedEntry& other) = delete;
-
- /**
- * @brief set the signing identity
- */
- PropagatedEntry&
- setSigningIdentity(const Name& identity);
-
- /**
- * @brief get the signing identity
- *
- * @return the signing identity
- */
- const Name&
- getSigningIdentity() const;
-
- /**
- * @brief switch the propagation status to PROPAGATING.
- *
- * this is called before start the propagation process of this entry.
- */
- void
- startPropagation();
-
- /**
- * @brief switch the propagation status to PROPAGATED, and set the
- * rePropagateEvent to @p event for refresh.
- *
- * this is called just after this entry is successfully propagated.
- */
- void
- succeed(ndn::util::Scheduler& scheduler, const ndn::util::scheduler::EventId& event);
-
- /**
- * @brief switch the propagation status to PROPAGATE_FAIL, and then set the
- * rePropagateEvent to @p event for retry.
- *
- * this is called just after propagation for this entry fails.
- */
- void
- fail(ndn::util::Scheduler& scheduler, const ndn::util::scheduler::EventId& event);
-
- /**
- * @brief cancel the events of re-sending propagation commands.
- *
- * switch the propagation status to NEW.
- */
- void
- initialize();
-
- /**
- * @brief check whether this entry is a new entry.
- *
- * @return true if current status is NEW.
- */
- bool
- isNew() const;
-
- /**
- * @brief check whether this entry is being propagated.
- *
- * @return true if current status is PROPAGATING.
- */
- bool
- isPropagating() const;
-
- /**
- * @brief check whether this entry has been successfully propagated.
- *
- * @return true if current status is PROPAGATED.
- */
- bool
- isPropagated() const;
-
- /**
- * @brief check whether this entry has failed in propagating.
- *
- * @return true if current status is PROPAGATE_FAIL.
- */
- bool
- isPropagateFail() const;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- Name m_signingIdentity;
- optional<ndn::util::scheduler::ScopedEventId> m_rePropagateEvent;
- PropagationStatus m_propagationStatus = PropagationStatus::NEW;
-};
-
-} // namespace rib
-} // namespace nfd
-
-#endif // NFD_RIB_PROPAGATED_ENTRY_HPP
diff --git a/rib/readvertise/host-to-gateway-readvertise-policy.cpp b/rib/readvertise/host-to-gateway-readvertise-policy.cpp
new file mode 100644
index 0000000..2d508f8
--- /dev/null
+++ b/rib/readvertise/host-to-gateway-readvertise-policy.cpp
@@ -0,0 +1,91 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "host-to-gateway-readvertise-policy.hpp"
+#include "core/scope-prefix.hpp"
+#include "rib/rib-manager.hpp"
+
+#include <ndn-cxx/security/pib/identity.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+
+namespace nfd {
+namespace rib {
+
+static const name::Component IGNORE_COMPONENT("nrd");
+static const time::seconds DEFAULT_REFRESH_INTERVAL = 25_s;
+
+HostToGatewayReadvertisePolicy::HostToGatewayReadvertisePolicy(const ndn::KeyChain& keyChain,
+ const ConfigSection& section)
+ : m_keyChain(keyChain)
+{
+ auto interval = section.get_optional<uint64_t>("refresh_interval");
+ m_refreshInterval = interval ? time::seconds(*interval) : DEFAULT_REFRESH_INTERVAL;
+}
+
+optional<ReadvertiseAction>
+HostToGatewayReadvertisePolicy::handleNewRoute(const RibRouteRef& ribRoute) const
+{
+ auto ribEntryName = ribRoute.entry->getName();
+ if (scope_prefix::LOCALHOST.isPrefixOf(ribEntryName) ||
+ ribEntryName == RibManager::LOCALHOP_TOP_PREFIX) {
+ return nullopt;
+ }
+
+ // find out the shortest identity whose name is a prefix of the RIB entry name
+ auto prefixToAdvertise = ribEntryName;
+ ndn::security::pib::Identity signingIdentity;
+ bool isFound = false;
+
+ for (const auto& identity : m_keyChain.getPib().getIdentities()) {
+ auto prefix = identity.getName();
+
+ // ignore the identity name's last component if it is "nrd"
+ if (!prefix.empty() && IGNORE_COMPONENT == prefix.at(-1)) {
+ prefix = prefix.getPrefix(-1);
+ }
+
+ if (prefix.isPrefixOf(prefixToAdvertise)) {
+ isFound = true;
+ prefixToAdvertise = prefix;
+ signingIdentity = identity;
+ }
+ }
+
+ if (isFound) {
+ return ReadvertiseAction{prefixToAdvertise, ndn::security::signingByIdentity(signingIdentity)};
+ }
+ else {
+ return nullopt;
+ }
+}
+
+time::milliseconds
+HostToGatewayReadvertisePolicy::getRefreshInterval() const
+{
+ return m_refreshInterval;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/rib/readvertise/host-to-gateway-readvertise-policy.hpp b/rib/readvertise/host-to-gateway-readvertise-policy.hpp
new file mode 100644
index 0000000..a2961b3
--- /dev/null
+++ b/rib/readvertise/host-to-gateway-readvertise-policy.hpp
@@ -0,0 +1,60 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_RIB_READVERTISE_HOST_TO_GATEWAY_READVERTISE_POLICY_HPP
+#define NFD_RIB_READVERTISE_HOST_TO_GATEWAY_READVERTISE_POLICY_HPP
+
+#include "readvertise-policy.hpp"
+#include "core/config-file.hpp"
+
+#include <ndn-cxx/security/key-chain.hpp>
+
+namespace nfd {
+namespace rib {
+
+/** \brief a policy to readvertise routes registered by local applications into remote gateway
+ */
+class HostToGatewayReadvertisePolicy : public ReadvertisePolicy
+{
+public:
+ HostToGatewayReadvertisePolicy(const ndn::KeyChain& keyChain,
+ const ConfigSection& section);
+
+public:
+ optional<ReadvertiseAction>
+ handleNewRoute(const RibRouteRef& ribRoute) const override;
+
+ time::milliseconds
+ getRefreshInterval() const override;
+
+private:
+ const ndn::KeyChain& m_keyChain;
+ time::seconds m_refreshInterval;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_RIB_READVERTISE_HOST_TO_GATEWAY_READVERTISE_POLICY_HPP
diff --git a/rib/readvertise/nfd-rib-readvertise-destination.cpp b/rib/readvertise/nfd-rib-readvertise-destination.cpp
index 530a9d4..f0a0482 100644
--- a/rib/readvertise/nfd-rib-readvertise-destination.cpp
+++ b/rib/readvertise/nfd-rib-readvertise-destination.cpp
@@ -26,9 +26,7 @@
#include "nfd-rib-readvertise-destination.hpp"
#include "core/logger.hpp"
-#include <ndn-cxx/mgmt/nfd/command-options.hpp>
#include <ndn-cxx/mgmt/nfd/control-command.hpp>
-#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
namespace nfd {
@@ -36,15 +34,15 @@
NFD_LOG_INIT(NfdRibReadvertiseDestination);
-using ndn::nfd::CommandOptions;
-using ndn::nfd::ControlParameters;
using ndn::nfd::ControlResponse;
NfdRibReadvertiseDestination::NfdRibReadvertiseDestination(ndn::nfd::Controller& controller,
- const Name& commandPrefix,
- Rib& rib)
+ Rib& rib,
+ const ndn::nfd::CommandOptions& options,
+ const ndn::nfd::ControlParameters& parameters)
: m_controller(controller)
- , m_commandPrefix(commandPrefix)
+ , m_commandOptions(options)
+ , m_controlParameters(parameters)
{
m_ribInsertConn = rib.afterInsertEntry.connect(
std::bind(&NfdRibReadvertiseDestination::handleRibInsert, this, _1));
@@ -57,13 +55,13 @@
std::function<void()> successCb,
std::function<void(const std::string&)> failureCb)
{
- NFD_LOG_DEBUG("advertise " << rr.prefix << " on " << m_commandPrefix);
+ NFD_LOG_DEBUG("advertise " << rr.prefix << " on " << m_commandOptions.getPrefix());
m_controller.start<ndn::nfd::RibRegisterCommand>(
- ControlParameters().setName(rr.prefix).setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT),
+ getControlParameters().setName(rr.prefix),
[=] (const ControlParameters& cp) { successCb(); },
[=] (const ControlResponse& cr) { failureCb(cr.getText()); },
- CommandOptions().setPrefix(m_commandPrefix).setSigningInfo(rr.signer));
+ getCommandOptions().setSigningInfo(rr.signer));
}
void
@@ -71,19 +69,31 @@
std::function<void()> successCb,
std::function<void(const std::string&)> failureCb)
{
- NFD_LOG_DEBUG("withdraw " << rr.prefix << " on " << m_commandPrefix);
+ NFD_LOG_DEBUG("withdraw " << rr.prefix << " on " << m_commandOptions.getPrefix());
m_controller.start<ndn::nfd::RibUnregisterCommand>(
- ControlParameters().setName(rr.prefix).setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT),
+ getControlParameters().setName(rr.prefix),
[=] (const ControlParameters& cp) { successCb(); },
[=] (const ControlResponse& cr) { failureCb(cr.getText()); },
- CommandOptions().setPrefix(m_commandPrefix).setSigningInfo(rr.signer));
+ getCommandOptions().setSigningInfo(rr.signer));
+}
+
+ndn::nfd::ControlParameters
+NfdRibReadvertiseDestination::getControlParameters()
+{
+ return m_controlParameters;
+}
+
+ndn::nfd::CommandOptions
+NfdRibReadvertiseDestination::getCommandOptions()
+{
+ return m_commandOptions;
}
void
NfdRibReadvertiseDestination::handleRibInsert(const ndn::Name& name)
{
- if (name.isPrefixOf(m_commandPrefix)) {
+ if (name.isPrefixOf(m_commandOptions.getPrefix())) {
setAvailability(true);
}
}
@@ -91,7 +101,7 @@
void
NfdRibReadvertiseDestination::handleRibErase(const ndn::Name& name)
{
- if (name.isPrefixOf(m_commandPrefix)) {
+ if (name.isPrefixOf(m_commandOptions.getPrefix())) {
setAvailability(false);
}
}
diff --git a/rib/readvertise/nfd-rib-readvertise-destination.hpp b/rib/readvertise/nfd-rib-readvertise-destination.hpp
index ec71d98..d31e81b 100644
--- a/rib/readvertise/nfd-rib-readvertise-destination.hpp
+++ b/rib/readvertise/nfd-rib-readvertise-destination.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,9 @@
#include "readvertise-destination.hpp"
#include "../rib.hpp"
+#include <ndn-cxx/mgmt/nfd/command-options.hpp>
#include <ndn-cxx/mgmt/nfd/controller.hpp>
+#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
namespace nfd {
namespace rib {
@@ -40,8 +42,11 @@
{
public:
NfdRibReadvertiseDestination(ndn::nfd::Controller& controller,
- const Name& commandPrefix,
- Rib& rib);
+ Rib& rib,
+ const ndn::nfd::CommandOptions& options = ndn::nfd::CommandOptions(),
+ const ndn::nfd::ControlParameters& parameters =
+ ndn::nfd::ControlParameters()
+ .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT));
/** \brief add a name prefix into NFD RIB
*/
@@ -57,6 +62,13 @@
std::function<void()> successCb,
std::function<void(const std::string&)> failureCb) override;
+protected:
+ ndn::nfd::ControlParameters
+ getControlParameters();
+
+ ndn::nfd::CommandOptions
+ getCommandOptions();
+
private:
void
handleRibInsert(const Name& name);
@@ -66,10 +78,12 @@
private:
ndn::nfd::Controller& m_controller;
- Name m_commandPrefix;
signal::ScopedConnection m_ribInsertConn;
signal::ScopedConnection m_ribEraseConn;
+
+ ndn::nfd::CommandOptions m_commandOptions;
+ ndn::nfd::ControlParameters m_controlParameters;
};
} // namespace rib
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index 5ba99b8..8762e39 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -42,9 +42,10 @@
static const std::string MGMT_MODULE_NAME = "rib";
static const Name LOCALHOST_TOP_PREFIX = "/localhost/nfd";
-static const Name LOCALHOP_TOP_PREFIX = "/localhop/nfd";
static const time::seconds ACTIVE_FACE_FETCH_INTERVAL = 5_min;
+const Name RibManager::LOCALHOP_TOP_PREFIX = "/localhop/nfd";
+
RibManager::RibManager(Rib& rib, ndn::Face& face, ndn::KeyChain& keyChain,
ndn::nfd::Controller& nfdController, Dispatcher& dispatcher,
ndn::util::Scheduler& scheduler)
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
index bb1a970..98d29f6 100644
--- a/rib/rib-manager.hpp
+++ b/rib/rib-manager.hpp
@@ -26,7 +26,6 @@
#ifndef NFD_RIB_RIB_MANAGER_HPP
#define NFD_RIB_RIB_MANAGER_HPP
-#include "auto-prefix-propagator.hpp"
#include "fib-updater.hpp"
#include "rib.hpp"
@@ -240,6 +239,9 @@
void
onNotification(const ndn::nfd::FaceEventNotification& notification);
+public:
+ static const Name LOCALHOP_TOP_PREFIX;
+
private:
Rib& m_rib;
ndn::KeyChain& m_keyChain;
diff --git a/rib/service.cpp b/rib/service.cpp
index 48ff69c..a91a93e 100644
--- a/rib/service.cpp
+++ b/rib/service.cpp
@@ -25,9 +25,9 @@
#include "service.hpp"
-#include "auto-prefix-propagator.hpp"
#include "fib-updater.hpp"
#include "readvertise/client-to-nlsr-readvertise-policy.hpp"
+#include "readvertise/host-to-gateway-readvertise-policy.hpp"
#include "readvertise/nfd-rib-readvertise-destination.hpp"
#include "readvertise/readvertise.hpp"
@@ -51,6 +51,8 @@
static const std::string CFG_PREFIX_PROPAGATE = "auto_prefix_propagate";
static const std::string CFG_READVERTISE_NLSR = "readvertise_nlsr";
static const Name READVERTISE_NLSR_PREFIX = "/localhost/nlsr";
+static const uint64_t PROPAGATE_DEFAULT_COST = 15;
+static const time::milliseconds PROPAGATE_DEFAULT_TIMEOUT = 10_s;
static ConfigSection
loadConfigSectionFromFile(const std::string& filename)
@@ -194,13 +196,33 @@
m_ribManager.enableLocalhop(value, filename);
}
else if (key == CFG_PREFIX_PROPAGATE) {
- if (m_prefixPropagator == nullptr) {
- m_prefixPropagator = make_unique<AutoPrefixPropagator>(m_nfdController, m_keyChain,
- m_scheduler, m_rib);
- }
- m_prefixPropagator->loadConfig(item.second);
- m_prefixPropagator->enable();
wantPrefixPropagate = true;
+
+ if (!m_readvertisePropagation) {
+ NFD_LOG_DEBUG("Enabling automatic prefix propagation");
+
+ auto parameters = ndn::nfd::ControlParameters()
+ .setCost(PROPAGATE_DEFAULT_COST)
+ .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT);
+ auto cost = item.second.get_optional<uint64_t>("cost");
+ if (cost) {
+ parameters.setCost(*cost);
+ }
+
+ auto options = ndn::nfd::CommandOptions()
+ .setPrefix(RibManager::LOCALHOP_TOP_PREFIX)
+ .setTimeout(PROPAGATE_DEFAULT_TIMEOUT);
+ auto timeout = item.second.get_optional<uint64_t>("timeout");
+ if (timeout) {
+ options.setTimeout(time::milliseconds(*timeout));
+ }
+
+ m_readvertisePropagation = make_unique<Readvertise>(
+ m_rib,
+ m_scheduler,
+ make_unique<HostToGatewayReadvertisePolicy>(m_keyChain, item.second),
+ make_unique<NfdRibReadvertiseDestination>(m_nfdController, m_rib, options, parameters));
+ }
}
else if (key == CFG_READVERTISE_NLSR) {
wantReadvertiseNlsr = ConfigFile::parseYesNo(item, CFG_SECTION + "." + CFG_READVERTISE_NLSR);
@@ -210,17 +232,19 @@
}
}
- if (!wantPrefixPropagate && m_prefixPropagator != nullptr) {
- m_prefixPropagator->disable();
+ if (!wantPrefixPropagate && m_readvertisePropagation != nullptr) {
+ NFD_LOG_DEBUG("Disabling automatic prefix propagation");
+ m_readvertisePropagation.reset();
}
if (wantReadvertiseNlsr && m_readvertiseNlsr == nullptr) {
NFD_LOG_DEBUG("Enabling readvertise-to-nlsr");
+ auto options = ndn::nfd::CommandOptions().setPrefix(READVERTISE_NLSR_PREFIX);
m_readvertiseNlsr = make_unique<Readvertise>(
m_rib,
m_scheduler,
make_unique<ClientToNlsrReadvertisePolicy>(),
- make_unique<NfdRibReadvertiseDestination>(m_nfdController, READVERTISE_NLSR_PREFIX, m_rib));
+ make_unique<NfdRibReadvertiseDestination>(m_nfdController, m_rib, options));
}
else if (!wantReadvertiseNlsr && m_readvertiseNlsr != nullptr) {
NFD_LOG_DEBUG("Disabling readvertise-to-nlsr");
diff --git a/rib/service.hpp b/rib/service.hpp
index 0b06013..e372a0d 100644
--- a/rib/service.hpp
+++ b/rib/service.hpp
@@ -40,7 +40,6 @@
namespace nfd {
namespace rib {
-class AutoPrefixPropagator;
class Readvertise;
/**
@@ -116,8 +115,8 @@
Rib m_rib;
FibUpdater m_fibUpdater;
- unique_ptr<AutoPrefixPropagator> m_prefixPropagator;
unique_ptr<Readvertise> m_readvertiseNlsr;
+ unique_ptr<Readvertise> m_readvertisePropagation;
ndn::mgmt::Dispatcher m_dispatcher;
RibManager m_ribManager;
};