face: unicast support in EthernetFactory
Change-Id: I1886a87d79a7194b3320a5417404b17a7290fa5d
Refs: #4012
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 44282c0..20fda6d 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -49,6 +49,8 @@
{
// ether
// {
+ // listen yes
+ // idle_timeout 600
// mcast yes
// mcast_group 01:00:5E:00:17:AA
// mcast_ad_hoc no
@@ -61,6 +63,8 @@
// }
// }
+ bool wantListen = true;
+ uint32_t idleTimeout = 600;
MulticastConfig mcastConfig;
if (configSection) {
@@ -71,8 +75,14 @@
const std::string& key = pair.first;
const ConfigSection& value = pair.second;
- if (key == "mcast") {
- mcastConfig.isEnabled = ConfigFile::parseYesNo(pair, "ether");
+ if (key == "listen") {
+ wantListen = ConfigFile::parseYesNo(pair, "face_system.ether");
+ }
+ else if (key == "idle_timeout") {
+ idleTimeout = ConfigFile::parseNumber<uint32_t>(pair, "face_system.ether");
+ }
+ else if (key == "mcast") {
+ mcastConfig.isEnabled = ConfigFile::parseYesNo(pair, "face_system.ether");
}
else if (key == "mcast_group") {
const std::string& valueStr = value.get_value<std::string>();
@@ -87,7 +97,7 @@
}
}
else if (key == "mcast_ad_hoc") {
- bool wantAdHoc = ConfigFile::parseYesNo(pair, "ether");
+ bool wantAdHoc = ConfigFile::parseYesNo(pair, "face_system.ether");
mcastConfig.linkType = wantAdHoc ? ndn::nfd::LINK_TYPE_AD_HOC : ndn::nfd::LINK_TYPE_MULTI_ACCESS;
}
else if (key == "whitelist") {
@@ -103,6 +113,32 @@
}
if (!context.isDryRun) {
+ if (configSection) {
+ providedSchemes.insert("ether");
+
+ // determine the interfaces on which channels should be created
+ auto netifs = context.listNetifs() |
+ boost::adaptors::filtered([this] (const NetworkInterfaceInfo& netif) {
+ return netif.isUp() && !netif.isLoopback();
+ });
+
+ // create channels
+ for (const auto& netif : netifs) {
+ auto channel = this->createChannel(netif, time::seconds(idleTimeout));
+ if (wantListen && !channel->isListening()) {
+ try {
+ channel->listen(context.addFace, nullptr);
+ }
+ catch (const EthernetChannel::Error& e) {
+ NFD_LOG_WARN("Cannot listen on " << netif.name << ": " << e.what());
+ }
+ }
+ }
+ }
+ else if (!m_channels.empty()) {
+ NFD_LOG_WARN("Cannot disable dev channels after initialization");
+ }
+
if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
if (mcastConfig.isEnabled) {
NFD_LOG_INFO("enabling multicast on " << mcastConfig.group);
@@ -139,13 +175,66 @@
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onFailure)
{
- onFailure(406, "Unsupported protocol");
+ BOOST_ASSERT(remoteUri.isCanonical());
+
+ if (!localUri || localUri->getScheme() != "dev") {
+ NFD_LOG_TRACE("Cannot create unicast Ethernet face without dev:// LocalUri");
+ onFailure(406, "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
+ return;
+ }
+ BOOST_ASSERT(localUri->isCanonical());
+
+ if (persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
+ NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
+ onFailure(406, "Outgoing Ethernet faces do not support on-demand persistency");
+ return;
+ }
+
+ ethernet::Address remoteEndpoint(ethernet::Address::fromString(remoteUri.getHost()));
+ std::string localEndpoint(localUri->getHost());
+
+ if (remoteEndpoint.isMulticast()) {
+ NFD_LOG_TRACE("createFace does not support multicast faces");
+ onFailure(406, "Cannot create multicast Ethernet faces");
+ return;
+ }
+
+ if (wantLocalFieldsEnabled) {
+ // Ethernet faces are never local
+ 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;
+ }
+
+ for (const auto& i : m_channels) {
+ if (i.first == localEndpoint) {
+ i.second->connect(remoteEndpoint, persistency, onCreated, onFailure);
+ return;
+ }
+ }
+
+ NFD_LOG_TRACE("No channels available to connect to " << remoteEndpoint);
+ onFailure(504, "No channels available to connect");
+}
+
+shared_ptr<EthernetChannel>
+EthernetFactory::createChannel(const NetworkInterfaceInfo& localEndpoint,
+ time::nanoseconds idleTimeout)
+{
+ auto it = m_channels.find(localEndpoint.name);
+ if (it != m_channels.end())
+ return it->second;
+
+ auto channel = std::make_shared<EthernetChannel>(localEndpoint, idleTimeout);
+ m_channels[localEndpoint.name] = channel;
+
+ return channel;
}
std::vector<shared_ptr<const Channel>>
EthernetFactory::getChannels() const
{
- return {};
+ return getChannelsFromMap(m_channels);
}
shared_ptr<Face>
@@ -197,8 +286,7 @@
face = this->createMulticastFace(netif, m_mcastConfig.group);
}
catch (const EthernetTransport::Error& e) {
- NFD_LOG_ERROR("Cannot create Ethernet multicast face on " << netif.name << ": " <<
- e.what() << ", continuing");
+ NFD_LOG_WARN("Cannot create Ethernet multicast face on " << netif.name << ": " << e.what());
continue;
}
diff --git a/daemon/face/ethernet-factory.hpp b/daemon/face/ethernet-factory.hpp
index 856116f..1cbe4e9 100644
--- a/daemon/face/ethernet-factory.hpp
+++ b/daemon/face/ethernet-factory.hpp
@@ -27,13 +27,12 @@
#define NFD_DAEMON_FACE_ETHERNET_FACTORY_HPP
#include "protocol-factory.hpp"
+#include "ethernet-channel.hpp"
namespace nfd {
namespace face {
/** \brief protocol factory for Ethernet
- *
- * Currently, only Ethernet multicast is supported.
*/
class EthernetFactory : public ProtocolFactory
{
@@ -47,8 +46,6 @@
processConfig(OptionalConfigSection configSection,
FaceSystem::ConfigContext& context) override;
- /** \brief unicast face creation is not supported and will always fail
- */
void
createFace(const FaceUri& remoteUri,
const ndn::optional<FaceUri>& localUri,
@@ -57,26 +54,45 @@
const FaceCreatedCallback& onCreated,
const FaceCreationFailedCallback& onFailure) override;
- /** \return empty container, because Ethernet unicast is not supported
+ /**
+ * \brief Create Ethernet-based channel on the specified network interface
+ *
+ * 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
+ * is thrown if it cannot be created.
+ * \throw PcapHelper::Error
*/
+ shared_ptr<EthernetChannel>
+ createChannel(const NetworkInterfaceInfo& localEndpoint,
+ time::nanoseconds idleTimeout);
+
std::vector<shared_ptr<const Channel>>
getChannels() const override;
-private:
- /** \brief Create a face to communicate on the given Ethernet multicast group
- * \param netif local network interface
- * \param group multicast group address
- * \note Calling this method again with same arguments returns the existing face on the given
- * interface and multicast group rather than creating a new one.
- * \throw EthernetTransport::Error transport creation fails
+ /**
+ * \brief Create a face to communicate on the given Ethernet multicast group
+ *
+ * If this method is called twice with the same arguments, only one face
+ * will be created. The second call will just return the existing face.
+ *
+ * \param netif local network interface
+ * \param group multicast group address
+ *
+ * \throw EthernetTransport::Error transport creation fails
*/
shared_ptr<Face>
- createMulticastFace(const NetworkInterfaceInfo& netif, const ethernet::Address& group);
+ createMulticastFace(const NetworkInterfaceInfo& netif,
+ const ethernet::Address& group);
+private:
void
applyConfig(const FaceSystem::ConfigContext& context);
private:
+ std::map<std::string, shared_ptr<EthernetChannel>> m_channels; ///< ifname => channel
+
struct MulticastConfig
{
bool isEnabled = false;
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 49f1307..3132796 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -144,11 +144,8 @@
tcp::Endpoint endpoint(ip::address::from_string(remoteUri.getHost()),
boost::lexical_cast<uint16_t>(remoteUri.getPort()));
- if (endpoint.address().is_multicast()) {
- NFD_LOG_TRACE("createFace does not support multicast faces");
- onFailure(406, "Cannot create multicast TCP faces");
- return;
- }
+ // a canonical tcp4/tcp6 FaceUri cannot have a multicast address
+ BOOST_ASSERT(!endpoint.address().is_multicast());
if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end()) {
NFD_LOG_TRACE("Requested endpoint is prohibited "
@@ -172,7 +169,7 @@
}
}
- NFD_LOG_TRACE("No channels available to connect to " + boost::lexical_cast<std::string>(endpoint));
+ NFD_LOG_TRACE("No channels available to connect to " << endpoint);
onFailure(504, "No channels available to connect");
}
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index 35a51d7..4576c65 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -59,15 +59,11 @@
*
* tcp::Endpoint is really 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.
+ * 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.
*
- * \returns always a valid pointer to a TcpChannel object, an exception
- * is thrown if it cannot be created.
- *
- * \see http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__tcp/endpoint.html
- * for details on ways to create tcp::Endpoint
+ * \return always a valid pointer to a TcpChannel object, an exception
+ * is thrown if it cannot be created.
*/
shared_ptr<TcpChannel>
createChannel(const tcp::Endpoint& localEndpoint);
@@ -75,10 +71,11 @@
/**
* \brief Create TCP-based channel using specified IP address and port number
*
- * This method is just a helper that converts a string representation of localIp and port to
- * tcp::Endpoint and calls the other createChannel overload.
+ * This method is just a helper that converts the string representation of \p localIp
+ * and \p localPort to tcp::Endpoint and calls the other createChannel overload.
*
- * \throws std::runtime_error
+ * \return always a valid pointer to a UdpChannel object, an exception
+ * is thrown if it cannot be created.
*/
shared_ptr<TcpChannel>
createChannel(const std::string& localIp, const std::string& localPort);
@@ -100,8 +97,8 @@
/**
* \brief Look up TcpChannel using specified local endpoint
*
- * \returns shared pointer to the existing TcpChannel object
- * or empty shared pointer when such channel does not exist
+ * \return shared pointer to the existing TcpChannel object
+ * or empty shared pointer when such channel does not exist
*/
shared_ptr<TcpChannel>
findChannel(const tcp::Endpoint& localEndpoint) const;
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index a544edf..5b68061 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -219,7 +219,7 @@
if (persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
- onFailure(406, "Outgoing unicast UDP faces do not support on-demand persistency");
+ onFailure(406, "Outgoing UDP faces do not support on-demand persistency");
return;
}
@@ -255,7 +255,7 @@
}
}
- NFD_LOG_TRACE("No channels available to connect to " + boost::lexical_cast<std::string>(endpoint));
+ NFD_LOG_TRACE("No channels available to connect to " << endpoint);
onFailure(504, "No channels available to connect");
}
@@ -307,38 +307,38 @@
}
shared_ptr<UdpChannel>
-UdpFactory::createChannel(const udp::Endpoint& endpoint,
- const time::seconds& timeout)
+UdpFactory::createChannel(const udp::Endpoint& localEndpoint,
+ time::nanoseconds idleTimeout)
{
- auto channel = findChannel(endpoint);
- if (channel)
- return channel;
+ auto it = m_channels.find(localEndpoint);
+ if (it != m_channels.end())
+ return it->second;
- if (endpoint.address().is_multicast()) {
+ if (localEndpoint.address().is_multicast()) {
BOOST_THROW_EXCEPTION(Error("createChannel is only for unicast channels. The provided endpoint "
"is multicast. Use createMulticastFace to create a multicast face"));
}
// check if the endpoint is already used by a multicast face
- auto face = findMulticastFace(endpoint);
- if (face) {
+ if (m_mcastFaces.find(localEndpoint) != m_mcastFaces.end()) {
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP unicast channel, local "
"endpoint is already allocated for a UDP multicast face"));
}
- channel = std::make_shared<UdpChannel>(endpoint, timeout);
- m_channels[endpoint] = channel;
- prohibitEndpoint(endpoint);
+ auto channel = std::make_shared<UdpChannel>(localEndpoint, idleTimeout);
+ m_channels[localEndpoint] = channel;
+ prohibitEndpoint(localEndpoint);
+
return channel;
}
shared_ptr<UdpChannel>
UdpFactory::createChannel(const std::string& localIp, const std::string& localPort,
- const time::seconds& timeout)
+ time::nanoseconds idleTimeout)
{
udp::Endpoint endpoint(ip::address::from_string(localIp),
boost::lexical_cast<uint16_t>(localPort));
- return createChannel(endpoint, timeout);
+ return createChannel(endpoint, idleTimeout);
}
std::vector<shared_ptr<const Channel>>
@@ -347,26 +347,16 @@
return getChannelsFromMap(m_channels);
}
-shared_ptr<UdpChannel>
-UdpFactory::findChannel(const udp::Endpoint& localEndpoint) const
-{
- auto i = m_channels.find(localEndpoint);
- if (i != m_channels.end())
- return i->second;
- else
- return nullptr;
-}
-
shared_ptr<Face>
UdpFactory::createMulticastFace(const udp::Endpoint& localEndpoint,
const udp::Endpoint& multicastEndpoint,
- const std::string& networkInterfaceName/* = ""*/)
+ const std::string& networkInterfaceName)
{
// checking if the local and multicast endpoints are already in use for a multicast face
- auto face = findMulticastFace(localEndpoint);
- if (face) {
- if (face->getRemoteUri() == FaceUri(multicastEndpoint))
- return face;
+ auto it = m_mcastFaces.find(localEndpoint);
+ if (it != m_mcastFaces.end()) {
+ if (it->second->getRemoteUri() == FaceUri(multicastEndpoint))
+ return it->second;
else
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, local "
"endpoint is already allocated for a UDP multicast face "
@@ -374,8 +364,7 @@
}
// checking if the local endpoint is already in use for a unicast channel
- auto unicastCh = findChannel(localEndpoint);
- if (unicastCh) {
+ if (m_channels.find(localEndpoint) != m_channels.end()) {
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, local "
"endpoint is already allocated for a UDP unicast channel"));
}
@@ -441,7 +430,7 @@
std::move(receiveSocket),
std::move(sendSocket),
m_mcastConfig.linkType);
- face = make_shared<Face>(std::move(linkService), std::move(transport));
+ auto face = make_shared<Face>(std::move(linkService), std::move(transport));
m_mcastFaces[localEndpoint] = face;
connectFaceClosedSignal(*face, [this, localEndpoint] { m_mcastFaces.erase(localEndpoint); });
@@ -453,7 +442,7 @@
UdpFactory::createMulticastFace(const std::string& localIp,
const std::string& multicastIp,
const std::string& multicastPort,
- const std::string& networkInterfaceName/* = ""*/)
+ const std::string& networkInterfaceName)
{
udp::Endpoint localEndpoint(ip::address::from_string(localIp),
boost::lexical_cast<uint16_t>(multicastPort));
@@ -462,16 +451,6 @@
return createMulticastFace(localEndpoint, multicastEndpoint, networkInterfaceName);
}
-shared_ptr<Face>
-UdpFactory::findMulticastFace(const udp::Endpoint& localEndpoint) const
-{
- auto i = m_mcastFaces.find(localEndpoint);
- if (i != m_mcastFaces.end())
- return i->second;
- else
- return nullptr;
-}
-
void
UdpFactory::applyMulticastConfig(const FaceSystem::ConfigContext& context)
{
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index ce6d2e5..3ebf0a3 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -75,46 +75,37 @@
*
* udp::Endpoint is really an alias for boost::asio::ip::udp::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.
+ * 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.
*
* If a multicast face is already active on the same local endpoint,
- * the creation fails and an exception is thrown
+ * the creation fails and an exception is thrown.
*
- * Once a face is created, if it doesn't send/receive anything for
- * a period of time equal to timeout, it will be destroyed
- * @todo this funcionality has to be implemented
- *
- * \returns always a valid pointer to a UdpChannel object, an exception
- * is thrown if it cannot be created.
- *
- * \throws UdpFactory::Error
- *
- * \see http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__udp/endpoint.html
- * for details on ways to create udp::Endpoint
+ * \return always a valid pointer to a UdpChannel object, an exception
+ * is thrown if it cannot be created.
+ * \throw UdpFactory::Error
*/
shared_ptr<UdpChannel>
createChannel(const udp::Endpoint& localEndpoint,
- const time::seconds& timeout = time::seconds(600));
+ time::nanoseconds idleTimeout);
/**
* \brief Create UDP-based channel using specified IP address and port number
*
- * This method is just a helper that converts a string representation of localIp and port to
- * udp::Endpoint and calls the other createChannel overload.
+ * This method is just a helper that converts the string representation of \p localIp
+ * and \p localPort to udp::Endpoint and calls the other createChannel overload.
*
- * If localHost is a IPv6 address of a specific device, it must be in the form:
- * ip address%interface name
- * Example: fe80::5e96:9dff:fe7d:9c8d%en1
- * Otherwise, you can use ::
+ * If \p localIp is an IPv6 address of a specific device, it must be in the form
+ * <tt>[ip address]%[interface name]</tt>, e.g. <tt>"fe80::5e96:9dff:fe7d:9c8d%en1"</tt>.
+ * Otherwise, you can use <tt>"::"</tt>.
*
- * \throws UdpChannel::Error if the bind on the socket fails
- * \throws UdpFactory::Error
+ * \return always a valid pointer to a UdpChannel object, an exception
+ * is thrown if it cannot be created.
+ * \throw UdpFactory::Error
*/
shared_ptr<UdpChannel>
createChannel(const std::string& localIp, const std::string& localPort,
- const time::seconds& timeout = time::seconds(600));
+ time::nanoseconds idleTimeout = time::seconds(600));
std::vector<shared_ptr<const Channel>>
getChannels() const override;
@@ -124,14 +115,13 @@
*
* udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
*
- * The face will join the multicast group
+ * The face will join the specified multicast group.
*
- * If this method called twice with the same endpoint and group, only one face
- * will be created. The second call will just retrieve the existing
- * channel.
+ * If this method is called twice with the same pair of endpoints, only one
+ * face will be created. The second call will just return the existing face.
*
* If an unicast face is already active on the same local NIC and port, the
- * creation fails and an exception is thrown
+ * creation fails and an exception is thrown.
*
* \param localEndpoint local endpoint
* \param multicastEndpoint multicast endpoint
@@ -141,14 +131,9 @@
* An empty string can be provided in other system or in linux machine with only one
* MulticastUdpFace per multicast group
*
- *
- * \returns always a valid pointer to a MulticastUdpFace object, an exception
- * is thrown if it cannot be created.
- *
- * \throws UdpFactory::Error
- *
- * \see http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__udp/endpoint.html
- * for details on ways to create udp::Endpoint
+ * \return always a valid pointer to a MulticastUdpFace object, an exception
+ * is thrown if it cannot be created.
+ * \throw UdpFactory::Error
*/
shared_ptr<Face>
createMulticastFace(const udp::Endpoint& localEndpoint,
@@ -172,24 +157,6 @@
prohibitAllIpv6Endpoints(uint16_t port);
private:
- /**
- * \brief Look up UdpChannel using specified local endpoint
- *
- * \returns shared pointer to the existing UdpChannel object
- * or nullptr when such channel does not exist
- */
- shared_ptr<UdpChannel>
- findChannel(const udp::Endpoint& localEndpoint) const;
-
- /**
- * \brief Look up multicast UdpFace using specified local endpoint
- *
- * \returns shared pointer to the existing multicast UdpFace object
- * or nullptr when such face does not exist
- */
- shared_ptr<Face>
- findMulticastFace(const udp::Endpoint& localEndpoint) const;
-
void
applyMulticastConfig(const FaceSystem::ConfigContext& context);
diff --git a/nfd.conf.sample.in b/nfd.conf.sample.in
index b763e0c..7e4c940 100644
--- a/nfd.conf.sample.in
+++ b/nfd.conf.sample.in
@@ -81,13 +81,13 @@
face_system
{
; The unix section contains settings of Unix stream faces and channels.
- ; Unix channel is always listening; delete unix section to disable
+ ; A Unix channel is always listening; delete the unix section to disable
; Unix stream faces and channels.
;
- ; The ndn-cxx library expects unix:///var/run/nfd.sock
- ; to be used as the default transport option. Please change
- ; the "transport" field in client.conf to an appropriate tcp4 FaceUri
- ; if you need to disable unix sockets.
+ ; The ndn-cxx library expects unix:///var/run/nfd.sock to be used as
+ ; the default transport option. Please change the "transport" field
+ ; in client.conf to an appropriate tcp4 FaceUri if you want to
+ ; disable Unix sockets and use TCP instead.
unix
{
path /var/run/nfd.sock ; Unix stream listener path
@@ -103,37 +103,40 @@
}
; The udp section contains settings of UDP faces and channels.
- ; UDP channel is always listening; delete udp section to disable UDP
udp
{
+ ; UDP unicast settings.
+ ; UDP channels are always listening; delete the udp section to disable them
port 6363 ; UDP unicast port number
enable_v4 yes ; set to 'no' to disable IPv4 channels, default 'yes'
enable_v6 yes ; set to 'no' to disable IPv6 channels, default 'yes'
- ; idle time (seconds) before closing a UDP unicast face, the actual timeout would be
- ; anywhere within [idle_timeout, 2*idle_timeout), default is 600
+ ; Time (in seconds) before closing an idle UDP unicast face.
+ ; The actual timeout will occur anytime between idle_timeout and 2*idle_timeout.
+ ; The default is 600 (10 minutes).
idle_timeout 600
keep_alive_interval 25; interval (seconds) between keep-alive refreshes
- ; UDP multicast settings
- ; By default, NFD creates one UDP multicast face per NIC
+ ; UDP multicast settings.
+ ; By default, NFD creates one UDP multicast face per NIC.
;
; In multi-homed Linux machines these settings will NOT work without
- ; root or settings the appropriate permissions:
+ ; root or setting the appropriate permissions:
;
- ; sudo setcap cap_net_raw=eip /full/path/nfd
+ ; sudo setcap cap_net_raw=eip /path/to/nfd
;
mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
mcast_port 56363 ; UDP multicast port number
- mcast_ad_hoc no ; set 'yes' to make all UDP multicast faces "ad hoc", default 'no'
+ mcast_ad_hoc no ; set to 'yes' to make all UDP multicast faces "ad hoc", default 'no'
; Whitelist and blacklist can contain, in no particular order:
- ; interface names, including wildcard patterns (e.g., 'ifname eth0', 'ifname en*', 'ifname wlp?s0'),
- ; mac addresses (e.g., 'ether 85:3b:4d:d3:5f:c2'),
- ; subnets (e.g., 'subnet 192.0.2.0/24', note that only IPv4 is supported here),
- ; or a single asterisk ('*') that matches all interfaces.
+ ; - interface names, including wildcard patterns (e.g., 'ifname eth0', 'ifname en*', 'ifname wlp?s0')
+ ; - mac addresses (e.g., 'ether 85:3b:4d:d3:5f:c2')
+ ; - subnets (e.g., 'subnet 192.0.2.0/24', note that only IPv4 is supported here)
+ ; - a single asterisk ('*') that matches all interfaces
+ ; By default, all interfaces are whitelisted.
whitelist
{
*
@@ -147,7 +150,7 @@
; These settings will NOT work without root or setting the appropriate
; permissions:
;
- ; sudo setcap cap_net_raw,cap_net_admin=eip /full/path/nfd
+ ; sudo setcap cap_net_raw,cap_net_admin=eip /path/to/nfd
;
; You may need to install a package to use setcap:
;
@@ -168,18 +171,26 @@
;
@IF_HAVE_LIBPCAP@ether
@IF_HAVE_LIBPCAP@{
- @IF_HAVE_LIBPCAP@ ; Ethernet multicast settings
- @IF_HAVE_LIBPCAP@ ; By default, NFD creates one Ethernet multicast face per NIC
+ @IF_HAVE_LIBPCAP@ ; Ethernet unicast settings.
+ @IF_HAVE_LIBPCAP@ listen yes ; set to 'no' to disable Ethernet listener, default 'yes'
@IF_HAVE_LIBPCAP@
+ @IF_HAVE_LIBPCAP@ ; Time (in seconds) before closing an idle Ethernet unicast face.
+ @IF_HAVE_LIBPCAP@ ; The actual timeout will occur anytime between idle_timeout and 2*idle_timeout.
+ @IF_HAVE_LIBPCAP@ ; The default is 600 (10 minutes).
+ @IF_HAVE_LIBPCAP@ idle_timeout 600
+ @IF_HAVE_LIBPCAP@
+ @IF_HAVE_LIBPCAP@ ; Ethernet multicast settings.
+ @IF_HAVE_LIBPCAP@ ; By default, NFD creates one Ethernet multicast face per NIC.
@IF_HAVE_LIBPCAP@ mcast yes ; set to 'no' to disable Ethernet multicast, default 'yes'
@IF_HAVE_LIBPCAP@ mcast_group 01:00:5E:00:17:AA ; Ethernet multicast group
- @IF_HAVE_LIBPCAP@ mcast_ad_hoc no ; set to 'yes' to make all Ethernet faces 'ad hoc', default 'no'
+ @IF_HAVE_LIBPCAP@ mcast_ad_hoc no ; set to 'yes' to make all Ethernet multicast faces "ad hoc", default 'no'
@IF_HAVE_LIBPCAP@
@IF_HAVE_LIBPCAP@ ; Whitelist and blacklist can contain, in no particular order:
- @IF_HAVE_LIBPCAP@ ; interface names, including wildcard patterns (e.g., 'ifname eth0', 'ifname en*', 'ifname wlp?s0'),
- @IF_HAVE_LIBPCAP@ ; mac addresses (e.g., 'ether 85:3b:4d:d3:5f:c2'),
- @IF_HAVE_LIBPCAP@ ; subnets (e.g., 'subnet 192.0.2.0/24', note that only IPv4 is supported here),
- @IF_HAVE_LIBPCAP@ ; or a single asterisk ('*') that matches all interfaces.
+ @IF_HAVE_LIBPCAP@ ; - interface names, including wildcard patterns (e.g., 'ifname eth0', 'ifname en*', 'ifname wlp?s0')
+ @IF_HAVE_LIBPCAP@ ; - mac addresses (e.g., 'ether 85:3b:4d:d3:5f:c2')
+ @IF_HAVE_LIBPCAP@ ; - subnets (e.g., 'subnet 192.0.2.0/24', note that only IPv4 is supported here)
+ @IF_HAVE_LIBPCAP@ ; - a single asterisk ('*') that matches all interfaces
+ @IF_HAVE_LIBPCAP@ ; By default, all interfaces are whitelisted.
@IF_HAVE_LIBPCAP@ whitelist
@IF_HAVE_LIBPCAP@ {
@IF_HAVE_LIBPCAP@ *
diff --git a/tests/daemon/face/ethernet-factory.t.cpp b/tests/daemon/face/ethernet-factory.t.cpp
index 5e7c6d2..953a35f 100644
--- a/tests/daemon/face/ethernet-factory.t.cpp
+++ b/tests/daemon/face/ethernet-factory.t.cpp
@@ -326,25 +326,44 @@
EthernetFactory factory;
createFace(factory,
- FaceUri("ether://[08:00:27:01:01:01]"),
- {},
- ndn::nfd::FACE_PERSISTENCY_PERMANENT,
- false,
- {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
-
- createFace(factory,
- FaceUri("ether://[08:00:27:01:01:01]"),
- {},
- ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
- false,
- {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
-
- createFace(factory,
- FaceUri("ether://[08:00:27:01:01:01]"),
+ FaceUri("ether://[00:00:5e:00:53:5e]"),
{},
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
false,
- {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
+
+ createFace(factory,
+ FaceUri("ether://[00:00:5e:00:53:5e]"),
+ FaceUri("udp4://127.0.0.1:20071"),
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ false,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
+
+ createFace(factory,
+ FaceUri("ether://[00:00:5e:00:53:5e]"),
+ FaceUri("dev://eth0"),
+ ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
+ false,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Outgoing Ethernet faces do not support on-demand persistency"});
+
+ createFace(factory,
+ FaceUri("ether://[01:00:5e:90:10:5e]"),
+ FaceUri("dev://eth0"),
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ false,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Cannot create multicast Ethernet faces"});
+
+ createFace(factory,
+ FaceUri("ether://[00:00:5e:00:53:5e]"),
+ FaceUri("dev://eth0"),
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ true,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Local fields can only be enabled on faces with local scope"});
}
BOOST_AUTO_TEST_SUITE_END() // TestEthernetFactory
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index d3f5fc9..7f93d78 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -204,25 +204,39 @@
BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
{
TcpFactory factory;
-
factory.createChannel("127.0.0.1", "20071");
- factory.createChannel("127.0.0.1", "20072");
createFace(factory,
+ FaceUri("tcp4://127.0.0.1:20072"),
FaceUri("tcp4://127.0.0.1:20071"),
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ false,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Unicast TCP faces cannot be created with a LocalUri"});
+
+ createFace(factory,
+ FaceUri("tcp4://127.0.0.1:20072"),
{},
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
false,
{CreateFaceExpectedResult::FAILURE, 406,
- "Outgoing TCP faces do not support on-demand persistency"});
+ "Outgoing TCP faces do not support on-demand persistency"});
createFace(factory,
- FaceUri("tcp4://127.0.0.1:20072"),
- FaceUri("tcp4://127.0.0.1:20073"),
+ FaceUri("tcp4://127.0.0.1:20071"),
+ {},
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
false,
{CreateFaceExpectedResult::FAILURE, 406,
- "Unicast TCP faces cannot be created with a LocalUri"});
+ "Requested endpoint is prohibited"});
+
+ createFace(factory,
+ FaceUri("tcp4://198.51.100.100:6363"),
+ {},
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ true,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Local fields can only be enabled on faces with local scope"});
}
class FaceCreateTimeoutFixture : public BaseFixture
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index 3270ad6..9677abe 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -635,25 +635,47 @@
BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
{
UdpFactory factory;
-
factory.createChannel("127.0.0.1", "20071");
- factory.createChannel("127.0.0.1", "20072");
createFace(factory,
+ FaceUri("udp4://127.0.0.1:20072"),
FaceUri("udp4://127.0.0.1:20071"),
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ false,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Unicast UDP faces cannot be created with a LocalUri"});
+
+ createFace(factory,
+ FaceUri("udp4://127.0.0.1:20072"),
{},
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
false,
{CreateFaceExpectedResult::FAILURE, 406,
- "Outgoing unicast UDP faces do not support on-demand persistency"});
+ "Outgoing UDP faces do not support on-demand persistency"});
createFace(factory,
- FaceUri("udp4://127.0.0.1:20072"),
- FaceUri("udp4://127.0.0.1:20073"),
+ FaceUri("udp4://233.252.0.1:23252"),
+ {},
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
false,
{CreateFaceExpectedResult::FAILURE, 406,
- "Unicast UDP faces cannot be created with a LocalUri"});
+ "Cannot create multicast UDP faces"});
+
+ createFace(factory,
+ FaceUri("udp4://127.0.0.1:20071"),
+ {},
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ false,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Requested endpoint is prohibited"});
+
+ createFace(factory,
+ FaceUri("udp4://127.0.0.1:20072"),
+ {},
+ ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+ true,
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Local fields can only be enabled on faces with local scope"});
}
class FakeNetworkInterfaceFixture : public BaseFixture