blob: 44b0579c1bfdecfaadbcb22f40168de6b0a8f321 [file] [log] [blame]
Alexander Afanasyev31c781e2015-02-09 17:39:59 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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"
35#include "face/internal-client-face.hpp"
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080036#include "mgmt/fib-manager.hpp"
37#include "mgmt/face-manager.hpp"
38#include "mgmt/strategy-choice-manager.hpp"
Yanbiao Li7cec7ea2015-08-19 16:30:16 -070039#include "mgmt/forwarder-status-manager.hpp"
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080040#include "mgmt/general-config-section.hpp"
41#include "mgmt/tables-config-section.hpp"
Yanbiao Li698f4fe2015-08-19 16:30:16 -070042#include "mgmt/command-validator.hpp"
43
44#include <ndn-cxx/mgmt/dispatcher.hpp>
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080045
46namespace nfd {
47
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070048NFD_LOG_INIT("Nfd");
49
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080050static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
51
Alexander Afanasyev441ba212015-09-10 23:41:07 -070052static inline ndn::util::NetworkMonitor*
53makeNetworkMonitor()
54{
55 try {
56 return new ndn::util::NetworkMonitor(getGlobalIoService());
57 }
58 catch (const ndn::util::NetworkMonitor::Error& e) {
59 NFD_LOG_WARN(e.what());
60 return nullptr;
61 }
62}
63
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080064Nfd::Nfd(const std::string& configFile, ndn::KeyChain& keyChain)
65 : m_configFile(configFile)
66 , m_keyChain(keyChain)
Alexander Afanasyev441ba212015-09-10 23:41:07 -070067 , m_networkMonitor(makeNetworkMonitor())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080068{
69}
70
71Nfd::Nfd(const ConfigSection& config, ndn::KeyChain& keyChain)
72 : m_configSection(config)
73 , m_keyChain(keyChain)
Alexander Afanasyev441ba212015-09-10 23:41:07 -070074 , m_networkMonitor(makeNetworkMonitor())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080075{
76}
77
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080078Nfd::~Nfd()
79{
80 // It is necessary to explicitly define the destructor, because some member variables (e.g.,
81 // unique_ptr<Forwarder>) are forward-declared, but implicitly declared destructor requires
82 // complete types for all members when instantiated.
83}
84
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080085void
86Nfd::initialize()
87{
88 initializeLogging();
89
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080090 m_forwarder.reset(new Forwarder());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080091
92 initializeManagement();
93
94 m_forwarder->getFaceTable().addReserved(make_shared<NullFace>(), FACEID_NULL);
95 m_forwarder->getFaceTable().addReserved(make_shared<NullFace>(FaceUri("contentstore://")),
96 FACEID_CONTENT_STORE);
97
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080098 PrivilegeHelper::drop();
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070099
Alexander Afanasyev441ba212015-09-10 23:41:07 -0700100 if (m_networkMonitor) {
101 m_networkMonitor->onNetworkStateChanged.connect([this] {
102 // delay stages, so if multiple events are triggered in short sequence,
103 // only one auto-detection procedure is triggered
104 m_reloadConfigEvent = scheduler::schedule(time::seconds(5),
105 [this] {
106 NFD_LOG_INFO("Network change detected, reloading face section of the config file...");
107 this->reloadConfigFileFaceSection();
108 });
109 });
110 }
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800111}
112
113void
114Nfd::initializeLogging()
115{
116 ConfigFile config(&ConfigFile::ignoreUnknownSection);
117 LoggerFactory::getInstance().setConfigFile(config);
118
119 if (!m_configFile.empty()) {
120 config.parse(m_configFile, true);
121 config.parse(m_configFile, false);
122 }
123 else {
124 config.parse(m_configSection, true, INTERNAL_CONFIG);
125 config.parse(m_configSection, false, INTERNAL_CONFIG);
126 }
127}
128
129
130static inline void
131ignoreRibAndLogSections(const std::string& filename, const std::string& sectionName,
132 const ConfigSection& section, bool isDryRun)
133{
134 // Ignore "log" and "rib" sections, but raise an error if we're missing a
135 // handler for an NFD section.
136 if (sectionName == "rib" || sectionName == "log") {
137 // do nothing
138 }
139 else {
140 // missing NFD section
141 ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
142 }
143}
144
145void
146Nfd::initializeManagement()
147{
148 m_internalFace = make_shared<InternalFace>();
Yanbiao Li4ee73d42015-08-19 16:30:16 -0700149 m_forwarder->getFaceTable().addReserved(m_internalFace, FACEID_INTERNAL_FACE);
150 m_internalClientFace = makeInternalClientFace(m_internalFace, m_keyChain);
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700151 m_dispatcher.reset(new ndn::mgmt::Dispatcher(*m_internalClientFace, m_keyChain));
152
153 m_validator.reset(new CommandValidator());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800154
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800155 m_fibManager.reset(new FibManager(m_forwarder->getFib(),
156 bind(&Forwarder::getFace, m_forwarder.get(), _1),
Yanbiao Li711c7932015-08-19 16:30:16 -0700157 *m_dispatcher,
158 *m_validator));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800159
Yanbiao Li73860e32015-08-19 16:30:16 -0700160 m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(),
161 *m_dispatcher,
162 *m_validator));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800163
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800164 m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700165 *m_dispatcher,
166 *m_validator));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800167
Yanbiao Li7cec7ea2015-08-19 16:30:16 -0700168 m_forwarderStatusManager.reset(new ForwarderStatusManager(*m_forwarder, *m_dispatcher));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800169
170 ConfigFile config(&ignoreRibAndLogSections);
171 general::setConfigFile(config);
172
173 TablesConfigSection tablesConfig(m_forwarder->getCs(),
174 m_forwarder->getPit(),
175 m_forwarder->getFib(),
176 m_forwarder->getStrategyChoice(),
Vince Lehman63ab1bb2015-09-04 17:06:58 -0500177 m_forwarder->getMeasurements(),
178 m_forwarder->getNetworkRegionTable());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800179 tablesConfig.setConfigFile(config);
180
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700181 m_validator->setConfigFile(config);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800182
183 m_faceManager->setConfigFile(config);
184
185 // parse config file
186 if (!m_configFile.empty()) {
187 config.parse(m_configFile, true);
188 config.parse(m_configFile, false);
189 }
190 else {
191 config.parse(m_configSection, true, INTERNAL_CONFIG);
192 config.parse(m_configSection, false, INTERNAL_CONFIG);
193 }
194
195 tablesConfig.ensureTablesAreConfigured();
196
197 // add FIB entry for NFD Management Protocol
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700198 Name topPrefix("/localhost/nfd");
199 auto entry = m_forwarder->getFib().insert(topPrefix).first;
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800200 entry->addNextHop(m_internalFace, 0);
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700201 m_dispatcher->addTopPrefix(topPrefix, false);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800202}
203
204void
205Nfd::reloadConfigFile()
206{
207 // Logging
208 initializeLogging();
209 /// \todo Reopen log file
210
211 // Other stuff
212 ConfigFile config(&ignoreRibAndLogSections);
213
214 general::setConfigFile(config);
215
216 TablesConfigSection tablesConfig(m_forwarder->getCs(),
217 m_forwarder->getPit(),
218 m_forwarder->getFib(),
219 m_forwarder->getStrategyChoice(),
Vince Lehman63ab1bb2015-09-04 17:06:58 -0500220 m_forwarder->getMeasurements(),
221 m_forwarder->getNetworkRegionTable());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800222
223 tablesConfig.setConfigFile(config);
224
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700225 m_validator->setConfigFile(config);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800226 m_faceManager->setConfigFile(config);
227
228 if (!m_configFile.empty()) {
229 config.parse(m_configFile, false);
230 }
231 else {
232 config.parse(m_configSection, false, INTERNAL_CONFIG);
233 }
234}
235
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -0700236void
237Nfd::reloadConfigFileFaceSection()
238{
239 // reload only face_system section of the config file to re-initialize multicast faces
240 ConfigFile config(&ConfigFile::ignoreUnknownSection);
241 m_faceManager->setConfigFile(config);
242
243 if (!m_configFile.empty()) {
244 config.parse(m_configFile, false);
245 }
246 else {
247 config.parse(m_configSection, false, INTERNAL_CONFIG);
248 }
249}
250
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800251} // namespace nfd