mgmt: add support for enabling/disabling IPv4 or v6 channels
refs: #1461
Change-Id: I00bda4098c9a7722bce9d498acce339809af3f01
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 95b01e0..855bc85 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -253,6 +253,8 @@
std::string port = "6363";
bool needToListen = true;
+ bool enableV4 = true;
+ bool enableV6 = true;
for (ConfigSection::const_iterator i = configSection.begin();
i != configSection.end();
@@ -269,41 +271,64 @@
catch (const std::bad_cast& error)
{
throw ConfigFile::Error("Invalid value for option " +
- i->first + "\" in \"udp\" section");
+ i->first + "\" in \"tcp\" section");
}
}
else if (i->first == "listen")
{
needToListen = parseYesNo(i, i->first, "tcp");
}
+ else if (i->first == "enable_v4")
+ {
+ enableV4 = parseYesNo(i, i->first, "tcp");
+ }
+ else if (i->first == "enable_v6")
+ {
+ enableV6 = parseYesNo(i, i->first, "tcp");
+ }
else
{
throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
}
}
+ if (!enableV4 && !enableV6)
+ {
+ throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+ " Remove \"tcp\" section to disable TCP channels or"
+ " re-enable at least one channel type.");
+ }
+
if (!isDryRun)
{
shared_ptr<TcpFactory> factory = make_shared<TcpFactory>(boost::cref(port));
+ m_factories.insert(std::make_pair("tcp", factory));
- using namespace boost::asio::ip;
-
- shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
- shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
-
- if (needToListen)
+ if (enableV4)
{
- // Should acceptFailed callback be used somehow?
+ shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
+ if (needToListen)
+ {
+ // Should acceptFailed callback be used somehow?
+ ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+ TcpChannel::ConnectFailedCallback());
+ }
- ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
- TcpChannel::ConnectFailedCallback());
- ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
- TcpChannel::ConnectFailedCallback());
+ m_factories.insert(std::make_pair("tcp4", factory));
}
- m_factories.insert(std::make_pair("tcp", factory));
- m_factories.insert(std::make_pair("tcp4", factory));
- m_factories.insert(std::make_pair("tcp6", factory));
+ if (enableV6)
+ {
+ shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
+ if (needToListen)
+ {
+ // Should acceptFailed callback be used somehow?
+ ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+ TcpChannel::ConnectFailedCallback());
+ }
+
+ m_factories.insert(std::make_pair("tcp6", factory));
+ }
}
}
@@ -326,6 +351,8 @@
// }
std::string port = "6363";
+ bool enableV4 = true;
+ bool enableV6 = true;
size_t timeout = 30;
size_t keepAliveInterval = 25;
bool useMcast = true;
@@ -351,6 +378,14 @@
i->first + "\" in \"udp\" section");
}
}
+ else if (i->first == "enable_v4")
+ {
+ enableV4 = parseYesNo(i, i->first, "udp");
+ }
+ else if (i->first == "enable_v6")
+ {
+ enableV6 = parseYesNo(i, i->first, "udp");
+ }
else if (i->first == "idle_timeout")
{
try
@@ -421,29 +456,47 @@
}
}
+ if (!enableV4 && !enableV6)
+ {
+ throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+ " Remove \"udp\" section to disable UDP channels or"
+ " re-enable at least one channel type.");
+ }
+ else if (useMcast && !enableV4)
+ {
+ throw ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
+ " have been disabled (conflicting configuration options set)");
+ }
+
/// \todo what is keep alive interval used for?
if (!isDryRun)
{
shared_ptr<UdpFactory> factory = make_shared<UdpFactory>(boost::cref(port));
-
- shared_ptr<UdpChannel> v4Channel =
- factory->createChannel("0.0.0.0", port, time::seconds(timeout));
-
- shared_ptr<UdpChannel> v6Channel =
- factory->createChannel("::", port, time::seconds(timeout));
-
- v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
- UdpChannel::ConnectFailedCallback());
-
- v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
- UdpChannel::ConnectFailedCallback());
-
m_factories.insert(std::make_pair("udp", factory));
- m_factories.insert(std::make_pair("udp4", factory));
- m_factories.insert(std::make_pair("udp6", factory));
- if (useMcast)
+ if (enableV4)
+ {
+ shared_ptr<UdpChannel> v4Channel =
+ factory->createChannel("0.0.0.0", port, time::seconds(timeout));
+
+ v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+ UdpChannel::ConnectFailedCallback());
+
+ m_factories.insert(std::make_pair("udp4", factory));
+ }
+
+ if (enableV6)
+ {
+ shared_ptr<UdpChannel> v6Channel =
+ factory->createChannel("::", port, time::seconds(timeout));
+
+ v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+ UdpChannel::ConnectFailedCallback());
+ m_factories.insert(std::make_pair("udp6", factory));
+ }
+
+ if (useMcast && enableV4)
{
for (std::list<shared_ptr<NetworkInterfaceInfo> >::const_iterator i = nicList.begin();
i != nicList.end();
diff --git a/nfd.conf.sample.in b/nfd.conf.sample.in
index b825cca..11cd009 100644
--- a/nfd.conf.sample.in
+++ b/nfd.conf.sample.in
@@ -50,12 +50,17 @@
{
listen yes ; set to 'no' to disable TCP listener, default 'yes'
port 6363 ; TCP listener 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'
}
; The udp section contains settings of UDP faces and channels.
+ ; UDP channel is always listening; delete udp section to disable UDP
udp
{
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_timeout 600 ; idle time (seconds) before closing a UDP unicast face
keep_alive_interval 25; interval (seconds) between keep-alive refreshes
diff --git a/tests/mgmt/face-manager.cpp b/tests/mgmt/face-manager.cpp
index 3b07274..c410878 100644
--- a/tests/mgmt/face-manager.cpp
+++ b/tests/mgmt/face-manager.cpp
@@ -400,6 +400,8 @@
" {\n"
" listen yes\n"
" port 6363\n"
+ " enable_v4 yes\n"
+ " enable_v6 yes\n"
" }\n"
"}\n";
try
@@ -425,6 +427,8 @@
" {\n"
" listen yes\n"
" port 6363\n"
+ " enable_v4 yes\n"
+ " enable_v6 yes\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
@@ -445,6 +449,25 @@
"Invalid value for option \"listen\" in \"tcp\" section"));
}
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpChannelsDisabled)
+{
+ const std::string CONFIG =
+ "face_system\n"
+ "{\n"
+ " tcp\n"
+ " {\n"
+ " port 6363\n"
+ " enable_v4 no\n"
+ " enable_v6 no\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+ bind(&isExpectedException, _1,
+ "IPv4 and IPv6 channels have been disabled."
+ " Remove \"tcp\" section to disable TCP channels or"
+ " re-enable at least one channel type."));
+}
+
BOOST_AUTO_TEST_CASE(TestProcessSectionTcpUnknownOption)
{
const std::string CONFIG =
@@ -468,6 +491,8 @@
" udp\n"
" {\n"
" port 6363\n"
+ " enable_v4 yes\n"
+ " enable_v6 yes\n"
" idle_timeout 30\n"
" keep_alive_interval 25\n"
" mcast yes\n"
@@ -564,6 +589,55 @@
"Invalid value for option \"mcast_group\" in \"udp\" section"));
}
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpChannelsDisabled)
+{
+ const std::string CONFIG =
+ "face_system\n"
+ "{\n"
+ " udp\n"
+ " {\n"
+ " port 6363\n"
+ " enable_v4 no\n"
+ " enable_v6 no\n"
+ " idle_timeout 30\n"
+ " keep_alive_interval 25\n"
+ " mcast yes\n"
+ " mcast_port 56363\n"
+ " mcast_group 224.0.23.170\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+ bind(&isExpectedException, _1,
+ "IPv4 and IPv6 channels have been disabled."
+ " Remove \"udp\" section to disable UDP channels or"
+ " re-enable at least one channel type."));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpConflictingMcast)
+{
+ const std::string CONFIG =
+ "face_system\n"
+ "{\n"
+ " udp\n"
+ " {\n"
+ " port 6363\n"
+ " enable_v4 no\n"
+ " enable_v6 yes\n"
+ " idle_timeout 30\n"
+ " keep_alive_interval 25\n"
+ " mcast yes\n"
+ " mcast_port 56363\n"
+ " mcast_group 224.0.23.170\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+ bind(&isExpectedException, _1,
+ "IPv4 multicast requested, but IPv4 channels"
+ " have been disabled (conflicting configuration options set)"));
+}
+
+
+
BOOST_AUTO_TEST_CASE(TestProcessSectionUdpUnknownOption)
{
const std::string CONFIG =