face: Configurable IP subnets for "local" TCP faces
Change-Id: Idaddfe4b2c304b552d2e132235f4c3d3e6c2ebcb
Refs: #4546
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 821c6d7..058bbe5 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -24,9 +24,9 @@
*/
#include "tcp-channel.hpp"
+#include "core/global-io.hpp"
#include "generic-link-service.hpp"
#include "tcp-transport.hpp"
-#include "core/global-io.hpp"
namespace nfd {
namespace face {
@@ -35,11 +35,13 @@
namespace ip = boost::asio::ip;
-TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking)
+TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
+ DetermineFaceScopeFromAddress determineFaceScope)
: m_localEndpoint(localEndpoint)
, m_acceptor(getGlobalIoService())
, m_socket(getGlobalIoService())
, m_wantCongestionMarking(wantCongestionMarking)
+ , m_determineFaceScope(std::move(determineFaceScope))
{
setUri(FaceUri(m_localEndpoint));
NFD_LOG_CHAN_INFO("Creating channel");
@@ -122,7 +124,9 @@
}
auto linkService = make_unique<GenericLinkService>(options);
- auto transport = make_unique<TcpTransport>(std::move(socket), params.persistency);
+ auto faceScope = m_determineFaceScope(socket.local_endpoint().address(),
+ socket.remote_endpoint().address());
+ auto transport = make_unique<TcpTransport>(std::move(socket), params.persistency, faceScope);
face = make_shared<Face>(std::move(linkService), std::move(transport));
m_channelFaces[remoteEndpoint] = face;
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
index 0f4c79a..c840695 100644
--- a/daemon/face/tcp-channel.hpp
+++ b/daemon/face/tcp-channel.hpp
@@ -37,6 +37,9 @@
namespace face {
+using DetermineFaceScopeFromAddress = std::function<ndn::nfd::FaceScope(const boost::asio::ip::address& local,
+ const boost::asio::ip::address& remote)>;
+
/**
* \brief Class implementing TCP-based channel to create faces
*
@@ -53,7 +56,8 @@
* To enable creation faces upon incoming connections,
* one needs to explicitly call TcpChannel::listen method.
*/
- TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking);
+ TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
+ DetermineFaceScopeFromAddress determineFaceScope);
bool
isListening() const override
@@ -126,6 +130,7 @@
boost::asio::ip::tcp::socket m_socket;
std::map<tcp::Endpoint, shared_ptr<Face>> m_channelFaces;
bool m_wantCongestionMarking;
+ DetermineFaceScopeFromAddress m_determineFaceScope;
};
} // namespace face
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 1477e09..1831467 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -72,6 +72,8 @@
uint16_t port = 6363;
bool enableV4 = true;
bool enableV6 = true;
+ IpAddressPredicate local;
+ bool isLocalConfigured = false;
for (const auto& pair : *configSection) {
const std::string& key = pair.first;
@@ -88,10 +90,28 @@
else if (key == "enable_v6") {
enableV6 = ConfigFile::parseYesNo(pair, "face_system.tcp");
}
+ else if (key == "local") {
+ isLocalConfigured = true;
+ for (const auto& localPair : pair.second) {
+ const std::string& localKey = localPair.first;
+ if (localKey == "whitelist") {
+ local.parseWhitelist(localPair.second);
+ }
+ else if (localKey == "blacklist") {
+ local.parseBlacklist(localPair.second);
+ }
+ else {
+ BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option face_system.tcp.local." + localKey));
+ }
+ }
+ }
else {
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option face_system.tcp." + key));
}
}
+ if (!isLocalConfigured) {
+ local.assign({{"subnet", "127.0.0.0/8"}, {"subnet", "::1/128"}}, {});
+ }
if (!enableV4 && !enableV6) {
BOOST_THROW_EXCEPTION(ConfigFile::Error(
@@ -125,6 +145,8 @@
else if (providedSchemes.count("tcp6") > 0) {
NFD_LOG_WARN("Cannot close tcp6 channel after its creation");
}
+
+ m_local = std::move(local);
}
}
@@ -179,7 +201,8 @@
if (it != m_channels.end())
return it->second;
- auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking);
+ auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking,
+ bind(&TcpFactory::determineFaceScopeFromAddresses, this, _1, _2));
m_channels[endpoint] = channel;
return channel;
}
@@ -190,5 +213,15 @@
return getChannelsFromMap(m_channels);
}
+ndn::nfd::FaceScope
+TcpFactory::determineFaceScopeFromAddresses(const boost::asio::ip::address& localAddress,
+ const boost::asio::ip::address& remoteAddress) const
+{
+ if (m_local(localAddress) && m_local(remoteAddress)) {
+ return ndn::nfd::FACE_SCOPE_LOCAL;
+ }
+ return ndn::nfd::FACE_SCOPE_NON_LOCAL;
+}
+
} // namespace face
} // namespace nfd
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index 6d3dbce..dddcd40 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -72,8 +72,16 @@
getChannels() const override;
private:
+ ndn::nfd::FaceScope
+ determineFaceScopeFromAddresses(const boost::asio::ip::address& local,
+ const boost::asio::ip::address& remote) const;
+
+private:
bool m_wantCongestionMarking = false;
std::map<tcp::Endpoint, shared_ptr<TcpChannel>> m_channels;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+ IpAddressPredicate m_local;
};
} // namespace face
diff --git a/daemon/face/tcp-transport.cpp b/daemon/face/tcp-transport.cpp
index c95f693..eef8570 100644
--- a/daemon/face/tcp-transport.cpp
+++ b/daemon/face/tcp-transport.cpp
@@ -39,20 +39,14 @@
time::milliseconds TcpTransport::s_maxReconnectWait = time::minutes(5);
float TcpTransport::s_reconnectWaitMultiplier = 2.0f;
-TcpTransport::TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency)
+TcpTransport::TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency, ndn::nfd::FaceScope faceScope)
: StreamTransport(std::move(socket))
, m_remoteEndpoint(m_socket.remote_endpoint())
, m_nextReconnectWait(s_initialReconnectWait)
{
this->setLocalUri(FaceUri(m_socket.local_endpoint()));
this->setRemoteUri(FaceUri(m_socket.remote_endpoint()));
-
- if (m_socket.local_endpoint().address().is_loopback() &&
- m_socket.remote_endpoint().address().is_loopback())
- this->setScope(ndn::nfd::FACE_SCOPE_LOCAL);
- else
- this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
-
+ this->setScope(faceScope);
this->setPersistency(persistency);
this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
this->setMtu(MTU_UNLIMITED);
diff --git a/daemon/face/tcp-transport.hpp b/daemon/face/tcp-transport.hpp
index d6b0890..9367ffe 100644
--- a/daemon/face/tcp-transport.hpp
+++ b/daemon/face/tcp-transport.hpp
@@ -42,7 +42,7 @@
class TcpTransport FINAL_UNLESS_WITH_TESTS : public StreamTransport<boost::asio::ip::tcp>
{
public:
- TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency);
+ TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency, ndn::nfd::FaceScope faceScope);
ssize_t
getSendQueueLength() final;