Skip to content

Commit

Permalink
face: change default Unix socket path
Browse files Browse the repository at this point in the history
Refs: #5304
Change-Id: I5c7415874131b156e54a655960d9de47c1eae91d
  • Loading branch information
Pesa committed Jan 3, 2024
1 parent 9b877c3 commit 4c95771
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 62 deletions.
17 changes: 11 additions & 6 deletions daemon/face/unix-stream-channel.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, Regents of the University of California,
* Copyright (c) 2014-2024, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
Expand Down Expand Up @@ -49,11 +49,10 @@ UnixStreamChannel::UnixStreamChannel(const unix_stream::Endpoint& endpoint,
UnixStreamChannel::~UnixStreamChannel()
{
if (isListening()) {
// use the non-throwing variants during destruction
// and ignore any errors
// use the non-throwing variants during destruction and ignore any errors
boost::system::error_code error;
m_acceptor.close(error);
NFD_LOG_CHAN_DEBUG("Removing socket file");
NFD_LOG_CHAN_TRACE("Removing socket file");
boost::filesystem::remove(m_endpoint.path(), error);
}
}
Expand All @@ -70,7 +69,7 @@ UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,

namespace fs = boost::filesystem;

fs::path socketPath(m_endpoint.path());
fs::path socketPath = m_endpoint.path();
fs::file_type type = fs::symlink_status(socketPath).type();

if (type == fs::socket_file) {
Expand All @@ -80,7 +79,7 @@ UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
NFD_LOG_CHAN_TRACE("connect() on existing socket file returned: " << error.message());
if (!error) {
// someone answered, leave the socket alone
NDN_THROW(Error("Socket file at " + m_endpoint.path() + " belongs to another NFD process"));
NDN_THROW(Error("Socket file at " + m_endpoint.path() + " belongs to another process"));
}
else if (error == boost::asio::error::connection_refused ||
error == boost::asio::error::timed_out) {
Expand All @@ -94,6 +93,12 @@ UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
NDN_THROW(Error(m_endpoint.path() + " already exists and is not a socket file"));
}

// ensure parent directory exists before creating socket
fs::path parent = socketPath.parent_path();
if (!parent.empty() && fs::create_directories(parent)) {
NFD_LOG_CHAN_TRACE("Created directory " << parent);
}

m_acceptor.open();
m_acceptor.bind(m_endpoint);
m_acceptor.listen(backlog);
Expand Down
22 changes: 9 additions & 13 deletions daemon/face/unix-stream-factory.cpp
Original file line number Diff line number Diff line change
@@ -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-2024, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
Expand Down Expand Up @@ -45,8 +45,8 @@ UnixStreamFactory::doProcessConfig(OptionalConfigSection configSection,
{
// unix
// {
// path /run/nfd.sock ; on Linux
// path /var/run/nfd.sock ; on other platforms
// path /run/nfd/nfd.sock ; on Linux
// path /var/run/nfd/nfd.sock ; on other platforms
// }

m_wantCongestionMarking = context.generalConfig.wantCongestionMarking;
Expand All @@ -59,15 +59,12 @@ UnixStreamFactory::doProcessConfig(OptionalConfigSection configSection,
}

#ifdef __linux__
std::string path = "/run/nfd.sock";
std::string path = "/run/nfd/nfd.sock";
#else
std::string path = "/var/run/nfd.sock";
std::string path = "/var/run/nfd/nfd.sock";
#endif // __linux__

for (const auto& pair : *configSection) {
const std::string& key = pair.first;
const ConfigSection& value = pair.second;

for (const auto& [key, value] : *configSection) {
if (key == "path") {
path = value.get_value<std::string>();
}
Expand All @@ -87,11 +84,10 @@ UnixStreamFactory::doProcessConfig(OptionalConfigSection configSection,
}

shared_ptr<UnixStreamChannel>
UnixStreamFactory::createChannel(const std::string& unixSocketPath)
UnixStreamFactory::createChannel(const std::string& socketPath)
{
boost::filesystem::path p(unixSocketPath);
p = boost::filesystem::canonical(p.parent_path()) / p.filename();
unix_stream::Endpoint endpoint(p.string());
auto normalizedPath = boost::filesystem::weakly_canonical(boost::filesystem::absolute(socketPath));
unix_stream::Endpoint endpoint(normalizedPath.string());

auto it = m_channels.find(endpoint);
if (it != m_channels.end())
Expand Down
4 changes: 2 additions & 2 deletions daemon/face/unix-stream-factory.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, Regents of the University of California,
* Copyright (c) 2014-2024, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
Expand Down Expand Up @@ -53,7 +53,7 @@ class UnixStreamFactory final : public ProtocolFactory
* an exception will be thrown if the channel cannot be created.
*/
shared_ptr<UnixStreamChannel>
createChannel(const std::string& unixSocketPath);
createChannel(const std::string& socketPath);

private:
void
Expand Down
6 changes: 3 additions & 3 deletions daemon/rib/service.cpp
Original file line number Diff line number Diff line change
@@ -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-2024, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
Expand Down Expand Up @@ -68,9 +68,9 @@ makeLocalNfdTransport(const ConfigSection& config)
if (config.get_child_optional("face_system.unix")) {
// default socket path should be the same as in UnixStreamFactory::processConfig
#ifdef __linux__
auto path = config.get<std::string>("face_system.unix.path", "/run/nfd.sock");
auto path = config.get<std::string>("face_system.unix.path", "/run/nfd/nfd.sock");
#else
auto path = config.get<std::string>("face_system.unix.path", "/var/run/nfd.sock");
auto path = config.get<std::string>("face_system.unix.path", "/var/run/nfd/nfd.sock");
#endif // __linux__
return make_shared<ndn::UnixTransport>(path);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'Named Data Networking Forwarding Daemon (NFD)'
copyright = 'Copyright © 2014-2023 Named Data Networking Project.'
copyright = 'Copyright © 2014-2024 Named Data Networking Project.'
author = 'Named Data Networking Project'

# The short X.Y version.
Expand Down
2 changes: 1 addition & 1 deletion docs/manpages/nfdc-face.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ OPTIONS
- tcp4://192.0.2.1:6363
- tcp6://[2001:db8::1]:6363
- tcp://example.net
- unix:///var/run/nfd.sock
- unix:///run/nfd/nfd.sock
- fd://6
- ether://[08:00:27:01:01:01]
- dev://eth0
Expand Down
11 changes: 5 additions & 6 deletions nfd.conf.sample.in
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,9 @@ face_system
; Unix stream faces and channels.
unix
{
; The default transport is unix:///run/nfd.sock (on Linux) or unix:///var/run/nfd.sock (on
; other platforms). This should match the "transport" field in client.conf for ndn-cxx. If you
; wish to use TCP instead of Unix sockets with ndn-cxx, change "transport" to an appropriate
; TCP FaceUri.
; The default transport is 'unix:///run/nfd/nfd.sock' (on Linux) or 'unix:///var/run/nfd/nfd.sock' (on
; other platforms). This should match the 'transport' field in client.conf for ndn-cxx. If you wish
; to use TCP instead of Unix sockets with ndn-cxx, change 'transport' to an appropriate TCP FaceUri.
path @UNIX_SOCKET_PATH@ ; Unix stream listener path
}

Expand Down Expand Up @@ -303,12 +302,12 @@ authorizations
; sudo mkdir -p @SYSCONFDIR@/ndn/keys
; sudo mv default.ndncert @SYSCONFDIR@/ndn/keys/default.ndncert
;
; The "certfile" field below specifies the default key directory for
; The 'certfile' field below specifies the default key directory for
; your machine. You may move your newly created key to the location it
; specifies or path.

; certfile keys/default.ndncert ; NDN identity certificate file
certfile any ; "any" authorizes command interests signed under any certificate,
certfile any ; 'any' authorizes command interests signed under any certificate,
; i.e., no actual validation.
privileges ; set of privileges granted to this identity
{
Expand Down
34 changes: 18 additions & 16 deletions tests/daemon/face/unix-stream-channel.t.cpp
Original file line number Diff line number Diff line change
@@ -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-2024, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
Expand Down Expand Up @@ -41,7 +41,8 @@ class UnixStreamChannelFixture : public ChannelFixture<UnixStreamChannel, unix_s
protected:
UnixStreamChannelFixture()
{
listenerEp = unix_stream::Endpoint("nfd-test-unix-stream-channel.sock");
listenerEp = unix_stream::Endpoint(socketPath.string());
fs::remove_all(socketPath.parent_path());
}

shared_ptr<UnixStreamChannel>
Expand All @@ -68,11 +69,14 @@ class UnixStreamChannelFixture : public ChannelFixture<UnixStreamChannel, unix_s
clientConnect(local::stream_protocol::socket& client)
{
client.async_connect(listenerEp,
[this] (const boost::system::error_code& error) {
[this] (const auto& error) {
BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
limitedIo.afterOp();
});
}

protected:
fs::path socketPath = fs::path(UNIT_TESTS_TMPDIR) / "unix-stream-channel" / "test" / "foo.sock";
};

BOOST_AUTO_TEST_SUITE(Face)
Expand Down Expand Up @@ -128,9 +132,6 @@ BOOST_AUTO_TEST_CASE(MultipleAccepts)

BOOST_AUTO_TEST_CASE(SocketFile)
{
fs::path socketPath(listenerEp.path());
fs::remove(socketPath);

auto channel = makeChannel();
BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::file_not_found);

Expand All @@ -144,32 +145,33 @@ BOOST_AUTO_TEST_CASE(SocketFile)
BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::file_not_found);
}

BOOST_AUTO_TEST_CASE(ExistingStaleSocketFile)
BOOST_AUTO_TEST_CASE(ExistingSocketFile)
{
fs::path socketPath(listenerEp.path());
fs::remove(socketPath);

fs::create_directories(socketPath.parent_path());
local::stream_protocol::acceptor acceptor(g_io, listenerEp);
acceptor.close();
BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::socket_file);

auto channel = makeChannel();
BOOST_CHECK_THROW(channel->listen(nullptr, nullptr), UnixStreamChannel::Error);

acceptor.close();
BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::socket_file);

BOOST_CHECK_NO_THROW(channel->listen(nullptr, nullptr));
BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::socket_file);
}

BOOST_AUTO_TEST_CASE(ExistingRegularFile)
{
fs::path socketPath(listenerEp.path());
fs::remove(socketPath);
auto guard = ndn::make_scope_exit([=] { fs::remove(socketPath); });

std::ofstream f(listenerEp.path());
fs::create_directories(socketPath.parent_path());
std::ofstream f(socketPath.string());
f.close();
BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::regular_file);

auto channel = makeChannel();
BOOST_CHECK_THROW(channel->listen(nullptr, nullptr), UnixStreamChannel::Error);

fs::remove(socketPath);
}

BOOST_AUTO_TEST_SUITE_END() // TestUnixStreamChannel
Expand Down
63 changes: 51 additions & 12 deletions tests/daemon/face/unix-stream-factory.t.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2023, Regents of the University of California,
* Copyright (c) 2014-2024, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
Expand Down Expand Up @@ -28,21 +28,18 @@
#include "face-system-fixture.hpp"
#include "factory-test-common.hpp"

namespace nfd::tests {
#include <boost/filesystem.hpp>

using face::UnixStreamFactory;
namespace nfd::tests {

using UnixStreamFactoryFixture = FaceSystemFactoryFixture<UnixStreamFactory>;
using UnixStreamFactoryFixture = FaceSystemFactoryFixture<face::UnixStreamFactory>;

BOOST_AUTO_TEST_SUITE(Face)
BOOST_FIXTURE_TEST_SUITE(TestUnixStreamFactory, UnixStreamFactoryFixture)

const std::string CHANNEL_PATH1("unix-stream-test.1.sock");
const std::string CHANNEL_PATH2("unix-stream-test.2.sock");

BOOST_AUTO_TEST_SUITE(ProcessConfig)

BOOST_AUTO_TEST_CASE(Normal)
BOOST_AUTO_TEST_CASE(AbsolutePath)
{
const std::string CONFIG = R"CONFIG(
face_system
Expand All @@ -58,9 +55,40 @@ BOOST_AUTO_TEST_CASE(Normal)
parseConfig(CONFIG, false);

BOOST_REQUIRE_EQUAL(factory.getChannels().size(), 1);
BOOST_TEST(factory.getChannels().front()->isListening());

const auto& uri = factory.getChannels().front()->getUri();
BOOST_CHECK_EQUAL(uri.getScheme(), "unix");
BOOST_CHECK_NE(uri.getPath().find("nfd-test.sock"), std::string::npos);
BOOST_TEST(uri.getScheme() == "unix");
boost::filesystem::path path(uri.getPath());
BOOST_TEST(path.filename() == "nfd-test.sock");
BOOST_TEST(boost::filesystem::canonical(path) == path); // path should already be in canonical form
BOOST_TEST(boost::filesystem::equivalent(path, "/tmp/nfd-test.sock"));
}

BOOST_AUTO_TEST_CASE(RelativePath)
{
const std::string CONFIG = R"CONFIG(
face_system
{
unix
{
path nfd-test.sock
}
}
)CONFIG";

parseConfig(CONFIG, true);
parseConfig(CONFIG, false);

BOOST_REQUIRE_EQUAL(factory.getChannels().size(), 1);
BOOST_TEST(factory.getChannels().front()->isListening());

const auto& uri = factory.getChannels().front()->getUri();
BOOST_TEST(uri.getScheme() == "unix");
boost::filesystem::path path(uri.getPath());
BOOST_TEST(path.filename() == "nfd-test.sock");
BOOST_TEST(boost::filesystem::canonical(path) == path); // path should already be in canonical form
BOOST_TEST(boost::filesystem::equivalent(path, "nfd-test.sock"));
}

BOOST_AUTO_TEST_CASE(Omitted)
Expand Down Expand Up @@ -95,6 +123,9 @@ BOOST_AUTO_TEST_CASE(UnknownOption)

BOOST_AUTO_TEST_SUITE_END() // ProcessConfig

const std::string CHANNEL_PATH1("unix-stream-test.1.sock");
const std::string CHANNEL_PATH2("unix-stream-test.2.sock");

BOOST_AUTO_TEST_CASE(GetChannels)
{
BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Expand All @@ -107,16 +138,24 @@ BOOST_AUTO_TEST_CASE(GetChannels)

BOOST_AUTO_TEST_CASE(CreateChannel)
{
auto channel1 = factory.createChannel(CHANNEL_PATH1);
auto channel1 = factory.createChannel("./" + CHANNEL_PATH1); // test path normalization
auto channel1a = factory.createChannel(CHANNEL_PATH1);
auto channel1b = factory.createChannel(boost::filesystem::absolute(CHANNEL_PATH1).string());
auto channel1c = factory.createChannel("foo//../" + CHANNEL_PATH1);
BOOST_CHECK_EQUAL(channel1, channel1a);
BOOST_CHECK_EQUAL(channel1, channel1b);
BOOST_CHECK_EQUAL(channel1, channel1c);
BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);

const auto& uri = channel1->getUri();
BOOST_TEST_INFO_SCOPE(uri);
BOOST_CHECK_EQUAL(uri.getScheme(), "unix");
BOOST_CHECK_EQUAL(uri.getHost(), "");
BOOST_CHECK_EQUAL(uri.getPort(), "");
BOOST_CHECK_EQUAL(uri.getPath().rfind(CHANNEL_PATH1), uri.getPath().size() - CHANNEL_PATH1.size());
boost::filesystem::path path1(uri.getPath());
BOOST_TEST(path1.filename() == CHANNEL_PATH1);
BOOST_TEST(path1.is_absolute()); // path should always be absolute
BOOST_TEST(path1.lexically_normal() == path1); // path should be in normal form

auto channel2 = factory.createChannel(CHANNEL_PATH2);
BOOST_CHECK_NE(channel1, channel2);
Expand Down

0 comments on commit 4c95771

Please sign in to comment.