blob: dff26cd87cd5e57e41cf398626032e9d69bd3d8e [file] [log] [blame]
Alexander Afanasyev2aa39622014-01-22 11:51:11 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
Junxiao Shi09bf7c42014-01-31 11:10:25 -07007#include <getopt.h>
Junxiao Shi98e29f42014-03-31 10:27:26 -07008#include <boost/filesystem.hpp>
9
Junxiao Shi09bf7c42014-01-31 11:10:25 -070010#include "core/logger.hpp"
Junxiao Shi98e29f42014-03-31 10:27:26 -070011#include "core/global-io.hpp"
Junxiao Shi09bf7c42014-01-31 11:10:25 -070012#include "fw/forwarder.hpp"
13#include "mgmt/internal-face.hpp"
Steve DiBenedetto214563c2014-02-03 19:20:36 -070014#include "mgmt/fib-manager.hpp"
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070015#include "mgmt/face-manager.hpp"
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -070016#include "mgmt/strategy-choice-manager.hpp"
Junxiao Shiea48d8b2014-03-16 13:53:47 -070017#include "mgmt/status-server.hpp"
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070018#include "mgmt/config-file.hpp"
Alexander Afanasyevc78b1412014-02-19 14:08:26 -080019
Junxiao Shi09bf7c42014-01-31 11:10:25 -070020namespace nfd {
21
22NFD_LOG_INIT("Main");
23
24struct ProgramOptions
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080025{
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -070026 bool showUsage;
27 std::string config;
Junxiao Shi09bf7c42014-01-31 11:10:25 -070028};
29
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -070030class Nfd : noncopyable
Junxiao Shi09bf7c42014-01-31 11:10:25 -070031{
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -070032public:
33 explicit
34 Nfd(const std::string& configFile)
35 : m_internalFace(new InternalFace())
36 , m_fibManager(m_forwarder.getFib(),
37 bind(&Forwarder::getFace, &m_forwarder, _1),
38 m_internalFace)
39 , m_faceManager(m_forwarder.getFaceTable(), m_internalFace)
40 , m_strategyChoiceManager(m_forwarder.getStrategyChoice(), m_internalFace)
41 , m_statusServer(m_internalFace, m_forwarder)
42 {
43 ConfigFile config;
44 m_internalFace->getValidator().setConfigFile(config);
Junxiao Shi09bf7c42014-01-31 11:10:25 -070045
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -070046 m_forwarder.addFace(m_internalFace);
Junxiao Shic041ca32014-02-25 20:01:15 -070047
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -070048 m_faceManager.setConfigFile(config);
Junxiao Shic041ca32014-02-25 20:01:15 -070049
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -070050 // parse config file
51 config.parse(configFile, true);
52 config.parse(configFile, false);
53
54 // add FIB entry for NFD Management Protocol
55 shared_ptr<fib::Entry> entry = m_forwarder.getFib().insert("/localhost/nfd").first;
56 entry->addNextHop(m_internalFace, 0);
57 }
58
59
60 static void
61 printUsage(std::ostream& os, const std::string& programName)
62 {
63 os << "Usage: \n"
64 << " " << programName << " [options]\n"
65 << "\n"
66 << "Run NFD forwarding daemon\n"
67 << "\n"
68 << "Options:\n"
69 << " [--help] - print this help message\n"
70 << " [--config /path/to/nfd.conf] - path to configuration file "
71 << "(default: " << DEFAULT_CONFIG_FILE << ")\n"
72 ;
73 }
74
75 static bool
76 parseCommandLine(int argc, char** argv, ProgramOptions& options)
77 {
78 options.showUsage = false;
79 options.config = DEFAULT_CONFIG_FILE;
80
81 while (true) {
82 int optionIndex = 0;
83 static ::option longOptions[] = {
84 { "help" , no_argument , 0, 0 },
85 { "config" , required_argument, 0, 0 },
86 { 0 , 0 , 0, 0 }
87 };
88 int c = getopt_long_only(argc, argv, "", longOptions, &optionIndex);
89 if (c == -1)
90 break;
91
92 switch (c) {
Junxiao Shi09bf7c42014-01-31 11:10:25 -070093 case 0:
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -070094 switch (optionIndex) {
95 case 0: // help
96 options.showUsage = true;
97 break;
98 case 1: // config
99 options.config = ::optarg;
100 break;
101 default:
102 return false;
Junxiao Shi09bf7c42014-01-31 11:10:25 -0700103 }
104 break;
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700105 }
Junxiao Shi09bf7c42014-01-31 11:10:25 -0700106 }
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700107
108 return true;
Junxiao Shi09bf7c42014-01-31 11:10:25 -0700109 }
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700110
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700111 void
112 terminate(const boost::system::error_code& error,
113 int signalNo,
114 boost::asio::signal_set& signalSet)
115 {
116 if (error)
117 return;
Junxiao Shi09bf7c42014-01-31 11:10:25 -0700118
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700119 if (signalNo == SIGINT ||
120 signalNo == SIGTERM)
121 {
122 getGlobalIoService().stop();
123 std::cout << "Caught signal '" << strsignal(signalNo) << "', exiting..." << std::endl;
124 }
125 else
126 {
127 /// \todo May be try to reload config file (at least security section)
128 signalSet.async_wait(bind(&Nfd::terminate, this, _1, _2,
129 boost::ref(signalSet)));
130 }
Junxiao Shiea48d8b2014-03-16 13:53:47 -0700131 }
Steve DiBenedetto84da5bf2014-03-11 14:51:29 -0600132
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700133private:
134 Forwarder m_forwarder;
135 shared_ptr<InternalFace> m_internalFace;
Steve DiBenedetto84da5bf2014-03-11 14:51:29 -0600136
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700137 FibManager m_fibManager;
138 FaceManager m_faceManager;
139 StrategyChoiceManager m_strategyChoiceManager;
140 StatusServer m_statusServer;
141};
Junxiao Shi09bf7c42014-01-31 11:10:25 -0700142
143} // namespace nfd
144
145int
146main(int argc, char** argv)
147{
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700148 using namespace nfd;
Junxiao Shiea48d8b2014-03-16 13:53:47 -0700149
Alexander Afanasyev5a4388a2014-03-27 18:02:55 -0700150 ProgramOptions options;
151 bool isCommandLineValid = Nfd::parseCommandLine(argc, argv, options);
152 if (!isCommandLineValid) {
153 Nfd::printUsage(std::cerr, argv[0]);
154 return 1;
155 }
156 if (options.showUsage) {
157 Nfd::printUsage(std::cout, argv[0]);
158 return 0;
159 }
160
161 try {
162 Nfd nfdInstance(options.config);
163
164 boost::asio::signal_set signalSet(getGlobalIoService());
165 signalSet.add(SIGINT);
166 signalSet.add(SIGTERM);
167 signalSet.add(SIGHUP);
168 signalSet.add(SIGUSR1);
169 signalSet.add(SIGUSR2);
170 signalSet.async_wait(bind(&Nfd::terminate, &nfdInstance, _1, _2,
171 boost::ref(signalSet)));
172
173 getGlobalIoService().run();
174 }
175 catch (boost::filesystem::filesystem_error& e) {
176 if (e.code() == boost::system::errc::permission_denied) {
177 NFD_LOG_FATAL("Permissions denied for " << e.path1() << ". "
178 << argv[0] << " should be run as superuser");
179 }
180 else {
181 NFD_LOG_FATAL(e.what());
182 }
183 return 2;
184 }
185 catch (std::exception& e) {
186 NFD_LOG_FATAL(e.what());
187 return 1;
188 }
189
190 return 0;
191}