35 return [] (
const Name& prefix,
48 , m_keyChain(keyChain)
49 , m_signingInfo(signingInfo)
50 , m_storage(m_face.getIoContext(), imsCapacity)
60 bool hasOverlap = std::any_of(m_topLevelPrefixes.begin(), m_topLevelPrefixes.end(),
61 [&prefix] (
const auto& x) {
62 return x.first.isPrefixOf(prefix) || prefix.isPrefixOf(x.first);
65 NDN_THROW(std::out_of_range(
"top-level prefix overlaps"));
68 TopPrefixEntry& topPrefixEntry = m_topLevelPrefixes[prefix];
73 [] (
const Name&,
const std::string& reason) {
74 NDN_THROW(std::runtime_error(
"prefix registration failed: " + reason));
79 for (
const auto& entry : m_handlers) {
80 Name fullPrefix =
Name(prefix).append(entry.first);
82 [=, cb = entry.second] (
const auto&,
const auto& interest) {
85 topPrefixEntry.interestFilters.emplace_back(std::move(filterHdl));
92 m_topLevelPrefixes.erase(prefix);
96 Dispatcher::isOverlappedWithOthers(
const PartialName& relPrefix)
const
98 bool hasOverlapWithHandlers =
99 std::any_of(m_handlers.begin(), m_handlers.end(),
100 [&] (
const auto& entry) {
101 return entry.first.isPrefixOf(relPrefix) || relPrefix.isPrefixOf(entry.first);
103 bool hasOverlapWithStreams =
104 std::any_of(m_streams.begin(), m_streams.end(),
105 [&] (
const auto& entry) {
106 return entry.first.isPrefixOf(relPrefix) || relPrefix.isPrefixOf(entry.first);
109 return hasOverlapWithHandlers || hasOverlapWithStreams;
116 sendControlResponse(
ControlResponse(403,
"authorization rejected"), interest);
121 Dispatcher::queryStorage(
const Name& prefix,
const Interest& interest,
122 const InterestHandler& missContinuation)
124 auto data = m_storage.
find(interest);
125 if (data ==
nullptr) {
127 if (missContinuation)
128 missContinuation(prefix, interest);
137 Dispatcher::sendData(
const Name& dataName,
const Block& content,
const MetaInfo& metaInfo,
138 SendDestination option)
140 auto data = make_shared<Data>(dataName);
141 data->setContent(content).setMetaInfo(metaInfo).setFreshnessPeriod(1_s);
143 m_keyChain.
sign(*data, m_signingInfo);
145 if (option == SendDestination::IMS || option == SendDestination::FACE_AND_IMS) {
148 data->setTag(make_shared<lp::CachePolicyTag>(policy));
149 m_storage.
insert(*data, 1_s);
152 if (option == SendDestination::FACE || option == SendDestination::FACE_AND_IMS) {
158 Dispatcher::sendOnFace(
const Data& data)
163 catch (
const Face::Error& e) {
164 NDN_LOG_ERROR(
"sendOnFace(" << data.getName() <<
"): " << e.what());
169 Dispatcher::processControlCommandInterest(
const Name& prefix,
170 const Name& relPrefix,
172 const ControlParametersParser& parser,
174 const AuthorizationAcceptedCallback& accepted,
175 const AuthorizationRejectedCallback& rejected)
178 size_t parametersLoc = prefix.size() + relPrefix.size();
179 const name::Component& pc = interest.getName().get(parametersLoc);
181 shared_ptr<ControlParameters> parameters;
183 parameters = parser(pc);
185 catch (
const tlv::Error&) {
189 AcceptContinuation accept = [=] (
const auto& req) { accepted(req, prefix, interest, parameters); };
191 authorization(prefix, interest, parameters.get(), accept, reject);
195 Dispatcher::processAuthorizedControlCommandInterest(
const std::string& requester,
198 const shared_ptr<ControlParameters>& parameters,
202 if (validateParams(*parameters)) {
203 handler(prefix, interest, *parameters,
204 [=] (
const auto& resp) { sendControlResponse(resp, interest); });
207 sendControlResponse(
ControlResponse(400,
"failed in validating parameters"), interest);
220 sendData(interest.getName(), resp.wireEncode(), metaInfo, SendDestination::FACE);
228 if (!m_topLevelPrefixes.empty()) {
229 NDN_THROW(std::domain_error(
"one or more top-level prefix has been added"));
232 if (isOverlappedWithOthers(relPrefix)) {
233 NDN_THROW(std::out_of_range(
"status dataset name overlaps"));
236 AuthorizationAcceptedCallback accept =
237 [
this, handler = std::move(handler)] (
auto&&,
const auto& prefix,
const auto& interest,
auto&&) {
238 processAuthorizedStatusDatasetInterest(prefix, interest, handler);
240 AuthorizationRejectedCallback reject =
241 [
this] (
auto&&... args) {
242 afterAuthorizationRejected(std::forward<decltype(args)>(args)...);
245 InterestHandler missContinuation =
246 [
this, auth = std::move(auth), accept = std::move(accept), reject = std::move(reject)] (
auto&&... args) {
247 processStatusDatasetInterest(std::forward<decltype(args)>(args)..., auth, accept, reject);
250 m_handlers[relPrefix] = [
this, miss = std::move(missContinuation)] (
auto&&... args) {
251 queryStorage(std::forward<decltype(args)>(args)..., miss);
256 Dispatcher::processStatusDatasetInterest(
const Name& prefix,
259 const AuthorizationAcceptedCallback& accepted,
260 const AuthorizationRejectedCallback& rejected)
263 bool endsWithVersionOrSegment = interestName.
size() >= 1 &&
264 (interestName[-1].isVersion() || interestName[-1].isSegment());
265 if (endsWithVersionOrSegment) {
269 AcceptContinuation accept = [=] (
const auto& req) { accepted(req, prefix, interest,
nullptr); };
271 authorization(prefix, interest,
nullptr, accept, reject);
275 Dispatcher::processAuthorizedStatusDatasetInterest(
const Name& prefix,
279 StatusDatasetContext context(interest,
280 [
this] (
auto&&... args) {
281 sendStatusDatasetSegment(std::forward<decltype(args)>(args)...);
283 [
this, interest] (
auto&&... args) {
284 sendControlResponse(std::forward<decltype(args)>(args)..., interest,
true);
286 handler(prefix, interest, context);
290 Dispatcher::sendStatusDatasetSegment(
const Name& dataName,
const Block& content,
bool isFinalBlock)
294 auto destination = SendDestination::IMS;
295 if (dataName[-1].toSegment() == 0) {
296 destination = SendDestination::FACE_AND_IMS;
301 metaInfo.setFinalBlock(dataName[-1]);
304 sendData(dataName, content, metaInfo, destination);
310 if (!m_topLevelPrefixes.empty()) {
311 NDN_THROW(std::domain_error(
"one or more top-level prefix has been added"));
314 if (isOverlappedWithOthers(relPrefix)) {
315 NDN_THROW(std::out_of_range(
"notification stream name overlaps"));
320 m_handlers[relPrefix] = [
this] (
auto&&... args) {
321 queryStorage(std::forward<decltype(args)>(args)...,
nullptr);
323 m_streams[relPrefix] = 0;
325 return [=] (
const Block& b) { postNotification(b, relPrefix); };
329 Dispatcher::postNotification(
const Block& notification,
const PartialName& relPrefix)
331 if (m_topLevelPrefixes.size() != 1) {
332 NDN_LOG_WARN(
"postNotification: no top-level prefix or too many top-level prefixes");
336 Name streamName(m_topLevelPrefixes.begin()->first);
337 streamName.append(relPrefix);
338 streamName.appendSequenceNumber(m_streams[streamName]++);
342 sendData(streamName, notification, {}, SendDestination::FACE_AND_IMS);
Represents a TLV element of the NDN packet format.
Provide a communication channel with local or remote NDN forwarder.
RegisteredPrefixHandle registerPrefix(const Name &prefix, const RegisterPrefixSuccessCallback &onSuccess, const RegisterPrefixFailureCallback &onFailure, const security::SigningInfo &signingInfo=security::SigningInfo(), uint64_t flags=nfd::ROUTE_FLAG_CHILD_INHERIT)
Register prefix with the connected NDN forwarder.
RegisteredPrefixHandle setInterestFilter(const InterestFilter &filter, const InterestCallback &onInterest, const RegisterPrefixFailureCallback &onFailure, const security::SigningInfo &signingInfo=security::SigningInfo(), uint64_t flags=nfd::ROUTE_FLAG_CHILD_INHERIT)
Set InterestFilter to dispatch incoming matching interest to onInterest callback and register the fil...
void put(const Data &data)
Publish a Data packet.
void insert(const Data &data, const time::milliseconds &mustBeFreshProcessingWindow=INFINITE_WINDOW)
Inserts a Data packet.
shared_ptr< const Data > find(const Interest &interest)
Finds the best match Data for an Interest.
Represents an Interest packet.
const Name & getName() const noexcept
Get the Interest name.
Represents an absolute name.
size_t size() const noexcept
Returns the number of components.
Base class for a struct that contains ControlCommand parameters.
Implements a request dispatcher on server side of NFD Management protocol.
PostNotification addNotificationStream(const PartialName &relPrefix)
Register a NotificationStream.
Dispatcher(Face &face, KeyChain &keyChain, const security::SigningInfo &signingInfo=security::SigningInfo(), size_t imsCapacity=256)
Constructor.
void addStatusDataset(const PartialName &relPrefix, Authorization authorize, StatusDatasetHandler handle)
Register a StatusDataset or a prefix under which StatusDatasets can be requested.
void addTopPrefix(const Name &prefix, bool wantRegister=true, const security::SigningInfo &signingInfo=security::SigningInfo())
Add a top-level prefix.
void removeTopPrefix(const Name &prefix)
Remove a top-level prefix.
The main interface for signing key management.
void sign(Data &data, const SigningInfo ¶ms=SigningInfo())
Sign a Data packet according to the supplied signing information.
Signing parameters passed to KeyChain.
#define NDN_LOG_WARN(expression)
Log at WARN level.
#define NDN_LOG_ERROR(expression)
Log at ERROR level.
#define NDN_LOG_INIT(name)
Define a non-member log module.
std::function< void(const std::string &requester)> AcceptContinuation
A function to be called if authorization is successful.
std::function< void(const Name &prefix, const Interest &interest, const ControlParameters *params, const AcceptContinuation &accept, const RejectContinuation &reject)> Authorization
A function that performs authorization.
std::function< void(const Block ¬ification)> PostNotification
A function to post a notification.
std::function< void(RejectReply)> RejectContinuation
A function to be called if authorization is rejected.
RejectReply
Indicates how to reply in case authorization is rejected.
@ STATUS403
Reply with a ControlResponse where StatusCode is 403.
std::function< bool(const ControlParameters ¶ms)> ValidateParameters
A function to validate input ControlParameters.
std::function< void(const Name &prefix, const Interest &interest, const ControlParameters ¶ms, const CommandContinuation &done)> ControlCommandHandler
A function to handle an authorized ControlCommand.
Authorization makeAcceptAllAuthorization()
Return an Authorization that accepts all Interests, with empty string as requester.
std::function< void(const Name &prefix, const Interest &interest, StatusDatasetContext &context)> StatusDatasetHandler
A function to handle a StatusDataset request.
mgmt::ControlResponse ControlResponse
@ ContentType_Nack
application-level nack