blob: d199e2957e1c9cee91c50391959e491751b9e074 [file] [log] [blame]
Shock Jiangcde28712014-10-19 21:17:20 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yumin Xia2c509c22017-02-09 14:37:36 -08002/*
Alexander Afanasyev60514ec2020-06-03 14:18:53 -04003 * Copyright (c) 2014-2020, Regents of the University of California.
Shock Jiangcde28712014-10-19 21:17:20 -07004 *
5 * This file is part of NDNS (Named Data Networking Domain Name Service).
6 * See AUTHORS.md for complete list of NDNS authors and contributors.
7 *
8 * NDNS is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
Davide Pesavento7debce92019-01-20 16:12:29 -050020#include "logger.hpp"
Shock Jiangcde28712014-10-19 21:17:20 -070021#include "daemon/config-file.hpp"
Davide Pesavento7debce92019-01-20 16:12:29 -050022#include "daemon/name-server.hpp"
Yumin Xia2c509c22017-02-09 14:37:36 -080023#include "util/cert-helper.hpp"
Davide Pesaventod01c1a42019-01-21 21:42:45 -050024#include "util/util.hpp"
Yumin Xia2c509c22017-02-09 14:37:36 -080025
Davide Pesavento7debce92019-01-20 16:12:29 -050026#include <ndn-cxx/face.hpp>
27#include <ndn-cxx/security/key-chain.hpp>
28
29#include <boost/asio/io_service.hpp>
Davide Pesavento7debce92019-01-20 16:12:29 -050030#include <boost/program_options.hpp>
31
Davide Pesavento948c50c2020-12-26 21:30:45 -050032#include <iostream>
33
Davide Pesavento7debce92019-01-20 16:12:29 -050034NDNS_LOG_INIT(NdnsDaemon);
Shock Jiangcde28712014-10-19 21:17:20 -070035
36namespace ndn {
37namespace ndns {
38
Shock Jiangcde28712014-10-19 21:17:20 -070039/**
40 * @brief Name Server Daemon
41 * @note NdnsDaemon allows multiple name servers hosted by the same daemon, and they
42 * share same KeyChain, DbMgr, Validator and Face
43 */
Davide Pesavento948c50c2020-12-26 21:30:45 -050044class NdnsDaemon : boost::noncopyable
Shock Jiangcde28712014-10-19 21:17:20 -070045{
Shock Jiange1a81fd2014-11-20 20:25:49 -080046public:
Shock Jiangcde28712014-10-19 21:17:20 -070047 DEFINE_ERROR(Error, std::runtime_error);
48
Shock Jiange1a81fd2014-11-20 20:25:49 -080049 NdnsDaemon(const std::string& configFile, Face& face, Face& validatorFace)
50 : m_face(face)
51 , m_validatorFace(validatorFace)
Shock Jiangcde28712014-10-19 21:17:20 -070052 {
Davide Pesavento7debce92019-01-20 16:12:29 -050053 NDNS_LOG_INFO("ConfigFile = " << configFile);
54 ConfigFile config;
55 config.addSectionHandler("zones", bind(&NdnsDaemon::processZonesSection, this, _1));
56 config.parse(configFile, false);
Shock Jiangcde28712014-10-19 21:17:20 -070057 }
58
59 void
Davide Pesavento7debce92019-01-20 16:12:29 -050060 processZonesSection(const ndn::ndns::ConfigSection& section)
Shock Jiangcde28712014-10-19 21:17:20 -070061 {
Shock Jiangcde28712014-10-19 21:17:20 -070062 if (section.begin() == section.end()) {
Davide Pesavento948c50c2020-12-26 21:30:45 -050063 NDN_THROW(Error("zones section is empty"));
Shock Jiangcde28712014-10-19 21:17:20 -070064 }
65
Davide Pesaventod01c1a42019-01-21 21:42:45 -050066 std::string dbFile = getDefaultDatabaseFile();
Davide Pesavento7debce92019-01-20 16:12:29 -050067 auto item = section.find("dbFile");
Shock Jiangcde28712014-10-19 21:17:20 -070068 if (item != section.not_found()) {
Shock Jiange1a81fd2014-11-20 20:25:49 -080069 dbFile = item->second.get_value<std::string>();
Shock Jiangcde28712014-10-19 21:17:20 -070070 }
Shock Jiange1a81fd2014-11-20 20:25:49 -080071 NDNS_LOG_INFO("DbFile = " << dbFile);
Davide Pesavento7debce92019-01-20 16:12:29 -050072 m_dbMgr = make_unique<DbMgr>(dbFile);
Shock Jiangcde28712014-10-19 21:17:20 -070073
Davide Pesaventod01c1a42019-01-21 21:42:45 -050074 std::string validatorConfigFile(NDNS_CONFDIR "/validator.conf");
Shock Jiange1a81fd2014-11-20 20:25:49 -080075 item = section.find("validatorConfigFile");
76 if (item != section.not_found()) {
77 validatorConfigFile = item->second.get_value<std::string>();
78 }
79 NDNS_LOG_INFO("ValidatorConfigFile = " << validatorConfigFile);
Yumin Xiafa2bce72017-04-09 16:20:25 -070080 m_validator = NdnsValidatorBuilder::create(m_validatorFace, 500, 0, validatorConfigFile);
Shock Jiangcde28712014-10-19 21:17:20 -070081
82 for (const auto& option : section) {
83 Name name;
84 Name cert;
85 if (option.first == "zone") {
86 try {
87 name = option.second.get<Name>("name"); // exception leads to exit
88 }
Davide Pesavento7debce92019-01-20 16:12:29 -050089 catch (const std::exception&) {
Shock Jiangcde28712014-10-19 21:17:20 -070090 NDNS_LOG_ERROR("Required `name' attribute missing in `zone' section");
Davide Pesavento948c50c2020-12-26 21:30:45 -050091 NDN_THROW(Error("Required `name' attribute missing in `zone' section"));
Shock Jiangcde28712014-10-19 21:17:20 -070092 }
93 try {
94 cert = option.second.get<Name>("cert");
95 }
Yumin Xia2c509c22017-02-09 14:37:36 -080096 catch (const std::exception&) {
Davide Pesavento7debce92019-01-20 16:12:29 -050097 // ignore
Shock Jiangcde28712014-10-19 21:17:20 -070098 }
99
100 if (cert.empty()) {
Shock Jiange1a81fd2014-11-20 20:25:49 -0800101 try {
Davide Pesavento7debce92019-01-20 16:12:29 -0500102 cert = CertHelper::getDefaultCertificateNameOfIdentity(m_keyChain,
103 Name(name)
104 .append(label::NDNS_ITERATIVE_QUERY));
Shock Jiange1a81fd2014-11-20 20:25:49 -0800105 }
Yumin Xia2c509c22017-02-09 14:37:36 -0800106 catch (const std::exception& e) {
Davide Pesavento7debce92019-01-20 16:12:29 -0500107 NDNS_LOG_ERROR("Identity " << name << " does not have a default certificate: " << e.what());
Davide Pesavento948c50c2020-12-26 21:30:45 -0500108 NDN_THROW(Error("identity does not have default certificate"));
Shock Jiange1a81fd2014-11-20 20:25:49 -0800109 }
Shock Jiangcde28712014-10-19 21:17:20 -0700110 }
111 else {
Yumin Xia2c509c22017-02-09 14:37:36 -0800112 try {
113 CertHelper::getCertificate(m_keyChain, name, cert);
Davide Pesavento7debce92019-01-20 16:12:29 -0500114 } catch (const std::exception&) {
Davide Pesavento948c50c2020-12-26 21:30:45 -0500115 NDN_THROW(Error("Certificate `" + cert.toUri() + "` does not exist in the KeyChain"));
Shock Jiangcde28712014-10-19 21:17:20 -0700116 }
117 }
118 NDNS_LOG_TRACE("name = " << name << " cert = " << cert);
119 m_servers.push_back(make_shared<NameServer>(name, cert, m_face, *m_dbMgr,
Shock Jiange1a81fd2014-11-20 20:25:49 -0800120 m_keyChain, *m_validator));
Shock Jiangcde28712014-10-19 21:17:20 -0700121 }
122 } // for
123 }
124
125private:
Shock Jiangcde28712014-10-19 21:17:20 -0700126 Face& m_face;
Shock Jiange1a81fd2014-11-20 20:25:49 -0800127 Face& m_validatorFace;
Alexander Afanasyev60514ec2020-06-03 14:18:53 -0400128 unique_ptr<security::Validator> m_validator;
Shock Jiange1a81fd2014-11-20 20:25:49 -0800129 unique_ptr<DbMgr> m_dbMgr;
130 std::vector<shared_ptr<NameServer>> m_servers;
Shock Jiangcde28712014-10-19 21:17:20 -0700131 KeyChain m_keyChain;
132};
133
134} // namespace ndns
135} // namespace ndn
136
137int
138main(int argc, char* argv[])
139{
Davide Pesaventod01c1a42019-01-21 21:42:45 -0500140 std::string configFile(NDNS_CONFDIR "/ndns.conf");
Shock Jiangcde28712014-10-19 21:17:20 -0700141
Davide Pesavento7debce92019-01-20 16:12:29 -0500142 namespace po = boost::program_options;
143 po::options_description optsDesc("Options");
144 optsDesc.add_options()
145 ("help,h", "print this help message and exit")
146 ("config-file,c", po::value<std::string>(&configFile)->default_value(configFile),
147 "path to configuration file")
148 ;
Shock Jiangcde28712014-10-19 21:17:20 -0700149
Davide Pesavento7debce92019-01-20 16:12:29 -0500150 po::variables_map vm;
Shock Jiangcde28712014-10-19 21:17:20 -0700151 try {
Davide Pesavento7debce92019-01-20 16:12:29 -0500152 po::store(po::parse_command_line(argc, argv, optsDesc), vm);
Shock Jiangcde28712014-10-19 21:17:20 -0700153 po::notify(vm);
Shock Jiangcde28712014-10-19 21:17:20 -0700154 }
Davide Pesavento7debce92019-01-20 16:12:29 -0500155 catch (const po::error& e) {
156 std::cerr << "ERROR: " << e.what() << std::endl;
157 return 2;
Shock Jiangcde28712014-10-19 21:17:20 -0700158 }
Davide Pesavento7debce92019-01-20 16:12:29 -0500159 catch (const boost::bad_any_cast& e) {
160 std::cerr << "ERROR: " << e.what() << std::endl;
161 return 2;
162 }
163
164 if (vm.count("help") != 0) {
165 std::cout << "Usage: " << argv[0] << " [options]\n"
166 << "\n"
167 << optsDesc;
168 return 0;
Shock Jiangcde28712014-10-19 21:17:20 -0700169 }
170
Shock Jiange1a81fd2014-11-20 20:25:49 -0800171 boost::asio::io_service io;
172 ndn::Face face(io);
173 ndn::Face validatorFace(io);
174
Shock Jiangcde28712014-10-19 21:17:20 -0700175 try {
Shock Jiange1a81fd2014-11-20 20:25:49 -0800176 // NFD does not to forward Interests to the face it was received from.
Davide Pesavento7debce92019-01-20 16:12:29 -0500177 // If the name server and its validator share the same face,
Shock Jiange1a81fd2014-11-20 20:25:49 -0800178 // the validator cannot be forwarded to the name server itself
Davide Pesavento7debce92019-01-20 16:12:29 -0500179 // For now, two faces are used here.
Shock Jiang06cd2142014-11-23 17:36:02 -0800180
Yumin Xia2c509c22017-02-09 14:37:36 -0800181 // refs: https://redmine.named-data.net/issues/2206
Davide Pesavento7debce92019-01-20 16:12:29 -0500182 // @TODO enhance validator to get the certificate from the local db if present
Shock Jiangcde28712014-10-19 21:17:20 -0700183
Davide Pesavento7debce92019-01-20 16:12:29 -0500184 ndn::ndns::NdnsDaemon daemon(configFile, face, validatorFace);
Shock Jiangcde28712014-10-19 21:17:20 -0700185 face.processEvents();
186 }
Yumin Xia2c509c22017-02-09 14:37:36 -0800187 catch (const std::exception& e) {
Davide Pesavento7debce92019-01-20 16:12:29 -0500188 NDNS_LOG_FATAL(e.what());
Shock Jiange1a81fd2014-11-20 20:25:49 -0800189 return 1;
Shock Jiangcde28712014-10-19 21:17:20 -0700190 }
191
192 return 0;
193}