blob: 5d6bec79824f97a506568d481f6523313709e40e [file] [log] [blame]
Alexander Afanasyev31c781e2015-02-09 17:39:59 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shia6de4292016-07-12 02:08:10 +00003 * Copyright (c) 2014-2016, Regents of the University of California,
Alexander Afanasyev31c781e2015-02-09 17:39:59 -08004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "nfd.hpp"
27
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070028#include "core/global-io.hpp"
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080029#include "core/logger-factory.hpp"
30#include "core/privilege-helper.hpp"
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070031#include "core/config-file.hpp"
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080032#include "fw/forwarder.hpp"
33#include "face/null-face.hpp"
Yanbiao Li4ee73d42015-08-19 16:30:16 -070034#include "face/internal-face.hpp"
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080035#include "mgmt/fib-manager.hpp"
36#include "mgmt/face-manager.hpp"
37#include "mgmt/strategy-choice-manager.hpp"
Yanbiao Li7cec7ea2015-08-19 16:30:16 -070038#include "mgmt/forwarder-status-manager.hpp"
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080039#include "mgmt/general-config-section.hpp"
40#include "mgmt/tables-config-section.hpp"
41
42namespace nfd {
43
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070044NFD_LOG_INIT("Nfd");
45
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080046static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
47
Alexander Afanasyev441ba212015-09-10 23:41:07 -070048static inline ndn::util::NetworkMonitor*
49makeNetworkMonitor()
50{
51 try {
52 return new ndn::util::NetworkMonitor(getGlobalIoService());
53 }
54 catch (const ndn::util::NetworkMonitor::Error& e) {
55 NFD_LOG_WARN(e.what());
56 return nullptr;
57 }
58}
59
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080060Nfd::Nfd(const std::string& configFile, ndn::KeyChain& keyChain)
61 : m_configFile(configFile)
62 , m_keyChain(keyChain)
Alexander Afanasyev441ba212015-09-10 23:41:07 -070063 , m_networkMonitor(makeNetworkMonitor())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080064{
65}
66
67Nfd::Nfd(const ConfigSection& config, ndn::KeyChain& keyChain)
68 : m_configSection(config)
69 , m_keyChain(keyChain)
Alexander Afanasyev441ba212015-09-10 23:41:07 -070070 , m_networkMonitor(makeNetworkMonitor())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080071{
72}
73
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000074// It is necessary to explicitly define the destructor, because some member variables (e.g.,
75// unique_ptr<Forwarder>) are forward-declared, but implicitly declared destructor requires
76// complete types for all members when instantiated.
77Nfd::~Nfd() = default;
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080078
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080079void
80Nfd::initialize()
81{
82 initializeLogging();
83
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080084 m_forwarder.reset(new Forwarder());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080085
86 initializeManagement();
87
Junxiao Shia044be72015-10-26 11:00:56 -070088 FaceTable& faceTable = m_forwarder->getFaceTable();
Junxiao Shicde37ad2015-12-24 01:02:05 -070089 faceTable.addReserved(face::makeNullFace(), face::FACEID_NULL);
90 faceTable.addReserved(face::makeNullFace(FaceUri("contentstore://")), face::FACEID_CONTENT_STORE);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080091
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080092 PrivilegeHelper::drop();
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070093
Alexander Afanasyev441ba212015-09-10 23:41:07 -070094 if (m_networkMonitor) {
95 m_networkMonitor->onNetworkStateChanged.connect([this] {
96 // delay stages, so if multiple events are triggered in short sequence,
97 // only one auto-detection procedure is triggered
98 m_reloadConfigEvent = scheduler::schedule(time::seconds(5),
99 [this] {
100 NFD_LOG_INFO("Network change detected, reloading face section of the config file...");
101 this->reloadConfigFileFaceSection();
102 });
103 });
104 }
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800105}
106
107void
108Nfd::initializeLogging()
109{
110 ConfigFile config(&ConfigFile::ignoreUnknownSection);
111 LoggerFactory::getInstance().setConfigFile(config);
112
113 if (!m_configFile.empty()) {
114 config.parse(m_configFile, true);
115 config.parse(m_configFile, false);
116 }
117 else {
118 config.parse(m_configSection, true, INTERNAL_CONFIG);
119 config.parse(m_configSection, false, INTERNAL_CONFIG);
120 }
121}
122
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800123static inline void
124ignoreRibAndLogSections(const std::string& filename, const std::string& sectionName,
125 const ConfigSection& section, bool isDryRun)
126{
127 // Ignore "log" and "rib" sections, but raise an error if we're missing a
128 // handler for an NFD section.
129 if (sectionName == "rib" || sectionName == "log") {
130 // do nothing
131 }
132 else {
133 // missing NFD section
134 ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
135 }
136}
137
138void
139Nfd::initializeManagement()
140{
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700141 std::tie(m_internalFace, m_internalClientFace) = face::makeInternalFace(m_keyChain);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700142 m_forwarder->getFaceTable().addReserved(m_internalFace, face::FACEID_INTERNAL_FACE);
Junxiao Shi9ddf1b52016-08-22 03:58:55 +0000143
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700144 m_dispatcher.reset(new ndn::mgmt::Dispatcher(*m_internalClientFace, m_keyChain));
Junxiao Shi9ddf1b52016-08-22 03:58:55 +0000145 m_authenticator = CommandAuthenticator::create();
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800146
Yanbiao Li7cec7ea2015-08-19 16:30:16 -0700147 m_forwarderStatusManager.reset(new ForwarderStatusManager(*m_forwarder, *m_dispatcher));
Junxiao Shi9ddf1b52016-08-22 03:58:55 +0000148 m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(),
149 *m_dispatcher, *m_authenticator));
150 m_fibManager.reset(new FibManager(m_forwarder->getFib(), m_forwarder->getFaceTable(),
151 *m_dispatcher, *m_authenticator));
152 m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
153 *m_dispatcher, *m_authenticator));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800154
155 ConfigFile config(&ignoreRibAndLogSections);
156 general::setConfigFile(config);
157
158 TablesConfigSection tablesConfig(m_forwarder->getCs(),
159 m_forwarder->getPit(),
160 m_forwarder->getFib(),
161 m_forwarder->getStrategyChoice(),
Vince Lehman63ab1bb2015-09-04 17:06:58 -0500162 m_forwarder->getMeasurements(),
163 m_forwarder->getNetworkRegionTable());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800164 tablesConfig.setConfigFile(config);
165
Junxiao Shi9ddf1b52016-08-22 03:58:55 +0000166 m_authenticator->setConfigFile(config);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800167 m_faceManager->setConfigFile(config);
168
169 // parse config file
170 if (!m_configFile.empty()) {
171 config.parse(m_configFile, true);
172 config.parse(m_configFile, false);
173 }
174 else {
175 config.parse(m_configSection, true, INTERNAL_CONFIG);
176 config.parse(m_configSection, false, INTERNAL_CONFIG);
177 }
178
179 tablesConfig.ensureTablesAreConfigured();
180
181 // add FIB entry for NFD Management Protocol
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700182 Name topPrefix("/localhost/nfd");
Junxiao Shia6de4292016-07-12 02:08:10 +0000183 m_forwarder->getFib().insert(topPrefix).first->addNextHop(*m_internalFace, 0);
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700184 m_dispatcher->addTopPrefix(topPrefix, false);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800185}
186
187void
188Nfd::reloadConfigFile()
189{
190 // Logging
191 initializeLogging();
192 /// \todo Reopen log file
193
194 // Other stuff
195 ConfigFile config(&ignoreRibAndLogSections);
196
197 general::setConfigFile(config);
198
199 TablesConfigSection tablesConfig(m_forwarder->getCs(),
200 m_forwarder->getPit(),
201 m_forwarder->getFib(),
202 m_forwarder->getStrategyChoice(),
Vince Lehman63ab1bb2015-09-04 17:06:58 -0500203 m_forwarder->getMeasurements(),
204 m_forwarder->getNetworkRegionTable());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800205 tablesConfig.setConfigFile(config);
206
Junxiao Shi9ddf1b52016-08-22 03:58:55 +0000207 m_authenticator->setConfigFile(config);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800208 m_faceManager->setConfigFile(config);
209
210 if (!m_configFile.empty()) {
211 config.parse(m_configFile, false);
212 }
213 else {
214 config.parse(m_configSection, false, INTERNAL_CONFIG);
215 }
216}
217
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -0700218void
219Nfd::reloadConfigFileFaceSection()
220{
221 // reload only face_system section of the config file to re-initialize multicast faces
222 ConfigFile config(&ConfigFile::ignoreUnknownSection);
223 m_faceManager->setConfigFile(config);
224
225 if (!m_configFile.empty()) {
226 config.parse(m_configFile, false);
227 }
228 else {
229 config.parse(m_configSection, false, INTERNAL_CONFIG);
230 }
231}
232
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800233} // namespace nfd