blob: bb1a9701199c2a9b841be755cd3531012e33106f [file] [log] [blame]
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento9f8b10e2018-08-22 08:45:37 +00002/*
3 * Copyright (c) 2014-2018, Regents of the University of California,
Junxiao Shi1e46be32015-01-08 20:18:05 -07004 * 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.
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070010 *
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/>.
Vince12e49462014-06-09 13:29:32 -050024 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070025
26#ifndef NFD_RIB_RIB_MANAGER_HPP
27#define NFD_RIB_RIB_MANAGER_HPP
28
Yanbiao Lid7c96362015-01-30 23:58:24 -080029#include "auto-prefix-propagator.hpp"
Vince Lehman76c751c2014-11-18 17:36:38 -060030#include "fib-updater.hpp"
Nick Gordon9fcf1232017-03-10 22:30:20 +000031#include "rib.hpp"
32
33#include "core/config-file.hpp"
34#include "core/manager-base.hpp"
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070035
Alexander Afanasyev4a771362014-04-24 21:29:33 -070036#include <ndn-cxx/security/validator-config.hpp>
Junxiao Shi25c6ce42016-09-09 13:49:59 +000037#include <ndn-cxx/mgmt/nfd/controller.hpp>
Nick Gordon9fcf1232017-03-10 22:30:20 +000038#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
39#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
Davide Pesaventod396b612017-02-20 22:11:50 -050040#include <ndn-cxx/util/scheduler-scoped-event-id.hpp>
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070041
42namespace nfd {
43namespace rib {
44
Junxiao Shif4cfed12018-08-22 23:26:29 +000045/**
46 * @brief Serve commands and datasets in NFD RIB management protocol.
47 */
Yanbiao Licf0db022016-01-29 00:54:25 -080048class RibManager : public nfd::ManagerBase
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070049{
50public:
Yingdi Yue5224e92014-04-29 18:04:02 -070051 class Error : public std::runtime_error
52 {
53 public:
Junxiao Shif4cfed12018-08-22 23:26:29 +000054 using std::runtime_error::runtime_error;
Yingdi Yue5224e92014-04-29 18:04:02 -070055 };
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070056
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040057 RibManager(Rib& rib, ndn::Face& face, ndn::KeyChain& keyChain, ndn::nfd::Controller& nfdController,
58 Dispatcher& dispatcher, ndn::util::Scheduler& scheduler);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070059
Junxiao Shif4cfed12018-08-22 23:26:29 +000060 /**
61 * @brief Apply localhost_security configuration.
62 */
63 void
64 applyLocalhostConfig(const ConfigSection& section, const std::string& filename);
Vince Lehman26b215c2014-08-17 15:00:41 -050065
Junxiao Shif4cfed12018-08-22 23:26:29 +000066 /**
67 * @brief Apply localhop_security configuration and allow accepting commands on
68 * /localhop/nfd/rib prefix.
69 */
70 void
71 enableLocalhop(const ConfigSection& section, const std::string& filename);
72
73 /**
74 * @brief Disallow accepting commands on /localhop/nfd/rib prefix.
75 */
76 void
77 disableLocalhop();
78
79 /**
80 * @brief Start accepting commands and dataset requests.
81 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070082 void
83 registerWithNfd();
84
Junxiao Shif4cfed12018-08-22 23:26:29 +000085 /**
86 * @brief Enable NDNLP IncomingFaceId field in order to support self-registration commands.
87 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070088 void
Eric Newberryecc45cb2016-11-08 19:57:12 +000089 enableLocalFields();
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070090
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000091public: // self-learning support
92 enum class SlAnnounceResult {
93 OK, ///< RIB and FIB have been updated
94 ERROR, ///< unspecified error
95 VALIDATION_FAILURE, ///< the announcement cannot be verified against the trust schema
96 EXPIRED, ///< the announcement has expired
97 NOT_FOUND, ///< route does not exist (slRenew only)
98 };
99
100 using SlAnnounceCallback = std::function<void(SlAnnounceResult res)>;
101 using SlFindAnnCallback = std::function<void(optional<ndn::PrefixAnnouncement>)>;
102
103 /** \brief Insert a route by prefix announcement from self-learning strategy.
104 * \param pa A prefix announcement. It must contain the Data.
105 * \param faceId Face on which the announcement arrives.
106 * \param maxLifetime Maximum route lifetime as imposed by self-learning strategy.
107 * \param cb Callback to receive the operation result.
108 *
109 * If \p pa passes validation and is unexpired, inserts or replaces a route for the announced
110 * name and faceId whose lifetime is set to the earlier of now+maxLifetime or prefix
111 * announcement expiration time, updates FIB, and invokes \p cb with SlAnnounceResult::OK.
112 * In case \p pa expires when validation completes, invokes \p cb with SlAnnounceResult::EXPIRED.
113 * If \p pa cannot be verified by the trust schema given in rib.localhop_security config key,
114 * or the relevant config has not been loaded via \c enableLocalHop, invokes \p cb with
115 * SlAnnounceResult::VALIDATION_FAILURE.
116 *
117 * Self-learning strategy invokes this method after receiving a Data carrying a prefix
118 * announcement.
119 */
120 void
121 slAnnounce(const ndn::PrefixAnnouncement& pa, uint64_t faceId, time::milliseconds maxLifetime,
122 const SlAnnounceCallback& cb);
123
124 /** \brief Renew a route created by prefix announcement from self-learning strategy.
125 * \param name Data name, for finding RIB entry by longest-prefix-match.
126 * \param faceId Nexthop face.
127 * \param maxLifetime Maximum route lifetime as imposed by self-learning strategy.
128 * \param cb Callback to receive the operation result.
129 *
130 * If the specified route exists, prolongs its lifetime to the earlier of now+maxLifetime or
131 * prefix announcement expiration time, and invokes \p cb with SlAnnounceResult::OK.
132 * If the prefix announcement has expired, invokes \p cb with SlAnnounceResult::EXPIRED.
133 * If the route is not found, invokes \p cb with SlAnnounceResult::NOT_FOUND.
134 *
135 * Self-learning strategy invokes this method after an Interest forwarded via a learned route
136 * is satisfied.
137 *
138 * \bug In current implementation, if an slAnnounce operation is in progress to create a Route
139 * or replace a prefix announcement, slRenew could fail because Route does not exist in
140 * existing RIB, or overwrite the new prefix announcement with an old one.
141 */
142 void
143 slRenew(const Name& name, uint64_t faceId, time::milliseconds maxLifetime,
144 const SlAnnounceCallback& cb);
145
146 /** \brief Retrieve an outgoing prefix announcement for self-learning strategy.
147 * \param name Data name.
148 * \param cb Callback to receive a prefix announcement that announces a prefix of \p name, or
149 * nullopt if no RIB entry is found by longest-prefix-match of \p name.
150 *
151 * Self-learning strategy invokes this method before sending a Data in reply to a discovery
152 * Interest, so as to attach a prefix announcement onto that Data.
153 *
154 * \bug In current implementation, if an slAnnounce operation is in progress, slFindAnn does not
155 * wait for that operation to complete and its result reflects the prior RIB state.
156 */
157 void
158 slFindAnn(const Name& name, const SlFindAnnCallback& cb) const;
159
Junxiao Shi52009042018-09-10 12:33:56 +0000160private: // RIB and FibUpdater actions
161 enum class RibUpdateResult
162 {
163 OK,
164 ERROR,
165 EXPIRED,
166 };
167
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000168 static SlAnnounceResult
169 getSlAnnounceResultFromRibUpdateResult(RibUpdateResult r);
170
Junxiao Shi52009042018-09-10 12:33:56 +0000171 /** \brief Start adding a route to RIB and FIB.
172 * \param name route name
173 * \param route route parameters; may contain absolute expiration time
174 * \param expires relative expiration time; if specified, overwrites \c route.expires
175 * \param done completion callback
176 */
Vince Lehman76c751c2014-11-18 17:36:38 -0600177 void
Junxiao Shi52009042018-09-10 12:33:56 +0000178 beginAddRoute(const Name& name, Route route, optional<time::nanoseconds> expires,
179 const std::function<void(RibUpdateResult)>& done);
180
181 /** \brief Start removing a route from RIB and FIB.
182 * \param name route name
183 * \param route route parameters
184 * \param done completion callback
185 */
186 void
187 beginRemoveRoute(const Name& name, const Route& route,
188 const std::function<void(RibUpdateResult)>& done);
Vince Lehman4387e782014-06-19 16:57:45 -0500189
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700190 void
Junxiao Shi52009042018-09-10 12:33:56 +0000191 beginRibUpdate(const RibUpdate& update, const std::function<void(RibUpdateResult)>& done);
Vince Lehman76c751c2014-11-18 17:36:38 -0600192
Junxiao Shi52009042018-09-10 12:33:56 +0000193private: // management Dispatcher related
Vince Lehman76c751c2014-11-18 17:36:38 -0600194 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800195 registerTopPrefix(const Name& topPrefix);
196
Junxiao Shi52009042018-09-10 12:33:56 +0000197 /** \brief Serve rib/register command.
198 */
Yanbiao Licf0db022016-01-29 00:54:25 -0800199 void
200 registerEntry(const Name& topPrefix, const Interest& interest,
201 ControlParameters parameters,
202 const ndn::mgmt::CommandContinuation& done);
Junxiao Shia3295742014-05-16 22:40:10 -0700203
Junxiao Shi52009042018-09-10 12:33:56 +0000204 /** \brief Serve rib/unregister command.
205 */
Junxiao Shia3295742014-05-16 22:40:10 -0700206 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800207 unregisterEntry(const Name& topPrefix, const Interest& interest,
208 ControlParameters parameters,
209 const ndn::mgmt::CommandContinuation& done);
Yingdi Yue5224e92014-04-29 18:04:02 -0700210
Junxiao Shi52009042018-09-10 12:33:56 +0000211 /** \brief Serve rib/list dataset.
212 */
Yingdi Yue5224e92014-04-29 18:04:02 -0700213 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800214 listEntries(const Name& topPrefix, const Interest& interest,
215 ndn::mgmt::StatusDatasetContext& context);
Yingdi Yue5224e92014-04-29 18:04:02 -0700216
217 void
Yanbiao Licf0db022016-01-29 00:54:25 -0800218 setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700219
Nick Gordon9fcf1232017-03-10 22:30:20 +0000220 ndn::mgmt::Authorization
Junxiao Shi21738402016-08-19 19:48:00 +0000221 makeAuthorization(const std::string& verb) override;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700222
Yanbiao Licf0db022016-01-29 00:54:25 -0800223private: // Face monitor
Vince Lehman26b215c2014-08-17 15:00:41 -0500224 void
Vince Lehmancd613c52014-07-30 14:34:49 -0500225 fetchActiveFaces();
226
227 void
Weiwei Liu6e21cdb2016-09-29 15:16:23 -0700228 onFetchActiveFacesFailure(uint32_t code, const std::string& reason);
Vince Lehmancd613c52014-07-30 14:34:49 -0500229
Yanbiao Licf0db022016-01-29 00:54:25 -0800230 void
231 onFaceDestroyedEvent(uint64_t faceId);
232
Vince Lehman281ded72014-08-21 12:17:08 -0500233PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Yanbiao Licf0db022016-01-29 00:54:25 -0800234 void
235 scheduleActiveFaceFetch(const time::seconds& timeToWait);
236
Vince Lehman26b215c2014-08-17 15:00:41 -0500237 void
Weiwei Liu6e21cdb2016-09-29 15:16:23 -0700238 removeInvalidFaces(const std::vector<ndn::nfd::FaceStatus>& activeFaces);
Vince Lehman26b215c2014-08-17 15:00:41 -0500239
Yanbiao Licf0db022016-01-29 00:54:25 -0800240 void
Nick Gordon9fcf1232017-03-10 22:30:20 +0000241 onNotification(const ndn::nfd::FaceEventNotification& notification);
Yanbiao Licf0db022016-01-29 00:54:25 -0800242
243private:
Davide Pesavento9f8b10e2018-08-22 08:45:37 +0000244 Rib& m_rib;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000245 ndn::KeyChain& m_keyChain;
Davide Pesavento9f8b10e2018-08-22 08:45:37 +0000246 ndn::nfd::Controller& m_nfdController;
Junxiao Shif4cfed12018-08-22 23:26:29 +0000247 Dispatcher& m_dispatcher;
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400248 ndn::util::Scheduler& m_scheduler;
Junxiao Shif4cfed12018-08-22 23:26:29 +0000249
Yanbiao Licf0db022016-01-29 00:54:25 -0800250 ndn::nfd::FaceMonitor m_faceMonitor;
Yingdi Yue5224e92014-04-29 18:04:02 -0700251 ndn::ValidatorConfig m_localhostValidator;
252 ndn::ValidatorConfig m_localhopValidator;
Junxiao Shif4cfed12018-08-22 23:26:29 +0000253 bool m_isLocalhopEnabled;
Vince Lehman4387e782014-06-19 16:57:45 -0500254
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400255 ndn::util::scheduler::ScopedEventId m_activeFaceFetchEvent;
256 using FaceIdSet = std::set<uint64_t>;
257 FaceIdSet m_registeredFaces; ///< contains FaceIds with one or more Routes in the RIB
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700258};
259
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000260std::ostream&
261operator<<(std::ostream& os, RibManager::SlAnnounceResult res);
262
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700263} // namespace rib
264} // namespace nfd
265
266#endif // NFD_RIB_RIB_MANAGER_HPP