23 #include "../lp/tags.hpp" 24 #include "../util/logger.hpp" 36 return [] (
const Name& prefix,
49 , m_keyChain(keyChain)
50 , m_signingInfo(signingInfo)
51 , m_storage(m_face.getIoService(), imsCapacity)
57 std::vector<Name> topPrefixNames;
58 std::transform(m_topLevelPrefixes.begin(), m_topLevelPrefixes.end(), std::back_inserter(topPrefixNames),
59 [] (
const auto& entry) {
return entry.second.topPrefix; });
61 for (
const auto& name : topPrefixNames) {
70 bool hasOverlap = std::any_of(m_topLevelPrefixes.begin(), m_topLevelPrefixes.end(),
71 [&prefix] (
const auto& x) {
72 return x.first.isPrefixOf(prefix) || prefix.
isPrefixOf(x.first);
75 BOOST_THROW_EXCEPTION(std::out_of_range(
"top-level prefix overlaps"));
78 TopPrefixEntry& topPrefixEntry = m_topLevelPrefixes[prefix];
79 topPrefixEntry.topPrefix = prefix;
84 [] (
const Name&,
const std::string& reason) {
85 BOOST_THROW_EXCEPTION(std::runtime_error(
"prefix registration failed: " + reason));
90 for (
const auto& entry : m_handlers) {
91 Name fullPrefix =
Name(prefix).append(entry.first);
92 const auto* filterId = m_face.
setInterestFilter(fullPrefix, bind(entry.second, prefix, _2));
93 topPrefixEntry.interestFilters.push_back(filterId);
100 auto it = m_topLevelPrefixes.find(prefix);
101 if (it == m_topLevelPrefixes.end()) {
105 const TopPrefixEntry& topPrefixEntry = it->second;
106 if (topPrefixEntry.registeredPrefixId) {
107 m_face.
unregisterPrefix(*topPrefixEntry.registeredPrefixId,
nullptr,
nullptr);
109 for (
const auto& filter : topPrefixEntry.interestFilters) {
113 m_topLevelPrefixes.erase(it);
117 Dispatcher::isOverlappedWithOthers(
const PartialName& relPrefix)
const 119 bool hasOverlapWithHandlers =
120 std::any_of(m_handlers.begin(), m_handlers.end(),
121 [&] (
const auto& entry) {
122 return entry.first.isPrefixOf(relPrefix) || relPrefix.
isPrefixOf(entry.first);
124 bool hasOverlapWithStreams =
125 std::any_of(m_streams.begin(), m_streams.end(),
126 [&] (
const auto& entry) {
127 return entry.first.isPrefixOf(relPrefix) || relPrefix.
isPrefixOf(entry.first);
130 return hasOverlapWithHandlers || hasOverlapWithStreams;
137 sendControlResponse(
ControlResponse(403,
"authorization rejected"), interest);
142 Dispatcher::queryStorage(
const Name& prefix,
const Interest& interest,
143 const InterestHandler& missContinuation)
145 auto data = m_storage.
find(interest);
146 if (data ==
nullptr) {
148 if (missContinuation)
149 missContinuation(prefix, interest);
158 Dispatcher::sendData(
const Name& dataName,
const Block& content,
const MetaInfo& metaInfo,
159 SendDestination option, time::milliseconds imsFresh)
161 auto data = make_shared<Data>(dataName);
162 data->setContent(content).setMetaInfo(metaInfo).setFreshnessPeriod(DEFAULT_FRESHNESS_PERIOD);
164 m_keyChain.sign(*data, m_signingInfo);
166 if (option == SendDestination::IMS || option == SendDestination::FACE_AND_IMS) {
169 data->setTag(make_shared<lp::CachePolicyTag>(policy));
170 m_storage.
insert(*data, imsFresh);
173 if (option == SendDestination::FACE || option == SendDestination::FACE_AND_IMS) {
179 Dispatcher::sendOnFace(
const Data& data)
190 Dispatcher::processControlCommandInterest(
const Name& prefix,
191 const Name& relPrefix,
193 const ControlParametersParser& parser,
195 const AuthorizationAcceptedCallback& accepted,
196 const AuthorizationRejectedCallback& rejected)
199 size_t parametersLoc = prefix.
size() + relPrefix.
size();
202 shared_ptr<ControlParameters> parameters;
204 parameters = parser(pc);
210 AcceptContinuation accept = [=] (
const auto& req) { accepted(req, prefix, interest, parameters); };
212 authorization(prefix, interest, parameters.get(), accept, reject);
216 Dispatcher::processAuthorizedControlCommandInterest(
const std::string& requester,
219 const shared_ptr<ControlParameters>& parameters,
223 if (validateParams(*parameters)) {
224 handler(prefix, interest, *parameters,
225 [=] (
const auto& resp) { this->sendControlResponse(resp, interest); });
228 sendControlResponse(
ControlResponse(400,
"failed in validating parameters"), interest);
250 if (!m_topLevelPrefixes.empty()) {
251 BOOST_THROW_EXCEPTION(std::domain_error(
"one or more top-level prefix has been added"));
254 if (isOverlappedWithOthers(relPrefix)) {
255 BOOST_THROW_EXCEPTION(std::out_of_range(
"status dataset name overlaps"));
258 AuthorizationAcceptedCallback accepted =
259 bind(&Dispatcher::processAuthorizedStatusDatasetInterest,
this, _1, _2, _3, std::move(handle));
260 AuthorizationRejectedCallback rejected =
261 bind(&Dispatcher::afterAuthorizationRejected,
this, _1, _2);
264 InterestHandler missContinuation = bind(&Dispatcher::processStatusDatasetInterest,
this, _1, _2,
265 std::move(authorize), std::move(accepted), std::move(rejected));
267 m_handlers[relPrefix] = [
this, miss = std::move(missContinuation)] (
auto&&... args) {
268 this->queryStorage(std::forward<decltype(args)>(args)..., miss);
273 Dispatcher::processStatusDatasetInterest(
const Name& prefix,
276 const AuthorizationAcceptedCallback& accepted,
277 const AuthorizationRejectedCallback& rejected)
280 bool endsWithVersionOrSegment = interestName.
size() >= 1 &&
281 (interestName[-1].isVersion() || interestName[-1].isSegment());
282 if (endsWithVersionOrSegment) {
286 AcceptContinuation accept = [=] (
const auto& req) { accepted(req, prefix, interest,
nullptr); };
288 authorization(prefix, interest,
nullptr, accept, reject);
292 Dispatcher::processAuthorizedStatusDatasetInterest(
const std::string& requester,
298 bind(&Dispatcher::sendStatusDatasetSegment,
this, _1, _2, _3, _4),
299 bind(&Dispatcher::sendControlResponse,
this, _1, interest,
true));
300 handler(prefix, interest, context);
304 Dispatcher::sendStatusDatasetSegment(
const Name& dataName,
const Block& content,
305 time::milliseconds imsFresh,
bool isFinalBlock)
309 auto destination = SendDestination::IMS;
310 if (dataName[-1].toSegment() == 0) {
311 destination = SendDestination::FACE_AND_IMS;
319 sendData(dataName, content, metaInfo, destination, imsFresh);
325 if (!m_topLevelPrefixes.empty()) {
326 BOOST_THROW_EXCEPTION(std::domain_error(
"one or more top-level prefix has been added"));
329 if (isOverlappedWithOthers(relPrefix)) {
330 BOOST_THROW_EXCEPTION(std::out_of_range(
"notification stream name overlaps"));
335 m_handlers[relPrefix] = [
this] (
auto&&... args) {
336 this->queryStorage(std::forward<decltype(args)>(args)...,
nullptr);
338 m_streams[relPrefix] = 0;
340 return [=] (
const Block& b) { postNotification(b, relPrefix); };
344 Dispatcher::postNotification(
const Block& notification,
const PartialName& relPrefix)
346 if (m_topLevelPrefixes.empty() || m_topLevelPrefixes.size() > 1) {
347 NDN_LOG_WARN(
"postNotification: no top-level prefix or too many top-level prefixes");
351 Name streamName(m_topLevelPrefixes.begin()->second.topPrefix);
352 streamName.
append(relPrefix);
represents a CachePolicy header field
const Name & getName() const
Copyright (c) 2013-2017 Regents of the University of California.
std::function< void(const Block ¬ification)> PostNotification
a function to post a notification
represents a dispatcher on server side of NFD Management protocol
RejectReply
indicate how to reply in case authorization is rejected
const RegisteredPrefixId * setInterestFilter(const InterestFilter &interestFilter, 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...
reply with a ControlResponse where StatusCode is 403
CachePolicy & setPolicy(CachePolicyType policy)
set policy type code
Represents a TLV element of NDN packet format.
Represents an Interest packet.
std::function< void(const std::string &requester)> AcceptContinuation
a function to be called if authorization is successful
Dispatcher(Face &face, KeyChain &keyChain, const security::SigningInfo &signingInfo=security::SigningInfo(), size_t imsCapacity=256)
constructor
const Block & wireEncode() const
#define NDN_LOG_INIT(name)
Define a non-member log module.
Authorization makeAcceptAllAuthorization()
return an Authorization that accepts all Interests, with empty string as requester ...
Name & append(const Component &component)
Append a component.
Signing parameters passed to KeyChain.
void unregisterPrefix(const RegisteredPrefixId *registeredPrefixId, const UnregisterPrefixSuccessCallback &onSuccess, const UnregisterPrefixFailureCallback &onFailure)
Unregister prefix from RIB.
shared_ptr< const Data > find(const Interest &interest)
Finds the best match Data for an Interest.
mgmt::ControlResponse ControlResponse
std::function< void(RejectReply reply)> RejectContinuation
a function to be called if authorization is rejected
Provide a communication channel with local or remote NDN forwarder.
void addTopPrefix(const Name &prefix, bool wantRegister=true, const security::SigningInfo &signingInfo=security::SigningInfo())
add a top-level prefix
size_t size() const
Get number of components.
Name & appendSequenceNumber(uint64_t seqNo)
Append a sequence number component.
Represents an absolute name.
bool isPrefixOf(const Name &other) const
Check if this name is a prefix of another name.
const time::milliseconds DEFAULT_FRESHNESS_PERIOD
void unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
Remove the registered prefix entry with the registeredPrefixId.
base class for a struct that contains ControlCommand parameters
#define NDN_LOG_WARN(expression)
Log at WARN level.
Represents a name component.
std::function< void(const Name &prefix, const Interest &interest, const ControlParameters ¶ms, const CommandContinuation &done)> ControlCommandHandler
a function to handle an authorized ControlCommand
std::function< bool(const ControlParameters ¶ms)> ValidateParameters
a function to validate input ControlParameters
void insert(const Data &data, const time::milliseconds &mustBeFreshProcessingWindow=INFINITE_WINDOW)
Inserts a Data packet.
void put(Data data)
Publish data packet.
void removeTopPrefix(const Name &prefix)
remove a top-level prefix
void addStatusDataset(const PartialName &relPrefix, Authorization authorize, StatusDatasetHandler handle)
register a StatusDataset or a prefix under which StatusDatasets can be requested
provides a context for generating response to a StatusDataset request
Represents a Data packet.
std::function< void(const Name &prefix, const Interest &interest, const ControlParameters *params, const AcceptContinuation &accept, const RejectContinuation &reject)> Authorization
a function that performs authorization
#define NDN_LOG_ERROR(expression)
Log at ERROR level.
const Component & get(ssize_t i) const
Get the component at the given index.
const RegisteredPrefixId * 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.
represents an error in TLV encoding or decoding
PostNotification addNotificationStream(const PartialName &relPrefix)
register a NotificationStream
std::function< void(const Name &prefix, const Interest &interest, StatusDatasetContext &context)> StatusDatasetHandler
a function to handle a StatusDataset request