36 return [] (
const Name& prefix,
49 , m_keyChain(keyChain)
50 , m_signingInfo(signingInfo)
51 , m_storage(m_face.getIoService(), imsCapacity)
61 bool hasOverlap = std::any_of(m_topLevelPrefixes.begin(), m_topLevelPrefixes.end(),
62 [&prefix] (
const auto& x) {
63 return x.first.isPrefixOf(prefix) || prefix.isPrefixOf(x.first);
66 NDN_THROW(std::out_of_range(
"top-level prefix overlaps"));
69 TopPrefixEntry& topPrefixEntry = m_topLevelPrefixes[prefix];
74 [] (
const Name&,
const std::string& reason) {
75 NDN_THROW(std::runtime_error(
"prefix registration failed: " + reason));
80 for (
const auto& entry : m_handlers) {
81 Name fullPrefix =
Name(prefix).append(entry.first);
82 auto filterHdl = m_face.
setInterestFilter(fullPrefix, bind(entry.second, prefix, _2));
83 topPrefixEntry.interestFilters.push_back(filterHdl);
90 m_topLevelPrefixes.erase(prefix);
94 Dispatcher::isOverlappedWithOthers(
const PartialName& relPrefix)
const
96 bool hasOverlapWithHandlers =
97 std::any_of(m_handlers.begin(), m_handlers.end(),
98 [&] (
const auto& entry) {
99 return entry.first.isPrefixOf(relPrefix) || relPrefix.isPrefixOf(entry.first);
101 bool hasOverlapWithStreams =
102 std::any_of(m_streams.begin(), m_streams.end(),
103 [&] (
const auto& entry) {
104 return entry.first.isPrefixOf(relPrefix) || relPrefix.isPrefixOf(entry.first);
107 return hasOverlapWithHandlers || hasOverlapWithStreams;
114 sendControlResponse(
ControlResponse(403,
"authorization rejected"), interest);
119 Dispatcher::queryStorage(
const Name& prefix,
const Interest& interest,
120 const InterestHandler& missContinuation)
122 auto data = m_storage.find(interest);
123 if (data ==
nullptr) {
125 if (missContinuation)
126 missContinuation(prefix, interest);
135 Dispatcher::sendData(
const Name& dataName,
const Block& content,
const MetaInfo& metaInfo,
136 SendDestination option, time::milliseconds imsFresh)
138 auto data = make_shared<Data>(dataName);
141 m_keyChain.
sign(*data, m_signingInfo);
143 if (option == SendDestination::IMS || option == SendDestination::FACE_AND_IMS) {
146 data->setTag(make_shared<lp::CachePolicyTag>(policy));
147 m_storage.insert(*data, imsFresh);
150 if (option == SendDestination::FACE || option == SendDestination::FACE_AND_IMS) {
156 Dispatcher::sendOnFace(
const Data& data)
161 catch (
const Face::Error& e) {
167 Dispatcher::processControlCommandInterest(
const Name& prefix,
168 const Name& relPrefix,
170 const ControlParametersParser& parser,
172 const AuthorizationAcceptedCallback& accepted,
173 const AuthorizationRejectedCallback& rejected)
176 size_t parametersLoc = prefix.size() + relPrefix.size();
179 shared_ptr<ControlParameters> parameters;
181 parameters = parser(pc);
183 catch (
const tlv::Error&) {
187 AcceptContinuation accept = [=] (
const auto& req) { accepted(req, prefix, interest, parameters); };
189 authorization(prefix, interest, parameters.get(), accept, reject);
193 Dispatcher::processAuthorizedControlCommandInterest(
const std::string& requester,
196 const shared_ptr<ControlParameters>& parameters,
200 if (validateParams(*parameters)) {
201 handler(prefix, interest, *parameters,
202 [=] (
const auto& resp) { this->sendControlResponse(resp, interest); });
205 sendControlResponse(
ControlResponse(400,
"failed in validating parameters"), interest);
218 sendData(interest.getName(), resp.wireEncode(), metaInfo,
227 if (!m_topLevelPrefixes.empty()) {
228 NDN_THROW(std::domain_error(
"one or more top-level prefix has been added"));
231 if (isOverlappedWithOthers(relPrefix)) {
232 NDN_THROW(std::out_of_range(
"status dataset name overlaps"));
235 AuthorizationAcceptedCallback accepted =
236 bind(&Dispatcher::processAuthorizedStatusDatasetInterest,
this, _1, _2, _3,
std::move(handle));
237 AuthorizationRejectedCallback rejected =
238 bind(&Dispatcher::afterAuthorizationRejected,
this, _1, _2);
241 InterestHandler missContinuation = bind(&Dispatcher::processStatusDatasetInterest,
this, _1, _2,
244 m_handlers[relPrefix] = [
this, miss =
std::move(missContinuation)] (
auto&&... args) {
245 this->queryStorage(std::forward<decltype(args)>(args)..., miss);
250 Dispatcher::processStatusDatasetInterest(
const Name& prefix,
253 const AuthorizationAcceptedCallback& accepted,
254 const AuthorizationRejectedCallback& rejected)
257 bool endsWithVersionOrSegment = interestName.
size() >= 1 &&
258 (interestName[-1].isVersion() || interestName[-1].isSegment());
259 if (endsWithVersionOrSegment) {
263 AcceptContinuation accept = [=] (
const auto& req) { accepted(req, prefix, interest,
nullptr); };
265 authorization(prefix, interest,
nullptr, accept, reject);
269 Dispatcher::processAuthorizedStatusDatasetInterest(
const std::string& requester,
274 StatusDatasetContext context(interest,
275 bind(&Dispatcher::sendStatusDatasetSegment,
this, _1, _2, _3, _4),
276 bind(&Dispatcher::sendControlResponse,
this, _1, interest,
true));
277 handler(prefix, interest, context);
281 Dispatcher::sendStatusDatasetSegment(
const Name& dataName,
const Block& content,
282 time::milliseconds imsFresh,
bool isFinalBlock)
286 auto destination = SendDestination::IMS;
287 if (dataName[-1].toSegment() == 0) {
288 destination = SendDestination::FACE_AND_IMS;
293 metaInfo.setFinalBlock(dataName[-1]);
296 sendData(dataName, content, metaInfo, destination, imsFresh);
302 if (!m_topLevelPrefixes.empty()) {
303 NDN_THROW(std::domain_error(
"one or more top-level prefix has been added"));
306 if (isOverlappedWithOthers(relPrefix)) {
307 NDN_THROW(std::out_of_range(
"notification stream name overlaps"));
312 m_handlers[relPrefix] = [
this] (
auto&&... args) {
313 this->queryStorage(std::forward<decltype(args)>(args)...,
nullptr);
315 m_streams[relPrefix] = 0;
317 return [=] (
const Block& b) { postNotification(b, relPrefix); };
321 Dispatcher::postNotification(
const Block& notification,
const PartialName& relPrefix)
323 if (m_topLevelPrefixes.size() != 1) {
324 NDN_LOG_WARN(
"postNotification: no top-level prefix or too many top-level prefixes");
328 Name streamName(m_topLevelPrefixes.begin()->first);
329 streamName.append(relPrefix);
330 streamName.appendSequenceNumber(m_streams[streamName]++);