mgmt: add sample configuration file and install default configuration
refs: #1332
Change-Id: Ic50aac57382b9760aa3b1c22b7dd2a9fec589cf9
diff --git a/daemon/main.cpp b/daemon/main.cpp
index 9f7bb75..f80a4bd 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -13,11 +13,8 @@
#include "mgmt/local-control-header-manager.hpp"
#include "mgmt/strategy-choice-manager.hpp"
#include "mgmt/config-file.hpp"
-#include "face/tcp-factory.hpp"
-#ifdef HAVE_UNIX_SOCKETS
-#include "face/unix-stream-factory.hpp"
-#endif
+#include <boost/filesystem.hpp>
namespace nfd {
@@ -25,21 +22,7 @@
struct ProgramOptions
{
- struct TcpOutgoing
- {
- TcpOutgoing(std::pair<std::string, std::string> endpoint)
- : m_endpoint(endpoint)
- {
- }
-
- std::pair<std::string, std::string> m_endpoint;
- std::vector<Name> m_prefixes;
- };
-
bool m_showUsage;
- std::pair<std::string, std::string> m_tcpListen;
- std::vector<TcpOutgoing> m_tcpOutgoings;
- std::string m_unixListen;
std::string m_config;
};
@@ -49,70 +32,33 @@
static FaceManager* g_faceManager;
static LocalControlHeaderManager* g_localControlHeaderManager;
static StrategyChoiceManager* g_strategyChoiceManager;
-static TcpFactory* g_tcpFactory;
-static shared_ptr<TcpChannel> g_tcpChannel;
static shared_ptr<InternalFace> g_internalFace;
-#ifdef HAVE_UNIX_SOCKETS
-static UnixStreamFactory* g_unixFactory;
-static shared_ptr<UnixStreamChannel> g_unixChannel;
-#endif
-
void
usage(char* programName)
{
printf(
"%s --help\n\tshow this help and exit\n"
- "%s [--tcp-listen \"0.0.0.0:6363\"] "
-#ifdef HAVE_UNIX_SOCKETS
- "[--unix-listen \"/var/run/nfd.sock\"] "
-#endif
- "[--tcp-connect \"192.0.2.1:6363\" "
- "[--prefix </example>]] "
+ "%s "
"[--config /path/to/nfd.conf]\n"
"\trun forwarding daemon\n"
- "\t--tcp-listen <ip:port>: listen on IP and port\n"
-#ifdef HAVE_UNIX_SOCKETS
- "\t--unix-listen <unix-socket-path>: listen on Unix socket\n"
-#endif
- "\t--tcp-connect <ip:port>: connect to IP and port (can occur multiple times)\n"
- "\t--prefix <NDN name>: add this face as nexthop to FIB entry "
- "(must appear after --tcp-connect, can occur multiple times)\n"
"\t--config <configuration file>]: path to configuration file\n"
"\n",
programName, programName
);
}
-inline std::pair<std::string, std::string>
-parseIpPortPair(const std::string& s)
-{
- size_t pos = s.rfind(":");
- if (pos == std::string::npos) {
- throw std::invalid_argument("ip:port");
- }
-
- return std::make_pair(s.substr(0, pos), s.substr(pos+1));
-}
-
bool
parseCommandLine(int argc, char** argv)
{
g_options.m_showUsage = false;
- g_options.m_tcpListen = std::make_pair("0.0.0.0", "6363");
- g_options.m_unixListen = "/var/run/nfd.sock";
- g_options.m_tcpOutgoings.clear();
g_options.m_config = DEFAULT_CONFIG_FILE;
while (1) {
int option_index = 0;
static ::option long_options[] = {
{ "help" , no_argument , 0, 0 },
- { "tcp-listen" , required_argument, 0, 0 },
- { "tcp-connect" , required_argument, 0, 0 },
- { "prefix" , required_argument, 0, 0 },
- { "unix-listen" , required_argument, 0, 0 },
{ "config" , required_argument, 0, 0 },
{ 0 , 0 , 0, 0 }
};
@@ -125,22 +71,7 @@
case 0://help
g_options.m_showUsage = true;
break;
- case 1://tcp-listen
- g_options.m_tcpListen = parseIpPortPair(::optarg);
- break;
- case 2://tcp-connect
- g_options.m_tcpOutgoings.push_back(parseIpPortPair(::optarg));
- break;
- case 3://prefix
- if (g_options.m_tcpOutgoings.empty()) {
- return false;
- }
- g_options.m_tcpOutgoings.back().m_prefixes.push_back(Name(::optarg));
- break;
- case 4://unix-listen
- g_options.m_unixListen = ::optarg;
- break;
- case 5://config
+ case 1://config
g_options.m_config = ::optarg;
break;
}
@@ -152,68 +83,6 @@
}
void
-onFaceFail(shared_ptr<Face> face, const std::string& reason)
-{
- g_forwarder->removeFace(face);
-}
-
-void
-onFaceEstablish(shared_ptr<Face> newFace, std::vector<Name>* prefixes)
-{
- g_forwarder->addFace(newFace);
- newFace->onFail += bind(&onFaceFail, newFace, _1);
-
- // add nexthop on prefixes
- if (prefixes != 0) {
- Fib& fib = g_forwarder->getFib();
- for (std::vector<Name>::iterator it = prefixes->begin();
- it != prefixes->end(); ++it) {
- std::pair<shared_ptr<fib::Entry>, bool> fibInsertResult =
- fib.insert(*it);
- shared_ptr<fib::Entry> fibEntry = fibInsertResult.first;
- fibEntry->addNextHop(newFace, 0);
- }
- }
-}
-
-void
-onFaceError(const std::string& reason)
-{
- throw std::runtime_error(reason);
-}
-
-void
-initializeTcp()
-{
- g_tcpFactory = new TcpFactory();
- g_tcpChannel = g_tcpFactory->createChannel(g_options.m_tcpListen.first,
- g_options.m_tcpListen.second);
- g_tcpChannel->listen(
- bind(&onFaceEstablish, _1, static_cast<std::vector<Name>*>(0)),
- &onFaceError);
-
- for (std::vector<ProgramOptions::TcpOutgoing>::iterator it =
- g_options.m_tcpOutgoings.begin();
- it != g_options.m_tcpOutgoings.end(); ++it) {
- g_tcpChannel->connect(it->m_endpoint.first, it->m_endpoint.second,
- bind(&onFaceEstablish, _1, &(it->m_prefixes)), &onFaceError);
- }
-}
-
-#ifdef HAVE_UNIX_SOCKETS
-void
-initializeUnix()
-{
- g_unixFactory = new UnixStreamFactory();
- g_unixChannel = g_unixFactory->createChannel(g_options.m_unixListen);
-
- g_unixChannel->listen(
- bind(&onFaceEstablish, _1, static_cast<std::vector<Name>*>(0)),
- &onFaceError);
-}
-#endif
-
-void
initializeMgmt()
{
ConfigFile config;
@@ -238,8 +107,8 @@
g_strategyChoiceManager = new StrategyChoiceManager(g_forwarder->getStrategyChoice(),
g_internalFace);
- /// \todo add parsing back when there is an official default config file
- // config.parse(g_options.m_config);
+ config.parse(g_options.m_config, true);
+ config.parse(g_options.m_config, false);
shared_ptr<fib::Entry> entry = g_forwarder->getFib().insert("/localhost/nfd").first;
entry->addNextHop(g_internalFace, 0);
@@ -248,29 +117,36 @@
int
main(int argc, char** argv)
{
- bool isCommandLineValid = parseCommandLine(argc, argv);
- if (!isCommandLineValid) {
- usage(argv[0]);
- return 1;
- }
- if (g_options.m_showUsage) {
- usage(argv[0]);
- return 0;
- }
-
- g_forwarder = new Forwarder();
- initializeTcp();
-#ifdef HAVE_UNIX_SOCKETS
- initializeUnix();
-#endif
- initializeMgmt();
-
- /// \todo Add signal processing to gracefully terminate the app
-
try {
+ bool isCommandLineValid = parseCommandLine(argc, argv);
+ if (!isCommandLineValid) {
+ usage(argv[0]);
+ return 1;
+ }
+ if (g_options.m_showUsage) {
+ usage(argv[0]);
+ return 0;
+ }
+
+ g_forwarder = new Forwarder();
+ initializeMgmt();
+
+ /// \todo Add signal processing to gracefully terminate the app
+
getGlobalIoService().run();
- } catch(std::exception& ex) {
- NFD_LOG_ERROR(ex.what());
+ // } catch(ConfigFile::Error& error) {
+ // NFD_LOG_ERROR("Error: " << error.what());
+ // NFD_LOG_ERROR("You should either specify --config option or copy sample configuration into "
+ // << DEFAULT_CONFIG_FILE);
+ } catch(boost::filesystem::filesystem_error& error) {
+ if (error.code() == boost::system::errc::permission_denied) {
+ NFD_LOG_ERROR("Error: Permissions denied for " << error.path1());
+ NFD_LOG_ERROR(argv[0] << " should be run as superuser");
+ } else {
+ NFD_LOG_ERROR("Error: " << error.what());
+ }
+ } catch(std::exception& exception) {
+ NFD_LOG_ERROR("Error: " << exception.what());
return 1;
}
diff --git a/daemon/mgmt/config-file.cpp b/daemon/mgmt/config-file.cpp
index 8018310..e5bbb9d 100644
--- a/daemon/mgmt/config-file.cpp
+++ b/daemon/mgmt/config-file.cpp
@@ -26,11 +26,11 @@
}
void
-ConfigFile::parse(const char* filename, bool isDryRun)
+ConfigFile::parse(const std::string& filename, bool isDryRun)
{
std::ifstream inputFile;
- inputFile.open(filename);
- if (!inputFile.is_open())
+ inputFile.open(filename.c_str());
+ if (!inputFile.good() || !inputFile.is_open())
{
std::string msg = "Failed to read configuration file: ";
msg += filename;
@@ -41,7 +41,7 @@
}
void
-ConfigFile::parse(const std::string& input, bool isDryRun, const char* filename)
+ConfigFile::parse(const std::string& input, bool isDryRun, const std::string& filename)
{
std::istringstream inputStream(input);
parse(inputStream, isDryRun, filename);
@@ -49,7 +49,7 @@
void
-ConfigFile::parse(std::istream& input, bool isDryRun, const char* filename)
+ConfigFile::parse(std::istream& input, bool isDryRun, const std::string& filename)
{
try
{
@@ -59,10 +59,7 @@
{
std::stringstream msg;
msg << "Failed to parse configuration file";
- if (filename != 0)
- {
- msg << " " << filename;
- }
+ msg << " " << filename;
msg << " " << error.message() << " line " << error.line();
throw Error(msg.str());
}
@@ -71,18 +68,16 @@
}
void
-ConfigFile::process(bool isDryRun, const char* filename)
+ConfigFile::process(bool isDryRun, const std::string& filename)
{
+ BOOST_ASSERT(!filename.empty());
// NFD_LOG_DEBUG("processing..." << ((isDryRun)?("dry run"):("")));
if (m_global.begin() == m_global.end())
{
std::string msg = "Error processing configuration file";
- if (filename != 0)
- {
- msg += ": ";
- msg += filename;
- }
+ msg += ": ";
+ msg += filename;
msg += " no data";
throw Error(msg);
}
@@ -101,11 +96,8 @@
else
{
std::string msg = "Error processing configuration file";
- if (filename != 0)
- {
- msg += " ";
- msg += filename;
- }
+ msg += " ";
+ msg += filename;
msg += " no module subscribed for section: " + sectionName;
throw Error(msg);
}
diff --git a/daemon/mgmt/config-file.hpp b/daemon/mgmt/config-file.hpp
index 2b72e7f..2a94fac 100644
--- a/daemon/mgmt/config-file.hpp
+++ b/daemon/mgmt/config-file.hpp
@@ -47,31 +47,31 @@
* \throws ConfigFile::Error if parse error
*/
void
- parse(const char* filename, bool isDryRun=false);
+ parse(const std::string& filename, bool isDryRun);
/**
* \param input configuration (as a string) to parse
* \param isDryRun true if performing a dry run of configuration, false otherwise
- * \param filename optional convenience argument to provide more detailed error messages (if available)
+ * \param filename optional convenience argument to provide more detailed error messages
* \throws ConfigFile::Error if file not found
* \throws ConfigFile::Error if parse error
*/
void
- parse(const std::string& input, bool isDryRun=false, const char* filename=0);
+ parse(const std::string& input, bool isDryRun, const std::string& filename);
/**
* \param input stream to parse
* \param isDryRun true if performing a dry run of configuration, false otherwise
- * \param filename optional convenience argument to provide more detailed error messages (if available)
+ * \param filename optional convenience argument to provide more detailed error messages
* \throws ConfigFile::Error if parse error
*/
void
- parse(std::istream& input, bool isDryRun=false, const char* filename=0);
+ parse(std::istream& input, bool isDryRun, const std::string& filename);
private:
void
- process(bool isDryRun, const char* filename);
+ process(bool isDryRun, const std::string& filename);
private: