blob: 5d9ce22a03bc7fa3d1d91c7b52969868fa0fb93f [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"
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"
Yanbiao Li698f4fe2015-08-19 16:30:16 -070041#include "mgmt/command-validator.hpp"
42
43#include <ndn-cxx/mgmt/dispatcher.hpp>
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080044
45namespace nfd {
46
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070047NFD_LOG_INIT("Nfd");
48
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080049static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
50
Alexander Afanasyev441ba212015-09-10 23:41:07 -070051static inline ndn::util::NetworkMonitor*
52makeNetworkMonitor()
53{
54 try {
55 return new ndn::util::NetworkMonitor(getGlobalIoService());
56 }
57 catch (const ndn::util::NetworkMonitor::Error& e) {
58 NFD_LOG_WARN(e.what());
59 return nullptr;
60 }
61}
62
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080063Nfd::Nfd(const std::string& configFile, ndn::KeyChain& keyChain)
64 : m_configFile(configFile)
65 , m_keyChain(keyChain)
Alexander Afanasyev441ba212015-09-10 23:41:07 -070066 , m_networkMonitor(makeNetworkMonitor())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080067{
68}
69
70Nfd::Nfd(const ConfigSection& config, ndn::KeyChain& keyChain)
71 : m_configSection(config)
72 , m_keyChain(keyChain)
Alexander Afanasyev441ba212015-09-10 23:41:07 -070073 , m_networkMonitor(makeNetworkMonitor())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080074{
75}
76
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080077Nfd::~Nfd()
78{
79 // It is necessary to explicitly define the destructor, because some member variables (e.g.,
80 // unique_ptr<Forwarder>) are forward-declared, but implicitly declared destructor requires
81 // complete types for all members when instantiated.
82}
83
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080084void
85Nfd::initialize()
86{
87 initializeLogging();
88
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080089 m_forwarder.reset(new Forwarder());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080090
91 initializeManagement();
92
Junxiao Shia044be72015-10-26 11:00:56 -070093 FaceTable& faceTable = m_forwarder->getFaceTable();
Junxiao Shicde37ad2015-12-24 01:02:05 -070094 faceTable.addReserved(face::makeNullFace(), face::FACEID_NULL);
95 faceTable.addReserved(face::makeNullFace(FaceUri("contentstore://")), face::FACEID_CONTENT_STORE);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080096
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080097 PrivilegeHelper::drop();
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070098
Alexander Afanasyev441ba212015-09-10 23:41:07 -070099 if (m_networkMonitor) {
100 m_networkMonitor->onNetworkStateChanged.connect([this] {
101 // delay stages, so if multiple events are triggered in short sequence,
102 // only one auto-detection procedure is triggered
103 m_reloadConfigEvent = scheduler::schedule(time::seconds(5),
104 [this] {
105 NFD_LOG_INFO("Network change detected, reloading face section of the config file...");
106 this->reloadConfigFileFaceSection();
107 });
108 });
109 }
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800110}
111
112void
113Nfd::initializeLogging()
114{
115 ConfigFile config(&ConfigFile::ignoreUnknownSection);
116 LoggerFactory::getInstance().setConfigFile(config);
117
118 if (!m_configFile.empty()) {
119 config.parse(m_configFile, true);
120 config.parse(m_configFile, false);
121 }
122 else {
123 config.parse(m_configSection, true, INTERNAL_CONFIG);
124 config.parse(m_configSection, false, INTERNAL_CONFIG);
125 }
126}
127
128
129static inline void
130ignoreRibAndLogSections(const std::string& filename, const std::string& sectionName,
131 const ConfigSection& section, bool isDryRun)
132{
133 // Ignore "log" and "rib" sections, but raise an error if we're missing a
134 // handler for an NFD section.
135 if (sectionName == "rib" || sectionName == "log") {
136 // do nothing
137 }
138 else {
139 // missing NFD section
140 ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
141 }
142}
143
144void
145Nfd::initializeManagement()
146{
Junxiao Shi6535f1e2015-10-08 13:02:18 -0700147 std::tie(m_internalFace, m_internalClientFace) = face::makeInternalFace(m_keyChain);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700148 m_forwarder->getFaceTable().addReserved(m_internalFace, face::FACEID_INTERNAL_FACE);
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700149 m_dispatcher.reset(new ndn::mgmt::Dispatcher(*m_internalClientFace, m_keyChain));
150
151 m_validator.reset(new CommandValidator());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800152
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800153 m_fibManager.reset(new FibManager(m_forwarder->getFib(),
154 bind(&Forwarder::getFace, m_forwarder.get(), _1),
Yanbiao Li711c7932015-08-19 16:30:16 -0700155 *m_dispatcher,
156 *m_validator));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800157
Yanbiao Li73860e32015-08-19 16:30:16 -0700158 m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(),
159 *m_dispatcher,
160 *m_validator));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800161
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800162 m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700163 *m_dispatcher,
164 *m_validator));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800165
Yanbiao Li7cec7ea2015-08-19 16:30:16 -0700166 m_forwarderStatusManager.reset(new ForwarderStatusManager(*m_forwarder, *m_dispatcher));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800167
168 ConfigFile config(&ignoreRibAndLogSections);
169 general::setConfigFile(config);
170
171 TablesConfigSection tablesConfig(m_forwarder->getCs(),
172 m_forwarder->getPit(),
173 m_forwarder->getFib(),
174 m_forwarder->getStrategyChoice(),
Vince Lehman63ab1bb2015-09-04 17:06:58 -0500175 m_forwarder->getMeasurements(),
176 m_forwarder->getNetworkRegionTable());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800177 tablesConfig.setConfigFile(config);
178
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700179 m_validator->setConfigFile(config);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800180
181 m_faceManager->setConfigFile(config);
182
183 // parse config file
184 if (!m_configFile.empty()) {
185 config.parse(m_configFile, true);
186 config.parse(m_configFile, false);
187 }
188 else {
189 config.parse(m_configSection, true, INTERNAL_CONFIG);
190 config.parse(m_configSection, false, INTERNAL_CONFIG);
191 }
192
193 tablesConfig.ensureTablesAreConfigured();
194
195 // add FIB entry for NFD Management Protocol
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700196 Name topPrefix("/localhost/nfd");
197 auto entry = m_forwarder->getFib().insert(topPrefix).first;
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800198 entry->addNextHop(m_internalFace, 0);
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700199 m_dispatcher->addTopPrefix(topPrefix, false);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800200}
201
202void
203Nfd::reloadConfigFile()
204{
205 // Logging
206 initializeLogging();
207 /// \todo Reopen log file
208
209 // Other stuff
210 ConfigFile config(&ignoreRibAndLogSections);
211
212 general::setConfigFile(config);
213
214 TablesConfigSection tablesConfig(m_forwarder->getCs(),
215 m_forwarder->getPit(),
216 m_forwarder->getFib(),
217 m_forwarder->getStrategyChoice(),
Vince Lehman63ab1bb2015-09-04 17:06:58 -0500218 m_forwarder->getMeasurements(),
219 m_forwarder->getNetworkRegionTable());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800220
221 tablesConfig.setConfigFile(config);
222
Yanbiao Li698f4fe2015-08-19 16:30:16 -0700223 m_validator->setConfigFile(config);
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800224 m_faceManager->setConfigFile(config);
225
226 if (!m_configFile.empty()) {
227 config.parse(m_configFile, false);
228 }
229 else {
230 config.parse(m_configSection, false, INTERNAL_CONFIG);
231 }
232}
233
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -0700234void
235Nfd::reloadConfigFileFaceSection()
236{
237 // reload only face_system section of the config file to re-initialize multicast faces
238 ConfigFile config(&ConfigFile::ignoreUnknownSection);
239 m_faceManager->setConfigFile(config);
240
241 if (!m_configFile.empty()) {
242 config.parse(m_configFile, false);
243 }
244 else {
245 config.parse(m_configSection, false, INTERNAL_CONFIG);
246 }
247}
248
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800249} // namespace nfd