face: give ProtocolFactory access to NetworkMonitor
Subclasses of ProtocolFactory can access NetworkMonitor and
addFace callback anytime via member fields. They are supplied
to ProtocolFactory::create from FaceSystem.
This is in preparation for letting ProtocolFactory subclasses
react to fine-grained signals from NetworkMonitor.
refs #4021
Change-Id: I8da116bffc83d1bdeed7fd3b2e12c8872f19177b
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 8fc9822..362527f 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -128,7 +128,7 @@
auto channel = this->createChannel(netif, time::seconds(idleTimeout));
if (wantListen && !channel->isListening()) {
try {
- channel->listen(context.addFace, nullptr);
+ channel->listen(this->addFace, nullptr);
}
catch (const EthernetChannel::Error& e) {
NFD_LOG_WARN("Cannot listen on " << netif->getName() << ": " << e.what());
@@ -293,7 +293,7 @@
if (face->getId() == face::INVALID_FACEID) {
// new face: register with forwarding
- context.addFace(face);
+ this->addFace(face);
}
else {
// existing face: don't destroy
diff --git a/daemon/face/face-system.cpp b/daemon/face/face-system.cpp
index ee44591..7877ed0 100644
--- a/daemon/face/face-system.cpp
+++ b/daemon/face/face-system.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -25,6 +25,7 @@
#include "face-system.hpp"
#include "protocol-factory.hpp"
+#include "core/global-io.hpp"
#include "fw/face-table.hpp"
namespace nfd {
@@ -32,15 +33,23 @@
NFD_LOG_INIT("FaceSystem");
-FaceSystem::FaceSystem(FaceTable& faceTable)
+FaceSystem::FaceSystem(FaceTable& faceTable, const shared_ptr<ndn::net::NetworkMonitor>& netmon)
: m_faceTable(faceTable)
{
+ BOOST_ASSERT(netmon != nullptr);
+
+ auto addFace = bind(&FaceTable::add, &m_faceTable, _1);
for (const std::string& id : ProtocolFactory::listRegistered()) {
NFD_LOG_TRACE("creating factory " << id);
- m_factories[id] = ProtocolFactory::create(id);
+ m_factories[id] = ProtocolFactory::create(id, netmon, addFace);
}
}
+FaceSystem::FaceSystem(FaceTable& faceTable)
+ : FaceSystem(faceTable, make_shared<ndn::net::NetworkMonitor>(getGlobalIoService()))
+{
+}
+
FaceSystem::~FaceSystem() = default;
std::set<const ProtocolFactory*>
@@ -78,7 +87,6 @@
{
ConfigContext context;
context.isDryRun = isDryRun;
- context.addFace = bind(&FaceTable::add, &m_faceTable, _1);
context.m_netifs = listNetworkInterfaces();
// process sections in protocol factories
diff --git a/daemon/face/face-system.hpp b/daemon/face/face-system.hpp
index d1f38b9..6557c72 100644
--- a/daemon/face/face-system.hpp
+++ b/daemon/face/face-system.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -30,6 +30,9 @@
#include "core/config-file.hpp"
#include "core/network-interface.hpp"
#include "core/network-interface-predicate.hpp"
+#include <ndn-cxx/net/network-address.hpp>
+#include <ndn-cxx/net/network-interface.hpp>
+#include <ndn-cxx/net/network-monitor.hpp>
namespace nfd {
@@ -47,8 +50,11 @@
class FaceSystem : noncopyable
{
public:
+ FaceSystem(FaceTable& faceTable, const shared_ptr<ndn::net::NetworkMonitor>& netmon);
+
+ DEPRECATED(
explicit
- FaceSystem(FaceTable& faceTable);
+ FaceSystem(FaceTable& faceTable));
~FaceSystem();
@@ -83,17 +89,15 @@
class ConfigContext : noncopyable
{
public:
+ /// \deprecated use NetworkMonitor provided as ProtocolFactory::netmon
const std::vector<NetworkInterfaceInfo>&
listNetifs() const
{
- ///\todo get netifs from NetworkMonitor
return m_netifs;
}
public:
bool isDryRun;
- FaceCreatedCallback addFace;
- ///\todo add NetworkMonitor
private:
std::vector<NetworkInterfaceInfo> m_netifs;
diff --git a/daemon/face/protocol-factory.cpp b/daemon/face/protocol-factory.cpp
index daa0214..010190d 100644
--- a/daemon/face/protocol-factory.cpp
+++ b/daemon/face/protocol-factory.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -38,11 +38,19 @@
}
unique_ptr<ProtocolFactory>
-ProtocolFactory::create(const std::string& id)
+ProtocolFactory::create(const std::string& id, shared_ptr<ndn::net::NetworkMonitor> netmon,
+ const FaceCreatedCallback& addFace)
{
Registry& registry = getRegistry();
auto found = registry.find(id);
- return found == registry.end() ? nullptr : found->second();
+ if (found == registry.end()) {
+ return nullptr;
+ }
+
+ auto factory = found->second();
+ factory->netmon = std::move(netmon);
+ factory->addFace = addFace;
+ return factory;
}
std::set<std::string>
diff --git a/daemon/face/protocol-factory.hpp b/daemon/face/protocol-factory.hpp
index b8bba3d..9d6ad3e 100644
--- a/daemon/face/protocol-factory.hpp
+++ b/daemon/face/protocol-factory.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -29,14 +29,14 @@
#include "channel.hpp"
#include "face-system.hpp"
-#include <ndn-cxx/encoding/nfd-constants.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
+#include <ndn-cxx/encoding/nfd-constants.hpp>
namespace nfd {
namespace face {
-/** \brief provide support for an underlying protocol
+/** \brief Provides support for an underlying protocol
* \sa FaceSystem
*
* A protocol factory provides support for an underlying protocol and owns Channel objects.
@@ -46,7 +46,7 @@
class ProtocolFactory : noncopyable
{
public: // registry
- /** \brief register a protocol factory type
+ /** \brief Register a protocol factory type
* \tparam S subclass of ProtocolFactory
* \param id factory identifier
*/
@@ -59,20 +59,21 @@
registry[id] = &make_unique<PF>;
}
- /** \return a protocol factory instance
+ /** \brief Create a protocol factory instance
* \retval nullptr if factory with \p id is not registered
*/
static unique_ptr<ProtocolFactory>
- create(const std::string& id);
+ create(const std::string& id, shared_ptr<ndn::net::NetworkMonitor> netmon,
+ const FaceCreatedCallback& addFace);
- /** \return registered protocol factory ids
+ /** \brief Get registered protocol factory ids
*/
static std::set<std::string>
listRegistered();
public:
/**
- * \brief Base class for all exceptions thrown by protocol factories
+ * \brief Base class for all exceptions thrown by ProtocolFactory subclasses
*/
class Error : public std::runtime_error
{
@@ -88,7 +89,7 @@
~ProtocolFactory() = default;
#ifdef DOXYGEN
- /** \return protocol factory id
+ /** \brief Get id for this ProtocolFactory
*
* face_system.factory-id config section is processed by the protocol factory.
*/
@@ -96,7 +97,7 @@
getId();
#endif
- /** \brief process face_system subsection that corresponds to this ProtocolFactory type
+ /** \brief Process face_system subsection that corresponds to this ProtocolFactory type
* \param configSection the configuration section or boost::null to indicate it is omitted
* \param context provides access to data structures and contextual information
* \throw ConfigFile::Error invalid configuration
@@ -107,7 +108,7 @@
processConfig(OptionalConfigSection configSection,
FaceSystem::ConfigContext& context) = 0;
- /** \return FaceUri schemes accepted by this ProtocolFactory
+ /** \brief Get FaceUri schemes accepted by this ProtocolFactory
*/
const std::set<std::string>&
getProvidedSchemes()
@@ -154,9 +155,16 @@
getRegistry();
protected:
- /** \brief FaceUri schemes provided by this ProtocolFactory
+ std::set<std::string> providedSchemes; ///< FaceUri schemes provided by this ProtocolFactory
+
+ /** \brief NetworkMonitor for listing available network interfaces and monitoring their changes
+ *
+ * ProtocolFactory subclass should check the NetworkMonitor has sufficient capabilities prior
+ * to usage.
*/
- std::set<std::string> providedSchemes;
+ shared_ptr<ndn::net::NetworkMonitor> netmon;
+
+ FaceCreatedCallback addFace; ///< callback when a new face is created
};
} // namespace face
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 3132796..e2fb3fe 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -97,7 +97,7 @@
tcp::Endpoint endpoint(ip::tcp::v4(), port);
shared_ptr<TcpChannel> v4Channel = this->createChannel(endpoint);
if (wantListen && !v4Channel->isListening()) {
- v4Channel->listen(context.addFace, nullptr);
+ v4Channel->listen(this->addFace, nullptr);
}
providedSchemes.insert("tcp4");
}
@@ -109,7 +109,7 @@
tcp::Endpoint endpoint(ip::tcp::v6(), port);
shared_ptr<TcpChannel> v6Channel = this->createChannel(endpoint);
if (wantListen && !v6Channel->isListening()) {
- v6Channel->listen(context.addFace, nullptr);
+ v6Channel->listen(this->addFace, nullptr);
}
providedSchemes.insert("tcp6");
}
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 5b68061..cc02bfc 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -151,7 +151,7 @@
udp::Endpoint endpoint(ip::udp::v4(), port);
shared_ptr<UdpChannel> v4Channel = this->createChannel(endpoint, time::seconds(idleTimeout));
if (!v4Channel->isListening()) {
- v4Channel->listen(context.addFace, nullptr);
+ v4Channel->listen(this->addFace, nullptr);
}
providedSchemes.insert("udp");
providedSchemes.insert("udp4");
@@ -164,7 +164,7 @@
udp::Endpoint endpoint(ip::udp::v6(), port);
shared_ptr<UdpChannel> v6Channel = this->createChannel(endpoint, time::seconds(idleTimeout));
if (!v6Channel->isListening()) {
- v6Channel->listen(context.addFace, nullptr);
+ v6Channel->listen(this->addFace, nullptr);
}
providedSchemes.insert("udp");
providedSchemes.insert("udp6");
@@ -485,7 +485,7 @@
needIfname ? netif.name : "");
if (face->getId() == INVALID_FACEID) {
// new face: register with forwarding
- context.addFace(face);
+ this->addFace(face);
}
else {
// existing face: don't destroy
diff --git a/daemon/face/unix-stream-factory.cpp b/daemon/face/unix-stream-factory.cpp
index a7aeadb..2d5fe94 100644
--- a/daemon/face/unix-stream-factory.cpp
+++ b/daemon/face/unix-stream-factory.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -74,7 +74,7 @@
if (!context.isDryRun) {
auto channel = this->createChannel(path);
if (!channel->isListening()) {
- channel->listen(context.addFace, nullptr);
+ channel->listen(this->addFace, nullptr);
}
}
}
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index a0b58e5..2905ae4 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -105,7 +105,7 @@
auto channel = this->createChannel(endpoint);
if (!channel->isListening()) {
- channel->listen(context.addFace);
+ channel->listen(this->addFace);
if (m_channels.size() > 1) {
NFD_LOG_WARN("Adding WebSocket channel for new endpoint; cannot close existing channels");
}
diff --git a/daemon/nfd.cpp b/daemon/nfd.cpp
index 8c58034..8a917a9 100644
--- a/daemon/nfd.cpp
+++ b/daemon/nfd.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -46,30 +46,22 @@
static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
-static inline ndn::net::NetworkMonitor*
-makeNetworkMonitor()
+Nfd::Nfd(ndn::KeyChain& keyChain)
+ : m_keyChain(keyChain)
+ , m_netmon(make_shared<ndn::net::NetworkMonitor>(getGlobalIoService()))
{
- try {
- return new ndn::net::NetworkMonitor(getGlobalIoService());
- }
- catch (const ndn::net::NetworkMonitor::Error& e) {
- NFD_LOG_WARN(e.what());
- return nullptr;
- }
}
Nfd::Nfd(const std::string& configFile, ndn::KeyChain& keyChain)
- : m_configFile(configFile)
- , m_keyChain(keyChain)
- , m_networkMonitor(makeNetworkMonitor())
+ : Nfd(keyChain)
{
+ m_configFile = configFile;
}
Nfd::Nfd(const ConfigSection& config, ndn::KeyChain& keyChain)
- : m_configSection(config)
- , m_keyChain(keyChain)
- , m_networkMonitor(makeNetworkMonitor())
+ : Nfd(keyChain)
{
+ m_configSection = config;
}
// It is necessary to explicitly define the destructor, because some member variables (e.g.,
@@ -87,23 +79,21 @@
FaceTable& faceTable = m_forwarder->getFaceTable();
faceTable.addReserved(face::makeNullFace(), face::FACEID_NULL);
faceTable.addReserved(face::makeNullFace(FaceUri("contentstore://")), face::FACEID_CONTENT_STORE);
- m_faceSystem.reset(new face::FaceSystem(faceTable));
+ m_faceSystem = make_unique<face::FaceSystem>(faceTable, m_netmon);
initializeManagement();
PrivilegeHelper::drop();
- if (m_networkMonitor) {
- m_networkMonitor->onNetworkStateChanged.connect([this] {
- // delay stages, so if multiple events are triggered in short sequence,
- // only one auto-detection procedure is triggered
- m_reloadConfigEvent = scheduler::schedule(time::seconds(5),
- [this] {
- NFD_LOG_INFO("Network change detected, reloading face section of the config file...");
- this->reloadConfigFileFaceSection();
- });
- });
- }
+ m_netmon->onNetworkStateChanged.connect([this] {
+ // delay stages, so if multiple events are triggered in short sequence,
+ // only one auto-detection procedure is triggered
+ m_reloadConfigEvent = scheduler::schedule(time::seconds(5),
+ [this] {
+ NFD_LOG_INFO("Network change detected, reloading face section of the config file...");
+ this->reloadConfigFileFaceSection();
+ });
+ });
}
void
diff --git a/daemon/nfd.hpp b/daemon/nfd.hpp
index 8f83644..ff7b1c4 100644
--- a/daemon/nfd.hpp
+++ b/daemon/nfd.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -93,6 +93,9 @@
reloadConfigFile();
private:
+ explicit
+ Nfd(ndn::KeyChain& keyChain);
+
void
initializeLogging();
@@ -119,7 +122,7 @@
unique_ptr<FibManager> m_fibManager;
unique_ptr<StrategyChoiceManager> m_strategyChoiceManager;
- unique_ptr<ndn::net::NetworkMonitor> m_networkMonitor;
+ shared_ptr<ndn::net::NetworkMonitor> m_netmon;
scheduler::ScopedEventId m_reloadConfigEvent;
};
diff --git a/tests/daemon/face/face-system-fixture.hpp b/tests/daemon/face/face-system-fixture.hpp
index 42ed02c..f1ea72c 100644
--- a/tests/daemon/face/face-system-fixture.hpp
+++ b/tests/daemon/face/face-system-fixture.hpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
@@ -32,6 +32,7 @@
#include "fw/face-table.hpp"
#include "tests/test-common.hpp"
+#include <ndn-cxx/net/network-monitor-stub.hpp>
namespace nfd {
namespace face {
@@ -43,7 +44,8 @@
{
public:
FaceSystemFixture()
- : faceSystem(faceTable)
+ : netmon(make_shared<ndn::net::NetworkMonitorStub>(~0))
+ , faceSystem(faceTable, netmon)
{
faceSystem.setConfigFile(configFile);
}
@@ -107,6 +109,7 @@
protected:
ConfigFile configFile;
FaceTable faceTable;
+ shared_ptr<ndn::net::NetworkMonitorStub> netmon;
FaceSystem faceSystem;
};