face: more robust handling of multicast face creation errors

Refs: #5030, #5297
Change-Id: I3ca985498d9d3756cbff94873063f3734bcea288
This commit is contained in:
Davide Pesavento committed 2023-10-19 02:12:05 -04:00
1 parent 0a05f7aea6
commit c5a9f81fce
14 files changed
+119 -97

No files matched your search

+3 -2
View File
@@ -101,8 +101,9 @@ void
EthernetChannel::asyncRead(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
{
m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read,
[=] (const auto& e) { this->handleRead(e, onFaceCreated, onReceiveFailed); });
m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read, [=] (const auto& e) {
handleRead(e, onFaceCreated, onReceiveFailed);
});
}
void
+10 -13
View File
@@ -26,7 +26,6 @@
#include "ethernet-factory.hpp"
#include "generic-link-service.hpp"
#include "multicast-ethernet-transport.hpp"
#include "pcap-helper.hpp"
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm/copy.hpp>
@@ -170,13 +169,13 @@ EthernetFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (!req.localUri || req.localUri->getScheme() != "dev") {
NFD_LOG_TRACE("Cannot create unicast Ethernet face without dev:// LocalUri");
NFD_LOG_TRACE("createFace: dev:// LocalUri required");
onFailure(406, "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing Ethernet faces do not support on-demand persistency");
return;
}
@@ -185,14 +184,14 @@ EthernetFactory::doCreateFace(const CreateFaceRequest& req,
std::string localEndpoint(req.localUri->getHost());
if (remoteEndpoint.isMulticast()) {
NFD_LOG_TRACE("createFace does not support multicast faces");
NFD_LOG_TRACE("createFace: unsupported multicast endpoint");
onFailure(406, "Cannot create multicast Ethernet faces");
return;
}
if (req.params.wantLocalFields) {
// Ethernet faces are never local
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -258,7 +257,9 @@ EthernetFactory::createMulticastFace(const ndn::net::NetworkInterface& netif,
connectFaceClosedSignal(*face, [this, key] { m_mcastFaces.erase(key); });
auto channelIt = m_channels.find(netif.getName());
face->setChannel(channelIt != m_channels.end() ? channelIt->second : nullptr);
if (channelIt != m_channels.end()) {
face->setChannel(channelIt->second);
}
return face;
}
@@ -332,15 +333,11 @@ EthernetFactory::applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif
NFD_LOG_DEBUG("Creating multicast face on " << netif.getName());
shared_ptr<Face> face;
try {
face = this->createMulticastFace(netif, m_mcastConfig.group);
face = createMulticastFace(netif, m_mcastConfig.group);
}
catch (const EthernetTransport::Error& e) {
catch (const std::runtime_error& e) {
NFD_LOG_WARN("Cannot create multicast face on " << netif.getName() << ": " << e.what());
return nullptr;
}
catch (const PcapHelper::Error& e) {
NFD_LOG_WARN("Cannot create multicast face on " << netif.getName() << ": " << e.what());
return nullptr;
return nullptr; // not a fatal error
}
if (face->getId() == INVALID_FACEID) {
+14 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,10 +28,12 @@
#include "protocol-factory.hpp"
#include "ethernet-channel.hpp"
#include "network-predicate.hpp"
namespace nfd::face {
/** \brief Protocol factory for Ethernet.
/**
* \brief Protocol factory for Ethernet.
*/
class EthernetFactory final : public ProtocolFactory
{
@@ -48,7 +50,7 @@ public:
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
* \return always a valid pointer to a EthernetChannel object, an exception
* \return Always a valid pointer to a EthernetChannel object, an exception
* is thrown if it cannot be created.
* \throw PcapHelper::Error channel creation failed
*/
@@ -65,7 +67,7 @@ public:
* \param localEndpoint local network interface
* \param group multicast group address
*
* \throw EthernetTransport::Error transport creation fails
* \throw std::runtime_error %Face creation failed
*/
shared_ptr<Face>
createMulticastFace(const ndn::net::NetworkInterface& localEndpoint,
@@ -84,14 +86,16 @@ private:
std::vector<shared_ptr<const Channel>>
doGetChannels() const final;
/** \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
* \return new or existing channel, or nullptr if no channel should be created
/**
* \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
* \return New or existing channel, or nullptr if no channel should be created.
*/
shared_ptr<EthernetChannel>
applyUnicastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
/** \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
* \return new or existing face, or nullptr if no face should be created
/**
* \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
* \return New or existing face, or nullptr if no face should be created.
*/
shared_ptr<Face>
applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif);
@@ -100,7 +104,8 @@ private:
applyConfig(const FaceSystem::ConfigContext& context);
private:
std::map<std::string, shared_ptr<EthernetChannel>> m_channels; ///< ifname => channel
// ifname => channel
std::map<std::string, shared_ptr<EthernetChannel>> m_channels;
struct UnicastConfig
{
+4 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,9 +24,8 @@
*/
#include "face-system.hpp"
#include "protocol-factory.hpp"
#include "netdev-bound.hpp"
#include "common/global.hpp"
#include "protocol-factory.hpp"
#include "fw/face-table.hpp"
namespace nfd::face {
@@ -71,14 +70,14 @@ FaceSystem::listProtocolFactories() const
}
ProtocolFactory*
FaceSystem::getFactoryById(const std::string& id)
FaceSystem::getFactoryById(const std::string& id) const
{
auto found = m_factories.find(id);
return found == m_factories.end() ? nullptr : found->second.get();
}
ProtocolFactory*
FaceSystem::getFactoryByScheme(const std::string& scheme)
FaceSystem::getFactoryByScheme(const std::string& scheme) const
{
auto found = m_factoryByScheme.find(scheme);
return found == m_factoryByScheme.end() ? nullptr : found->second;
+7 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,7 +26,6 @@
#ifndef NFD_DAEMON_FACE_FACE_SYSTEM_HPP
#define NFD_DAEMON_FACE_FACE_SYSTEM_HPP
#include "network-predicate.hpp"
#include "common/config-file.hpp"
#include <ndn-cxx/net/network-address.hpp>
@@ -62,15 +61,17 @@ public:
[[nodiscard]] std::set<const ProtocolFactory*>
listProtocolFactories() const;
/** \return ProtocolFactory for the specified registered factory id or nullptr if not found.
/**
* \return ProtocolFactory for the specified registered factory id or nullptr if not found.
*/
ProtocolFactory*
getFactoryById(const std::string& id);
getFactoryById(const std::string& id) const;
/** \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found.
/**
* \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found.
*/
ProtocolFactory*
getFactoryByScheme(const std::string& scheme);
getFactoryByScheme(const std::string& scheme) const;
bool
hasFactoryForScheme(const std::string& scheme) const;
+2 -1
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,6 +26,7 @@
#ifndef NFD_DAEMON_FACE_NETDEV_BOUND_HPP
#define NFD_DAEMON_FACE_NETDEV_BOUND_HPP
#include "network-predicate.hpp"
#include "protocol-factory.hpp"
namespace nfd::face {
+4 -4
View File
@@ -152,13 +152,13 @@ TcpFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (req.localUri) {
NFD_LOG_TRACE("Cannot create unicast TCP face with LocalUri");
NFD_LOG_TRACE("createFace: unsupported LocalUri");
onFailure(406, "Unicast TCP faces cannot be created with a LocalUri");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing TCP faces do not support on-demand persistency");
return;
}
@@ -170,13 +170,13 @@ TcpFactory::doCreateFace(const CreateFaceRequest& req,
BOOST_ASSERT(!endpoint.address().is_multicast());
if (req.params.wantLocalFields && !endpoint.address().is_loopback()) {
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
if (req.params.mtu) {
NFD_LOG_TRACE("createFace cannot create a TCP face with an overridden MTU");
NFD_LOG_TRACE("createFace: cannot create TCP face with overridden MTU");
onFailure(406, "TCP faces do not support MTU overrides");
return;
}
+6 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,11 +27,13 @@
#define NFD_DAEMON_FACE_TCP_FACTORY_HPP
#include "protocol-factory.hpp"
#include "network-predicate.hpp"
#include "tcp-channel.hpp"
namespace nfd::face {
/** \brief Protocol factory for TCP over IPv4 and IPv6.
/**
* \brief Protocol factory for TCP over IPv4 and IPv6.
*/
class TcpFactory final : public ProtocolFactory
{
@@ -44,12 +46,12 @@ public:
/**
* \brief Create TCP-based channel using tcp::Endpoint.
*
* tcp::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
* tcp::Endpoint is an alias for boost::asio::ip::tcp::endpoint.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
* \return always a valid pointer to a TcpChannel object, an exception
* \return Always a valid pointer to a TcpChannel object, an exception
* is thrown if it cannot be created.
*/
shared_ptr<TcpChannel>
+3 -4
View File
@@ -97,10 +97,9 @@ void
UdpChannel::waitForNewPeer(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
{
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint,
[=] (auto&&... args) {
this->handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
});
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint, [=] (auto&&... args) {
handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
});
}
void
+19 -10
View File
@@ -28,6 +28,7 @@
#include "multicast-udp-transport.hpp"
#include "common/global.hpp"
#include <boost/container/static_vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
@@ -196,7 +197,7 @@ UdpFactory::doProcessConfig(OptionalConfigSection configSection,
providedSchemes.insert("udp4");
}
else if (providedSchemes.count("udp4") > 0) {
NFD_LOG_WARN("Cannot close udp4 channel after its creation");
NFD_LOG_WARN("Cannot close UDP channel after its creation");
}
if (enableV6) {
@@ -209,7 +210,7 @@ UdpFactory::doProcessConfig(OptionalConfigSection configSection,
providedSchemes.insert("udp6");
}
else if (providedSchemes.count("udp6") > 0) {
NFD_LOG_WARN("Cannot close udp6 channel after its creation");
NFD_LOG_WARN("Cannot close UDP channel after its creation");
}
if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
@@ -250,13 +251,13 @@ UdpFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (req.localUri) {
NFD_LOG_TRACE("Cannot create unicast UDP face with LocalUri");
NFD_LOG_TRACE("createFace: unsupported LocalUri");
onFailure(406, "Unicast UDP faces cannot be created with a LocalUri");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing UDP faces do not support on-demand persistency");
return;
}
@@ -265,14 +266,14 @@ UdpFactory::doCreateFace(const CreateFaceRequest& req,
boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
if (endpoint.address().is_multicast()) {
NFD_LOG_TRACE("createFace does not support multicast faces");
NFD_LOG_TRACE("createFace: unsupported multicast endpoint");
onFailure(406, "Cannot create multicast UDP faces");
return;
}
if (req.params.wantLocalFields) {
// UDP faces are never local
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -377,7 +378,9 @@ UdpFactory::createMulticastFace(const net::NetworkInterface& netif,
[isV4 = localEp.address().is_v4()] (const auto& it) {
return it.first.address().is_v4() == isV4;
});
face->setChannel(channelIt != m_channels.end() ? channelIt->second : nullptr);
if (channelIt != m_channels.end()) {
face->setChannel(channelIt->second);
}
return face;
}
@@ -423,7 +426,7 @@ UdpFactory::applyMcastConfigToNetif(const shared_ptr<const net::NetworkInterface
return {};
}
std::vector<ip::address> addrs;
boost::container::static_vector<ip::address, 2> addrs;
for (auto af : {net::AddressFamily::V4, net::AddressFamily::V6}) {
auto addr = pickAddress(*netif, af);
if (addr)
@@ -442,8 +445,14 @@ UdpFactory::applyMcastConfigToNetif(const shared_ptr<const net::NetworkInterface
std::vector<shared_ptr<Face>> faces;
for (const auto& addr : addrs) {
auto face = this->createMulticastFace(*netif, addr,
addr.is_v4() ? m_mcastConfig.group : m_mcastConfig.groupV6);
shared_ptr<Face> face;
try {
face = createMulticastFace(*netif, addr, addr.is_v4() ? m_mcastConfig.group : m_mcastConfig.groupV6);
}
catch (const std::runtime_error& e) {
NFD_LOG_WARN("Cannot create multicast face on " << addr << ": " << e.what());
continue; // not a fatal error
}
if (face->getId() == INVALID_FACEID) {
// new face: register with forwarding
this->addFace(face);
+14 -10
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,11 +27,13 @@
#define NFD_DAEMON_FACE_UDP_FACTORY_HPP
#include "protocol-factory.hpp"
#include "network-predicate.hpp"
#include "udp-channel.hpp"
namespace nfd::face {
/** \brief Protocol factory for UDP over IPv4 and IPv6.
/**
* \brief Protocol factory for UDP over IPv4 and IPv6.
*/
class UdpFactory final : public ProtocolFactory
{
@@ -51,7 +53,7 @@ public:
/**
* \brief Create UDP-based channel using udp::Endpoint.
*
* udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
* udp::Endpoint is an alias for boost::asio::ip::udp::endpoint.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
@@ -59,7 +61,7 @@ public:
* If a multicast face is already active on the same local endpoint,
* the creation fails and an exception is thrown.
*
* \return always a valid pointer to a UdpChannel object, an exception
* \return Always a valid pointer to a UdpChannel object, an exception
* is thrown if it cannot be created.
* \throw UdpFactory::Error
*/
@@ -70,7 +72,7 @@ public:
/**
* \brief Create a multicast UDP face.
*
* udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
* udp::Endpoint is an alias for boost::asio::ip::udp::endpoint.
*
* The face will join the specified multicast group.
*
@@ -85,9 +87,9 @@ public:
* \param localAddress the local IP address to which the face will be bound
* \param multicastEndpoint the multicast endpoint (multicast group and port number)
*
* \return always a valid shared pointer to the created face;
* \return Always a valid shared pointer to the created face;
* an exception is thrown if the face cannot be created.
* \throw UdpFactory::Error
* \throw std::runtime_error %Face creation failed
*/
shared_ptr<Face>
createMulticastFace(const ndn::net::NetworkInterface& netif,
@@ -107,13 +109,15 @@ private:
std::vector<shared_ptr<const Channel>>
doGetChannels() const final;
/** \brief Create UDP multicast faces on \p netif if needed by \p m_mcastConfig.
* \return list of faces (just created or already existing) on \p netif
/**
* \brief Create UDP multicast faces on \p netif if needed by \p m_mcastConfig.
* \return List of faces (just created or already existing) on \p netif.
*/
std::vector<shared_ptr<Face>>
applyMcastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
/** \brief Create and destroy UDP multicast faces according to \p m_mcastConfig.
/**
* \brief Create and destroy UDP multicast faces according to \p m_mcastConfig.
*/
void
applyMcastConfig(const FaceSystem::ConfigContext& context);
+4 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
namespace nfd::face {
/** \brief Protocol factory for stream-oriented Unix sockets.
/**
* \brief Protocol factory for stream-oriented Unix sockets.
*/
class UnixStreamFactory final : public ProtocolFactory
{
@@ -48,7 +49,7 @@ public:
* will be created. The second call will just retrieve the existing
* channel.
*
* \returns always a valid pointer to a UnixStreamChannel object,
* \returns Always a valid pointer to a UnixStreamChannel object,
* an exception will be thrown if the channel cannot be created.
*/
shared_ptr<UnixStreamChannel>
+5 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
namespace nfd::face {
/** \brief Protocol factory for WebSocket.
/**
* \brief Protocol factory for WebSocket.
*/
class WebSocketFactory final : public ProtocolFactory
{
@@ -44,13 +45,13 @@ public:
/**
* \brief Create WebSocket-based channel using websocket::Endpoint.
*
* websocket::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
* websocket::Endpoint is an alias for boost::asio::ip::tcp::endpoint.
*
* If this method called twice with the same endpoint, only one channel
* will be created. The second call will just retrieve the existing
* channel.
*
* \returns always a valid pointer to a WebSocketChannel object, an exception
* \returns Always a valid pointer to a WebSocketChannel object, an exception
* is thrown if it cannot be created.
*/
shared_ptr<WebSocketChannel>
+24 -22
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -43,20 +43,19 @@ class FaceSystemFixture : public virtual GlobalIoFixture
{
public:
FaceSystemFixture()
: netmon(make_shared<ndn::net::NetworkMonitorStub>(~0))
, faceSystem(faceTable, netmon)
, netdevBound(*faceSystem.m_netdevBound)
{
faceSystem.setConfigFile(configFile);
}
/** \brief Copy a snapshot of NetworkInterface information to \p netmon.
* \pre netmon contains no NetworkInterface
/**
* \brief Copy a snapshot of NetworkInterface information to \p netmon.
* \pre netmon contains no NetworkInterface.
*/
void
copyRealNetifsToNetmon()
{
BOOST_ASSERT(netmon->listNetworkInterfaces().empty());
for (const auto& netif : collectNetworkInterfaces()) {
auto copy = netmon->makeNetworkInterface();
copy->setIndex(netif->getIndex());
@@ -72,6 +71,7 @@ public:
}
netmon->addInterface(copy);
}
netmon->emitEnumerationCompleted();
}
@@ -81,39 +81,42 @@ public:
configFile.parse(text, isDryRun, "test-config");
}
/** \brief Get ProtocolFactory from FaceSystem.
* \tparam F ProtocolFactory subclass
/**
* \brief Get ProtocolFactory from FaceSystem.
* \tparam F ProtocolFactory subclass
*
* If ProtocolFactory with \p scheme does not exist or has an incompatible type,
* this fails the test case.
* If ProtocolFactory with \p id does not exist or has an incompatible type,
* this fails the test case.
*/
template<typename F>
F&
getFactoryById(const std::string& id)
getFactoryById(const std::string& id) const
{
F* factory = dynamic_cast<F*>(faceSystem.getFactoryById(id));
BOOST_REQUIRE(factory != nullptr);
return *factory;
}
/** \brief Get ProtocolFactory from FaceSystem.
* \tparam F ProtocolFactory subclass
/**
* \brief Get ProtocolFactory from FaceSystem.
* \tparam F ProtocolFactory subclass
*
* If ProtocolFactory with \p scheme does not exist or has an incompatible type,
* this fails the test case.
* If ProtocolFactory with \p scheme does not exist or has an incompatible type,
* this fails the test case.
*/
template<typename F>
F&
getFactoryByScheme(const std::string& scheme)
getFactoryByScheme(const std::string& scheme) const
{
F* factory = dynamic_cast<F*>(faceSystem.getFactoryByScheme(scheme));
BOOST_REQUIRE(factory != nullptr);
return *factory;
}
/** \brief List faces of specified scheme from FaceTable.
* \param scheme local or remote FaceUri scheme
* \param linkType if not NONE, filter by specified LinkType
/**
* \brief List faces of specified scheme from FaceTable.
* \param scheme local or remote FaceUri scheme
* \param linkType if not NONE, filter by specified LinkType
*/
std::vector<const Face*>
listFacesByScheme(const std::string& scheme,
@@ -134,9 +137,8 @@ public:
protected:
ConfigFile configFile;
FaceTable faceTable;
shared_ptr<ndn::net::NetworkMonitorStub> netmon;
FaceSystem faceSystem;
face::NetdevBound& netdevBound;
shared_ptr<ndn::net::NetworkMonitorStub> netmon{make_shared<ndn::net::NetworkMonitorStub>(~0)};
FaceSystem faceSystem{faceTable, netmon};
};
/**