blob: d880ebb4d1e6644172fe57d712e3be5689e9a637 [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"
34#include "mgmt/internal-face.hpp"
35#include "mgmt/fib-manager.hpp"
36#include "mgmt/face-manager.hpp"
37#include "mgmt/strategy-choice-manager.hpp"
38#include "mgmt/status-server.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
48Nfd::Nfd(const std::string& configFile, ndn::KeyChain& keyChain)
49 : m_configFile(configFile)
50 , m_keyChain(keyChain)
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070051 , m_networkMonitor(getGlobalIoService())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080052{
53}
54
55Nfd::Nfd(const ConfigSection& config, ndn::KeyChain& keyChain)
56 : m_configSection(config)
57 , m_keyChain(keyChain)
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070058 , m_networkMonitor(getGlobalIoService())
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080059{
60}
61
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080062Nfd::~Nfd()
63{
64 // It is necessary to explicitly define the destructor, because some member variables (e.g.,
65 // unique_ptr<Forwarder>) are forward-declared, but implicitly declared destructor requires
66 // complete types for all members when instantiated.
67}
68
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080069void
70Nfd::initialize()
71{
72 initializeLogging();
73
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -080074 m_forwarder.reset(new Forwarder());
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080075
76 initializeManagement();
77
78 m_forwarder->getFaceTable().addReserved(make_shared<NullFace>(), FACEID_NULL);
79 m_forwarder->getFaceTable().addReserved(make_shared<NullFace>(FaceUri("contentstore://")),
80 FACEID_CONTENT_STORE);
81
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080082 PrivilegeHelper::drop();
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -070083
84 m_networkMonitor.onNetworkStateChanged.connect([this] {
85 // delay stages, so if multiple events are triggered in short sequence,
86 // only one auto-detection procedure is triggered
87 m_reloadConfigEvent = scheduler::schedule(time::seconds(5),
88 [this] {
89 NFD_LOG_INFO("Network change detected, reloading face section of the config file...");
90 this->reloadConfigFileFaceSection();
91 });
92 });
Alexander Afanasyev31c781e2015-02-09 17:39:59 -080093}
94
95void
96Nfd::initializeLogging()
97{
98 ConfigFile config(&ConfigFile::ignoreUnknownSection);
99 LoggerFactory::getInstance().setConfigFile(config);
100
101 if (!m_configFile.empty()) {
102 config.parse(m_configFile, true);
103 config.parse(m_configFile, false);
104 }
105 else {
106 config.parse(m_configSection, true, INTERNAL_CONFIG);
107 config.parse(m_configSection, false, INTERNAL_CONFIG);
108 }
109}
110
111
112static inline void
113ignoreRibAndLogSections(const std::string& filename, const std::string& sectionName,
114 const ConfigSection& section, bool isDryRun)
115{
116 // Ignore "log" and "rib" sections, but raise an error if we're missing a
117 // handler for an NFD section.
118 if (sectionName == "rib" || sectionName == "log") {
119 // do nothing
120 }
121 else {
122 // missing NFD section
123 ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
124 }
125}
126
127void
128Nfd::initializeManagement()
129{
130 m_internalFace = make_shared<InternalFace>();
131
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800132 m_fibManager.reset(new FibManager(m_forwarder->getFib(),
133 bind(&Forwarder::getFace, m_forwarder.get(), _1),
134 m_internalFace, m_keyChain));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800135
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800136 m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(), m_internalFace, m_keyChain));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800137
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800138 m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
139 m_internalFace, m_keyChain));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800140
Alexander Afanasyev2bda6f82015-02-10 14:17:19 -0800141 m_statusServer.reset(new StatusServer(m_internalFace, *m_forwarder, m_keyChain));
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800142
143 ConfigFile config(&ignoreRibAndLogSections);
144 general::setConfigFile(config);
145
146 TablesConfigSection tablesConfig(m_forwarder->getCs(),
147 m_forwarder->getPit(),
148 m_forwarder->getFib(),
149 m_forwarder->getStrategyChoice(),
150 m_forwarder->getMeasurements());
151 tablesConfig.setConfigFile(config);
152
153 m_internalFace->getValidator().setConfigFile(config);
154
155 m_forwarder->getFaceTable().addReserved(m_internalFace, FACEID_INTERNAL_FACE);
156
157 m_faceManager->setConfigFile(config);
158
159 // parse config file
160 if (!m_configFile.empty()) {
161 config.parse(m_configFile, true);
162 config.parse(m_configFile, false);
163 }
164 else {
165 config.parse(m_configSection, true, INTERNAL_CONFIG);
166 config.parse(m_configSection, false, INTERNAL_CONFIG);
167 }
168
169 tablesConfig.ensureTablesAreConfigured();
170
171 // add FIB entry for NFD Management Protocol
172 shared_ptr<fib::Entry> entry = m_forwarder->getFib().insert("/localhost/nfd").first;
173 entry->addNextHop(m_internalFace, 0);
174}
175
176void
177Nfd::reloadConfigFile()
178{
179 // Logging
180 initializeLogging();
181 /// \todo Reopen log file
182
183 // Other stuff
184 ConfigFile config(&ignoreRibAndLogSections);
185
186 general::setConfigFile(config);
187
188 TablesConfigSection tablesConfig(m_forwarder->getCs(),
189 m_forwarder->getPit(),
190 m_forwarder->getFib(),
191 m_forwarder->getStrategyChoice(),
192 m_forwarder->getMeasurements());
193
194 tablesConfig.setConfigFile(config);
195
196 m_internalFace->getValidator().setConfigFile(config);
197 m_faceManager->setConfigFile(config);
198
199 if (!m_configFile.empty()) {
200 config.parse(m_configFile, false);
201 }
202 else {
203 config.parse(m_configSection, false, INTERNAL_CONFIG);
204 }
205}
206
Alexander Afanasyev3f41ade2015-06-29 18:31:22 -0700207void
208Nfd::reloadConfigFileFaceSection()
209{
210 // reload only face_system section of the config file to re-initialize multicast faces
211 ConfigFile config(&ConfigFile::ignoreUnknownSection);
212 m_faceManager->setConfigFile(config);
213
214 if (!m_configFile.empty()) {
215 config.parse(m_configFile, false);
216 }
217 else {
218 config.parse(m_configSection, false, INTERNAL_CONFIG);
219 }
220}
221
Alexander Afanasyev31c781e2015-02-09 17:39:59 -0800222} // namespace nfd