blob: 739883c89d8d2d3c0b34d50c511b2592c8851889 [file] [log] [blame]
Alexander Afanasyev31367922015-02-09 20:51:10 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoa3148082018-04-12 18:21:54 -04002/*
3 * Copyright (c) 2014-2018, Regents of the University of California,
Alexander Afanasyev31367922015-02-09 20:51:10 -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
Junxiao Shib2600172016-07-11 08:53:53 +000026#include "service.hpp"
Davide Pesavento9f8b10e2018-08-22 08:45:37 +000027
28#include "auto-prefix-propagator.hpp"
29#include "fib-updater.hpp"
Alexander Afanasyev31367922015-02-09 20:51:10 -080030#include "rib-manager.hpp"
Davide Pesavento9f8b10e2018-08-22 08:45:37 +000031#include "readvertise/client-to-nlsr-readvertise-policy.hpp"
32#include "readvertise/nfd-rib-readvertise-destination.hpp"
33#include "readvertise/readvertise.hpp"
34
Alexander Afanasyev31367922015-02-09 20:51:10 -080035#include "core/global-io.hpp"
36
37#include <boost/property_tree/info_parser.hpp>
38
Alexander Afanasyev31367922015-02-09 20:51:10 -080039#include <ndn-cxx/transport/tcp-transport.hpp>
Davide Pesavento9f8b10e2018-08-22 08:45:37 +000040#include <ndn-cxx/transport/unix-transport.hpp>
Alexander Afanasyev31367922015-02-09 20:51:10 -080041
42namespace nfd {
43namespace rib {
44
45static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
Davide Pesavento9f8b10e2018-08-22 08:45:37 +000046static const Name READVERTISE_NLSR_PREFIX = "/localhost/nlsr";
Alexander Afanasyev31367922015-02-09 20:51:10 -080047
Teng Liang04d5ce62018-08-06 10:20:24 +080048Service* Service::s_instance = nullptr;
49
Junxiao Shib2600172016-07-11 08:53:53 +000050Service::Service(const std::string& configFile, ndn::KeyChain& keyChain)
Alexander Afanasyev31367922015-02-09 20:51:10 -080051 : m_configFile(configFile)
52 , m_keyChain(keyChain)
53{
Teng Liang04d5ce62018-08-06 10:20:24 +080054 if (s_instance != nullptr) {
55 BOOST_THROW_EXCEPTION(std::logic_error("RIB service cannot be instantiated more than once"));
56 }
57 if (&getGlobalIoService() != &getRibIoService()) {
58 BOOST_THROW_EXCEPTION(std::logic_error("RIB service must run on RIB thread"));
59 }
60 s_instance = this;
Alexander Afanasyev31367922015-02-09 20:51:10 -080061}
62
Davide Pesavento9f8b10e2018-08-22 08:45:37 +000063Service::Service(const ConfigSection& configSection, ndn::KeyChain& keyChain)
64 : m_configSection(configSection)
Alexander Afanasyev31367922015-02-09 20:51:10 -080065 , m_keyChain(keyChain)
66{
Teng Liang04d5ce62018-08-06 10:20:24 +080067 if (s_instance != nullptr) {
68 BOOST_THROW_EXCEPTION(std::logic_error("RIB service cannot be instantiated more than once"));
69 }
70 if (&getGlobalIoService() != &getRibIoService()) {
71 BOOST_THROW_EXCEPTION(std::logic_error("RIB service must run on RIB thread"));
72 }
73 s_instance = this;
Alexander Afanasyev31367922015-02-09 20:51:10 -080074}
75
Teng Liang04d5ce62018-08-06 10:20:24 +080076Service::~Service()
77{
78 s_instance = nullptr;
79}
80
81Service&
82Service::get()
83{
84 if (s_instance == nullptr) {
85 BOOST_THROW_EXCEPTION(std::logic_error("RIB service is not instantiated"));
86 }
87 if (&getGlobalIoService() != &getRibIoService()) {
88 BOOST_THROW_EXCEPTION(std::logic_error("Must get RIB service on RIB thread"));
89 }
90 return *s_instance;
91}
Alexander Afanasyevc3ea5a72015-02-12 20:14:16 -080092
Alexander Afanasyev31367922015-02-09 20:51:10 -080093void
Junxiao Shib2600172016-07-11 08:53:53 +000094Service::initialize()
Alexander Afanasyev31367922015-02-09 20:51:10 -080095{
Davide Pesaventoa3148082018-04-12 18:21:54 -040096 m_face = make_unique<ndn::Face>(getLocalNfdTransport(), getGlobalIoService(), m_keyChain);
Davide Pesavento9f8b10e2018-08-22 08:45:37 +000097 m_nfdController = make_unique<ndn::nfd::Controller>(*m_face, m_keyChain);
98 m_fibUpdater = make_unique<FibUpdater>(m_rib, *m_nfdController);
99 m_prefixPropagator = make_unique<AutoPrefixPropagator>(*m_nfdController, m_keyChain, m_rib);
Davide Pesaventoa3148082018-04-12 18:21:54 -0400100 m_dispatcher = make_unique<ndn::mgmt::Dispatcher>(*m_face, m_keyChain);
Davide Pesavento9f8b10e2018-08-22 08:45:37 +0000101 m_ribManager = make_unique<RibManager>(m_rib, *m_dispatcher, *m_face, *m_nfdController, *m_prefixPropagator);
Alexander Afanasyev31367922015-02-09 20:51:10 -0800102
103 ConfigFile config([] (const std::string& filename, const std::string& sectionName,
104 const ConfigSection& section, bool isDryRun) {
Davide Pesaventoa3148082018-04-12 18:21:54 -0400105 // Ignore sections belonging to NFD, but raise an error
106 // if we're missing a handler for a "rib" section.
107 if (sectionName == "rib") {
Alexander Afanasyev31367922015-02-09 20:51:10 -0800108 ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
109 }
110 });
111 m_ribManager->setConfigFile(config);
112
113 // parse config file
114 if (!m_configFile.empty()) {
115 config.parse(m_configFile, true);
116 config.parse(m_configFile, false);
117 }
118 else {
119 config.parse(m_configSection, true, INTERNAL_CONFIG);
120 config.parse(m_configSection, false, INTERNAL_CONFIG);
121 }
122
Davide Pesavento9f8b10e2018-08-22 08:45:37 +0000123 if (m_ribManager->wantAutoPrefixPropagator) {
124 m_prefixPropagator->enable();
125 }
126 else {
127 m_prefixPropagator->disable();
128 }
129
130 if (m_ribManager->wantReadvertiseToNlsr && m_readvertiseNlsr == nullptr) {
131 m_readvertiseNlsr = make_unique<Readvertise>(
132 m_rib,
133 make_unique<ClientToNlsrReadvertisePolicy>(),
134 make_unique<NfdRibReadvertiseDestination>(*m_nfdController, READVERTISE_NLSR_PREFIX, m_rib));
135 }
136 else if (!m_ribManager->wantReadvertiseToNlsr && m_readvertiseNlsr != nullptr) {
137 m_readvertiseNlsr.reset();
138 }
139
Alexander Afanasyev31367922015-02-09 20:51:10 -0800140 m_ribManager->registerWithNfd();
Eric Newberryecc45cb2016-11-08 19:57:12 +0000141 m_ribManager->enableLocalFields();
Alexander Afanasyev31367922015-02-09 20:51:10 -0800142}
143
Alexander Afanasyev31367922015-02-09 20:51:10 -0800144shared_ptr<ndn::Transport>
Junxiao Shib2600172016-07-11 08:53:53 +0000145Service::getLocalNfdTransport()
Alexander Afanasyev31367922015-02-09 20:51:10 -0800146{
147 ConfigSection config;
148
149 if (!m_configFile.empty()) {
150 // Any format errors should have been caught already
151 // If error is thrown at this point, it is development error
152 boost::property_tree::read_info(m_configFile, config);
153 }
Davide Pesaventoa3148082018-04-12 18:21:54 -0400154 else {
Alexander Afanasyev31367922015-02-09 20:51:10 -0800155 config = m_configSection;
Davide Pesaventoa3148082018-04-12 18:21:54 -0400156 }
Alexander Afanasyev31367922015-02-09 20:51:10 -0800157
158 if (config.get_child_optional("face_system.unix")) {
159 // unix socket enabled
160
Davide Pesaventoa3148082018-04-12 18:21:54 -0400161 auto socketPath = config.get<std::string>("face_system.unix.path", "/var/run/nfd.sock");
Davide Pesavento9f8b10e2018-08-22 08:45:37 +0000162 // default socketPath should be the same as in UnixStreamFactory::processConfig
Alexander Afanasyev31367922015-02-09 20:51:10 -0800163
164 return make_shared<ndn::UnixTransport>(socketPath);
165 }
166 else if (config.get_child_optional("face_system.tcp") &&
167 config.get<std::string>("face_system.tcp.listen", "yes") == "yes") {
168 // tcp is enabled
169
Davide Pesaventoa3148082018-04-12 18:21:54 -0400170 auto port = config.get<std::string>("face_system.tcp.port", "6363");
Davide Pesavento9f8b10e2018-08-22 08:45:37 +0000171 // default port should be the same as in TcpFactory::processConfig
Alexander Afanasyev31367922015-02-09 20:51:10 -0800172
173 return make_shared<ndn::TcpTransport>("localhost", port);
174 }
175 else {
Spyridon Mastorakis149e02c2015-07-27 13:22:22 -0700176 BOOST_THROW_EXCEPTION(Error("No transport is available to communicate with NFD"));
Alexander Afanasyev31367922015-02-09 20:51:10 -0800177 }
178}
179
180} // namespace rib
181} // namespace nfd