face: configuration option to make UDP multicast face "ad hoc"
Change-Id: Ifd407f42e9646826697f73ab1890c819fce16857
Refs: #4018, #3967
diff --git a/daemon/face/multicast-udp-transport.cpp b/daemon/face/multicast-udp-transport.cpp
index 34bef0c..7b3fca3 100644
--- a/daemon/face/multicast-udp-transport.cpp
+++ b/daemon/face/multicast-udp-transport.cpp
@@ -35,7 +35,8 @@
MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& localEndpoint,
const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
- protocol::socket&& sendSocket)
+ protocol::socket&& sendSocket,
+ ndn::nfd::LinkType linkType)
: DatagramTransport(std::move(recvSocket))
, m_multicastGroup(multicastGroup)
, m_sendSocket(std::move(sendSocket))
@@ -44,7 +45,7 @@
this->setRemoteUri(FaceUri(multicastGroup));
this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
this->setPersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
- this->setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS);
+ this->setLinkType(linkType);
this->setMtu(udp::computeMtu(localEndpoint));
NFD_LOG_FACE_INFO("Creating transport");
diff --git a/daemon/face/multicast-udp-transport.hpp b/daemon/face/multicast-udp-transport.hpp
index 2b04eb7..9b903d0 100644
--- a/daemon/face/multicast-udp-transport.hpp
+++ b/daemon/face/multicast-udp-transport.hpp
@@ -51,11 +51,13 @@
* \param multicastGroup multicast group
* \param recvSocket socket used to receive packets
* \param sendSocket socket used to send to the multicast group
+ * \param linkType either LINK_TYPE_MULTI_ACCESS or LINK_TYPE_AD_HOC
*/
MulticastUdpTransport(const protocol::endpoint& localEndpoint,
const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
- protocol::socket&& sendSocket);
+ protocol::socket&& sendSocket,
+ ndn::nfd::LinkType linkType);
private:
void
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 8ea503c..d141e58 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -66,6 +66,7 @@
// mcast yes
// mcast_group 224.0.23.170
// mcast_port 56363
+ // mcast_ad_hoc no
// whitelist
// {
// *
@@ -123,6 +124,10 @@
else if (key == "mcast_port") {
mcastConfig.group.port(ConfigFile::parseNumber<uint16_t>(pair, "face_system.udp"));
}
+ else if (key == "mcast_ad_hoc") {
+ bool wantAdHoc = ConfigFile::parseYesNo(pair, "face_system.udp");
+ mcastConfig.linkType = wantAdHoc ? ndn::nfd::LINK_TYPE_AD_HOC : ndn::nfd::LINK_TYPE_MULTI_ACCESS;
+ }
else if (key == "whitelist") {
mcastConfig.netifPredicate.parseWhitelist(value);
}
@@ -176,18 +181,21 @@
NFD_LOG_INFO("disabling multicast");
}
}
- else if (m_mcastConfig.group != mcastConfig.group) {
- NFD_LOG_INFO("changing multicast group from " << m_mcastConfig.group <<
- " to " << mcastConfig.group);
- }
- else if (m_mcastConfig.netifPredicate != mcastConfig.netifPredicate) {
- NFD_LOG_INFO("changing whitelist/blacklist");
- }
- else {
- // There's no configuration change, but we still need to re-apply configuration because
- // netifs may have changed.
+ else if (mcastConfig.isEnabled) {
+ if (m_mcastConfig.linkType != mcastConfig.linkType && !m_mcastFaces.empty()) {
+ NFD_LOG_WARN("Cannot change ad hoc setting on existing faces");
+ }
+ if (m_mcastConfig.group != mcastConfig.group) {
+ NFD_LOG_INFO("changing multicast group from " << m_mcastConfig.group <<
+ " to " << mcastConfig.group);
+ }
+ if (m_mcastConfig.netifPredicate != mcastConfig.netifPredicate) {
+ NFD_LOG_INFO("changing whitelist/blacklist");
+ }
}
+ // Even if there's no configuration change, we still need to re-apply configuration because
+ // netifs may have changed.
m_mcastConfig = mcastConfig;
this->applyMulticastConfig(context);
}
@@ -427,7 +435,8 @@
auto linkService = make_unique<GenericLinkService>();
auto transport = make_unique<MulticastUdpTransport>(localEndpoint, multicastEndpoint,
std::move(receiveSocket),
- std::move(sendSocket));
+ std::move(sendSocket),
+ m_mcastConfig.linkType);
face = make_shared<Face>(std::move(linkService), std::move(transport));
m_mcastFaces[localEndpoint] = face;
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index 9b68448..e662e6a 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -199,6 +199,7 @@
{
bool isEnabled = false;
udp::Endpoint group = udp::getDefaultMulticastGroup();
+ ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS;
NetworkInterfacePredicate netifPredicate;
};
diff --git a/nfd.conf.sample.in b/nfd.conf.sample.in
index fe3efef..8d6f5d1 100644
--- a/nfd.conf.sample.in
+++ b/nfd.conf.sample.in
@@ -125,8 +125,9 @@
; sudo setcap cap_net_raw=eip /full/path/nfd
;
mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
- mcast_port 56363 ; UDP multicast port number
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'
; Whitelist and blacklist can contain, in no particular order:
; interface names, including wildcard patterns (e.g., 'ifname eth0', 'ifname en*', 'ifname wlp?s0'),
diff --git a/tests/daemon/face/multicast-udp-transport-fixture.hpp b/tests/daemon/face/multicast-udp-transport-fixture.hpp
index b8ed524..574cb58 100644
--- a/tests/daemon/face/multicast-udp-transport-fixture.hpp
+++ b/tests/daemon/face/multicast-udp-transport-fixture.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2016, Regents of the University of California,
+ * Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -63,10 +63,12 @@
udp::socket sockTx(g_io);
localEp = udp::endpoint(address, 7001);
openMulticastSockets(sockRx, sockTx, localEp.port());
+ ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS;
face = make_unique<Face>(
make_unique<DummyReceiveLinkService>(),
- make_unique<MulticastUdpTransport>(localEp, multicastEp, std::move(sockRx), std::move(sockTx)));
+ make_unique<MulticastUdpTransport>(localEp, multicastEp, std::move(sockRx),
+ std::move(sockTx), linkType));
transport = static_cast<MulticastUdpTransport*>(face->getTransport());
receivedPackets = &static_cast<DummyReceiveLinkService*>(face->getLinkService())->receivedPackets;
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index 265bf97..14a0aee 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -124,15 +124,15 @@
}
std::vector<const Face*>
- listUdpMcastFaces() const
+ listUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
{
- return this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS);
+ return this->listFacesByScheme("udp4", linkType);
}
size_t
- countUdpMcastFaces() const
+ countUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
{
- return this->listUdpMcastFaces().size();
+ return this->listUdpMcastFaces(linkType).size();
}
/** \brief determine whether a UDP multicast face is created on \p netif
@@ -199,6 +199,28 @@
BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
}
+BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpMcastConfigFixture)
+{
+#ifdef __linux__
+ // need superuser privilege for creating multicast faces on linux
+ SKIP_IF_NOT_SUPERUSER();
+#endif // __linux__
+ SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
+
+ const std::string CONFIG = R"CONFIG(
+ face_system
+ {
+ udp
+ {
+ mcast_ad_hoc yes
+ }
+ }
+ )CONFIG";
+
+ parseConfig(CONFIG, false);
+ BOOST_CHECK_EQUAL(this->countUdpMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC), netifs.size());
+}
+
BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpoint, UdpMcastConfigFixture)
{
#ifdef __linux__