dispatcher.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2023 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
22 #ifndef NDN_CXX_MGMT_DISPATCHER_HPP
23 #define NDN_CXX_MGMT_DISPATCHER_HPP
24 
25 #include "ndn-cxx/face.hpp"
32 
33 #include <unordered_map>
34 
35 namespace ndn::mgmt {
36 
37 // ---- AUTHORIZATION ----
38 
44 using AcceptContinuation = std::function<void(const std::string& requester)>;
45 
49 enum class RejectReply {
53  SILENT,
57  STATUS403
58 };
59 
63 using RejectContinuation = std::function<void(RejectReply)>;
64 
77 using Authorization = std::function<void(const Name& prefix, const Interest& interest,
78  const ControlParameters* params,
79  const AcceptContinuation& accept,
80  const RejectContinuation& reject)>;
81 
87 
88 // ---- CONTROL COMMAND ----
89 
94 using ValidateParameters = std::function<bool(const ControlParameters& params)>;
95 
99 using CommandContinuation = std::function<void(const ControlResponse& resp)>;
100 
108 using ControlCommandHandler = std::function<void(const Name& prefix, const Interest& interest,
109  const ControlParameters& params,
110  const CommandContinuation& done)>;
111 
112 // ---- STATUS DATASET ----
113 
121 using StatusDatasetHandler = std::function<void(const Name& prefix, const Interest& interest,
122  StatusDatasetContext& context)>;
123 
124 //---- NOTIFICATION STREAM ----
125 
129 using PostNotification = std::function<void(const Block& notification)>;
130 
131 // ---- DISPATCHER ----
132 
136 class Dispatcher : noncopyable
137 {
138 public:
145  Dispatcher(Face& face, KeyChain& keyChain,
146  const security::SigningInfo& signingInfo = security::SigningInfo(),
147  size_t imsCapacity = 256);
148 
149  virtual
151 
171  void
172  addTopPrefix(const Name& prefix, bool wantRegister = true,
173  const security::SigningInfo& signingInfo = security::SigningInfo());
174 
183  void
184  removeTopPrefix(const Name& prefix);
185 
186 public: // ControlCommand
212  template<typename CP>
213  void
214  addControlCommand(const PartialName& relPrefix,
215  Authorization authorize,
216  ValidateParameters validate,
217  ControlCommandHandler handle);
218 
219 public: // StatusDataset
250  void
251  addStatusDataset(const PartialName& relPrefix,
252  Authorization authorize,
253  StatusDatasetHandler handle);
254 
255 public: // NotificationStream
276  addNotificationStream(const PartialName& relPrefix);
277 
278 private:
279  using InterestHandler = std::function<void(const Name& prefix, const Interest&)>;
280 
281  using AuthorizationAcceptedCallback = std::function<void(const std::string& requester,
282  const Name& prefix,
283  const Interest&,
284  const shared_ptr<ControlParameters>&)>;
285 
286  using AuthorizationRejectedCallback = std::function<void(RejectReply, const Interest&)>;
287 
293  using ControlParametersParser = std::function<shared_ptr<ControlParameters>(const name::Component&)>;
294 
295  bool
296  isOverlappedWithOthers(const PartialName& relPrefix) const;
297 
303  void
304  afterAuthorizationRejected(RejectReply act, const Interest& interest);
305 
315  void
316  queryStorage(const Name& prefix, const Interest& interest, const InterestHandler& missContinuation);
317 
318  enum class SendDestination {
319  NONE = 0,
320  FACE = 1,
321  IMS = 2,
322  FACE_AND_IMS = 3
323  };
324 
340  void
341  sendData(const Name& dataName, const Block& content, const MetaInfo& metaInfo,
342  SendDestination destination);
343 
349  void
350  sendOnFace(const Data& data);
351 
363  void
364  processControlCommandInterest(const Name& prefix,
365  const Name& relPrefix,
366  const Interest& interest,
367  const ControlParametersParser& parser,
368  const Authorization& authorization,
369  const AuthorizationAcceptedCallback& accepted,
370  const AuthorizationRejectedCallback& rejected);
371 
382  void
383  processAuthorizedControlCommandInterest(const std::string& requester,
384  const Name& prefix,
385  const Interest& interest,
386  const shared_ptr<ControlParameters>& parameters,
387  const ValidateParameters& validate,
388  const ControlCommandHandler& handler);
389 
390  void
391  sendControlResponse(const ControlResponse& resp, const Interest& interest, bool isNack = false);
392 
402  void
403  processStatusDatasetInterest(const Name& prefix,
404  const Interest& interest,
405  const Authorization& authorization,
406  const AuthorizationAcceptedCallback& accepted,
407  const AuthorizationRejectedCallback& rejected);
408 
416  void
417  processAuthorizedStatusDatasetInterest(const Name& prefix,
418  const Interest& interest,
419  const StatusDatasetHandler& handler);
420 
428  void
429  sendStatusDatasetSegment(const Name& dataName, const Block& content, bool isFinalBlock);
430 
431  void
432  postNotification(const Block& notification, const PartialName& relPrefix);
433 
434 private:
435  struct TopPrefixEntry
436  {
437  ScopedRegisteredPrefixHandle registeredPrefix;
438  std::vector<ScopedInterestFilterHandle> interestFilters;
439  };
440  std::unordered_map<Name, TopPrefixEntry> m_topLevelPrefixes;
441 
442  Face& m_face;
443  KeyChain& m_keyChain;
444  security::SigningInfo m_signingInfo;
445 
446  std::unordered_map<PartialName, InterestHandler> m_handlers;
447 
448  // NotificationStream name => next sequence number
449  std::unordered_map<Name, uint64_t> m_streams;
450 
452  InMemoryStorageFifo m_storage;
453 };
454 
455 template<typename CP>
456 void
458  Authorization authorize,
459  ValidateParameters validate,
460  ControlCommandHandler handle)
461 {
462  if (!m_topLevelPrefixes.empty()) {
463  NDN_THROW(std::domain_error("one or more top-level prefix has been added"));
464  }
465 
466  if (isOverlappedWithOthers(relPrefix)) {
467  NDN_THROW(std::out_of_range("relPrefix overlaps with another relPrefix"));
468  }
469 
470  ControlParametersParser parser = [] (const name::Component& comp) -> shared_ptr<ControlParameters> {
471  return make_shared<CP>(comp.blockFromValue());
472  };
473  AuthorizationAcceptedCallback accepted = [this, validate = std::move(validate),
474  handle = std::move(handle)] (auto&&... args) {
475  processAuthorizedControlCommandInterest(std::forward<decltype(args)>(args)..., validate, handle);
476  };
477  AuthorizationRejectedCallback rejected = [this] (auto&&... args) {
478  afterAuthorizationRejected(std::forward<decltype(args)>(args)...);
479  };
480 
481  m_handlers[relPrefix] = [this, relPrefix,
482  parser = std::move(parser),
483  authorize = std::move(authorize),
484  accepted = std::move(accepted),
485  rejected = std::move(rejected)] (const auto& prefix, const auto& interest) {
486  processControlCommandInterest(prefix, relPrefix, interest, parser, authorize, accepted, rejected);
487  };
488 }
489 
490 } // namespace ndn::mgmt
491 
492 #endif // NDN_CXX_MGMT_DISPATCHER_HPP
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
Represents a Data packet.
Definition: data.hpp:39
Provide a communication channel with local or remote NDN forwarder.
Definition: face.hpp:91
Provides in-memory storage employing First-In-First-Out (FIFO) replacement policy.
Represents an Interest packet.
Definition: interest.hpp:50
A MetaInfo holds the meta info which is signed inside the Data packet.
Definition: meta-info.hpp:62
Represents an absolute name.
Definition: name.hpp:45
Base class for a struct that contains ControlCommand parameters.
ControlCommand response.
Implements a request dispatcher on server side of NFD Management protocol.
Definition: dispatcher.hpp:137
PostNotification addNotificationStream(const PartialName &relPrefix)
Register a NotificationStream.
Definition: dispatcher.cpp:308
Dispatcher(Face &face, KeyChain &keyChain, const security::SigningInfo &signingInfo=security::SigningInfo(), size_t imsCapacity=256)
Constructor.
Definition: dispatcher.cpp:44
void addStatusDataset(const PartialName &relPrefix, Authorization authorize, StatusDatasetHandler handle)
Register a StatusDataset or a prefix under which StatusDatasets can be requested.
Definition: dispatcher.cpp:224
void addControlCommand(const PartialName &relPrefix, Authorization authorize, ValidateParameters validate, ControlCommandHandler handle)
Register a ControlCommand.
Definition: dispatcher.hpp:457
void addTopPrefix(const Name &prefix, bool wantRegister=true, const security::SigningInfo &signingInfo=security::SigningInfo())
Add a top-level prefix.
Definition: dispatcher.cpp:57
void removeTopPrefix(const Name &prefix)
Remove a top-level prefix.
Definition: dispatcher.cpp:90
Provides a context for generating the response to a StatusDataset request.
Represents a name component.
The main interface for signing key management.
Definition: key-chain.hpp:87
Signing parameters passed to KeyChain.
#define NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE
Definition: common.hpp:49
#define NDN_THROW(e)
Definition: exception.hpp:56
std::function< void(const std::string &requester)> AcceptContinuation
A function to be called if authorization is successful.
Definition: dispatcher.hpp:44
std::function< void(const Name &prefix, const Interest &interest, const ControlParameters *params, const AcceptContinuation &accept, const RejectContinuation &reject)> Authorization
A function that performs authorization.
Definition: dispatcher.hpp:80
std::function< void(const Block &notification)> PostNotification
A function to post a notification.
Definition: dispatcher.hpp:129
std::function< void(RejectReply)> RejectContinuation
A function to be called if authorization is rejected.
Definition: dispatcher.hpp:63
RejectReply
Indicates how to reply in case authorization is rejected.
Definition: dispatcher.hpp:49
@ SILENT
Do not reply.
@ STATUS403
Reply with a ControlResponse where StatusCode is 403.
std::function< bool(const ControlParameters &params)> ValidateParameters
A function to validate input ControlParameters.
Definition: dispatcher.hpp:94
std::function< void(const Name &prefix, const Interest &interest, const ControlParameters &params, const CommandContinuation &done)> ControlCommandHandler
A function to handle an authorized ControlCommand.
Definition: dispatcher.hpp:110
Authorization makeAcceptAllAuthorization()
Return an Authorization that accepts all Interests, with empty string as requester.
Definition: dispatcher.cpp:33
std::function< void(const ControlResponse &resp)> CommandContinuation
A function to be called after ControlCommandHandler completes.
Definition: dispatcher.hpp:99
std::function< void(const Name &prefix, const Interest &interest, StatusDatasetContext &context)> StatusDatasetHandler
A function to handle a StatusDataset request.
Definition: dispatcher.hpp:122