blob: 5e87153b42fc7b33e828cab090d950a7e77d2a31 [file] [log] [blame]
Yingdi Yuf7ede412014-08-30 20:37:52 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
Ashlesh Gawande04e8d492018-02-04 13:08:15 -06003 * Copyright (c) 2012-2018 University of California, Los Angeles
Yingdi Yuf7ede412014-08-30 20:37:52 -07004 *
5 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
7 *
8 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation, either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
20 * @author Chaoyi Bian <bcy@pku.edu.cn>
21 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
22 * @author Yingdi Yu <yingdi@cs.ucla.edu>
Sonu Mishra0dadc572016-12-12 23:59:41 -080023 * @author Sonu Mishra <https://www.linkedin.com/in/mishrasonu>
Yingdi Yuf7ede412014-08-30 20:37:52 -070024 */
25
26#include "logic.hpp"
27#include "logger.hpp"
28
Alexander Afanasyev89036292018-02-13 17:19:50 -050029#include <ndn-cxx/util/backports.hpp>
Ashlesh Gawande687cf922017-05-30 15:04:16 -050030#include <ndn-cxx/util/string-helper.hpp>
31
Alexander Afanasyev36eb3ed2017-01-11 12:35:58 -080032INIT_LOGGER(Logic);
Yingdi Yuf7ede412014-08-30 20:37:52 -070033
Yingdi Yuf7ede412014-08-30 20:37:52 -070034#define _LOG_DEBUG_ID(v) _LOG_DEBUG("Instance" << m_instanceId << ": " << v)
Yingdi Yuf7ede412014-08-30 20:37:52 -070035
36namespace chronosync {
37
Yingdi Yuf7ede412014-08-30 20:37:52 -070038using ndn::EventId;
39
40const uint8_t EMPTY_DIGEST_VALUE[] = {
41 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
42 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
43 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
44 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
45};
46
Ashlesh Gawande08784d42017-09-06 23:40:21 -050047int Logic::s_instanceCounter = 0;
Yingdi Yuf7ede412014-08-30 20:37:52 -070048
Yingdi Yucd339022014-11-05 17:51:19 -080049const ndn::Name Logic::DEFAULT_NAME;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -080050const ndn::Name Logic::EMPTY_NAME;
Ashlesh Gawande08784d42017-09-06 23:40:21 -050051const std::shared_ptr<Validator> Logic::DEFAULT_VALIDATOR;
Yingdi Yuf7ede412014-08-30 20:37:52 -070052const time::steady_clock::Duration Logic::DEFAULT_RESET_TIMER = time::seconds(0);
53const time::steady_clock::Duration Logic::DEFAULT_CANCEL_RESET_TIMER = time::milliseconds(500);
54const time::milliseconds Logic::DEFAULT_RESET_INTEREST_LIFETIME(1000);
55const time::milliseconds Logic::DEFAULT_SYNC_INTEREST_LIFETIME(1000);
56const time::milliseconds Logic::DEFAULT_SYNC_REPLY_FRESHNESS(1000);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -080057const time::milliseconds Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME(1000);
Yingdi Yuf7ede412014-08-30 20:37:52 -070058
Ashlesh Gawande08784d42017-09-06 23:40:21 -050059const ConstBufferPtr Logic::EMPTY_DIGEST(new ndn::Buffer(EMPTY_DIGEST_VALUE, 32));
Yingdi Yuf7ede412014-08-30 20:37:52 -070060const ndn::name::Component Logic::RESET_COMPONENT("reset");
Sonu Mishra4d3a2e02017-01-18 20:27:51 -080061const ndn::name::Component Logic::RECOVERY_COMPONENT("recovery");
Yingdi Yuf7ede412014-08-30 20:37:52 -070062
Alexander Afanasyev89036292018-02-13 17:19:50 -050063const size_t NDNLP_EXPECTED_OVERHEAD = 20;
64
65/**
66 * Get maximum packet limit
67 *
68 * By default, it returns `ndn::MAX_NDN_PACKET_SIZE`.
69 * The returned value can be customized using the environment variable `CHRONOSYNC_MAX_PACKET_SIZE`,
70 * but the returned value will be at least 500 and no more than `ndn::MAX_NDN_PACKET_SIZE`.
71 */
72#ifndef CHRONOSYNC_HAVE_TESTS
73static
74#endif // CHRONOSYNC_HAVE_TESTS
75size_t
76getMaxPacketLimit()
77{
78 static size_t limit = 0;
79#ifndef CHRONOSYNC_HAVE_TESTS
80 if (limit != 0) {
81 return limit;
82 }
83#endif // CHRONOSYNC_HAVE_TESTS
84
85 if (getenv("CHRONOSYNC_MAX_PACKET_SIZE") != nullptr) {
86 try {
87 limit = ndn::clamp<size_t>(boost::lexical_cast<size_t>(getenv("CHRONOSYNC_MAX_PACKET_SIZE")),
88 500, ndn::MAX_NDN_PACKET_SIZE);
89 }
90 catch (const boost::bad_lexical_cast&) {
91 limit = ndn::MAX_NDN_PACKET_SIZE;
92 }
93 }
94 else {
95 limit = ndn::MAX_NDN_PACKET_SIZE;
96 }
97
98 return limit;
99}
100
Yingdi Yuf7ede412014-08-30 20:37:52 -0700101Logic::Logic(ndn::Face& face,
102 const Name& syncPrefix,
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800103 const Name& defaultUserPrefix,
Yingdi Yuf7ede412014-08-30 20:37:52 -0700104 const UpdateCallback& onUpdate,
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800105 const Name& defaultSigningId,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500106 std::shared_ptr<Validator> validator,
Yingdi Yuf7ede412014-08-30 20:37:52 -0700107 const time::steady_clock::Duration& resetTimer,
108 const time::steady_clock::Duration& cancelResetTimer,
109 const time::milliseconds& resetInterestLifetime,
110 const time::milliseconds& syncInterestLifetime,
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800111 const time::milliseconds& syncReplyFreshness,
112 const time::milliseconds& recoveryInterestLifetime)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700113 : m_face(face)
114 , m_syncPrefix(syncPrefix)
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800115 , m_defaultUserPrefix(defaultUserPrefix)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700116 , m_interestTable(m_face.getIoService())
117 , m_outstandingInterestId(0)
118 , m_isInReset(false)
119 , m_needPeriodReset(resetTimer > time::steady_clock::Duration::zero())
120 , m_onUpdate(onUpdate)
121 , m_scheduler(m_face.getIoService())
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600122 , m_rng(std::random_device{}())
123 , m_rangeUniformRandom(100, 500)
124 , m_reexpressionJitter(100, 500)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700125 , m_resetTimer(resetTimer)
126 , m_cancelResetTimer(cancelResetTimer)
127 , m_resetInterestLifetime(resetInterestLifetime)
128 , m_syncInterestLifetime(syncInterestLifetime)
129 , m_syncReplyFreshness(syncReplyFreshness)
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800130 , m_recoveryInterestLifetime(recoveryInterestLifetime)
Yingdi Yucd339022014-11-05 17:51:19 -0800131 , m_validator(validator)
Alexander Afanasyev90587b82018-02-11 20:36:53 -0500132 , m_instanceId(s_instanceCounter++)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700133{
Yingdi Yuf7ede412014-08-30 20:37:52 -0700134 _LOG_DEBUG_ID(">> Logic::Logic");
135
Ashlesh Gawande687cf922017-05-30 15:04:16 -0500136 addUserNode(m_defaultUserPrefix, defaultSigningId);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800137
Yingdi Yuf7ede412014-08-30 20:37:52 -0700138 m_syncReset = m_syncPrefix;
139 m_syncReset.append("reset");
140
141 _LOG_DEBUG_ID("Listen to: " << m_syncPrefix);
142 m_syncRegisteredPrefixId =
Junxiao Shi4e010bc2017-11-16 14:11:00 +0000143 m_face.setInterestFilter(ndn::InterestFilter(m_syncPrefix).allowLoopback(false),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700144 bind(&Logic::onSyncInterest, this, _1, _2),
145 bind(&Logic::onSyncRegisterFailed, this, _1, _2));
146
Qiuhan Dinge246b622014-12-03 21:57:48 -0800147 sendSyncInterest();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700148 _LOG_DEBUG_ID("<< Logic::Logic");
149}
150
151Logic::~Logic()
152{
Yingdi Yuf7ede412014-08-30 20:37:52 -0700153 m_scheduler.cancelAllEvents();
Yingdi Yu9d5679a2015-02-01 00:17:58 -0800154 m_interestTable.clear();
155 m_face.shutdown();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700156}
157
158void
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800159Logic::reset(bool isOnInterest)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700160{
161 m_isInReset = true;
162
163 m_state.reset();
164 m_log.clear();
165
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800166 if (!isOnInterest)
167 sendResetInterest();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700168
169 // reset outstanding interest name, so that data for previous interest will be dropped.
170 if (m_outstandingInterestId != 0) {
171 m_face.removePendingInterest(m_outstandingInterestId);
172 m_outstandingInterestId = 0;
173 }
174
175 sendSyncInterest();
176
177 if (static_cast<bool>(m_delayedInterestProcessingId))
178 m_scheduler.cancelEvent(m_delayedInterestProcessingId);
179
180 m_delayedInterestProcessingId =
181 m_scheduler.scheduleEvent(m_cancelResetTimer,
182 bind(&Logic::cancelReset, this));
183}
184
185void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800186Logic::setDefaultUserPrefix(const Name& defaultUserPrefix)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700187{
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800188 if (defaultUserPrefix != EMPTY_NAME) {
189 if (m_nodeList.find(defaultUserPrefix) != m_nodeList.end()) {
190 m_defaultUserPrefix = defaultUserPrefix;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800191 }
192 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700193}
194
195void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800196Logic::addUserNode(const Name& userPrefix, const Name& signingId)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700197{
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800198 if (userPrefix == EMPTY_NAME)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700199 return;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800200 if (m_defaultUserPrefix == EMPTY_NAME) {
201 m_defaultUserPrefix = userPrefix;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800202 }
203 if (m_nodeList.find(userPrefix) == m_nodeList.end()) {
204 m_nodeList[userPrefix].userPrefix = userPrefix;
205 m_nodeList[userPrefix].signingId = signingId;
206 Name sessionName = userPrefix;
207 sessionName.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
208 m_nodeList[userPrefix].sessionName = sessionName;
209 m_nodeList[userPrefix].seqNo = 0;
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800210 reset(false);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800211 }
212}
Yingdi Yuf7ede412014-08-30 20:37:52 -0700213
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800214void
215Logic::removeUserNode(const Name& userPrefix)
216{
217 auto userNode = m_nodeList.find(userPrefix);
218 if (userNode != m_nodeList.end()) {
219 m_nodeList.erase(userNode);
220 if (m_defaultUserPrefix == userPrefix) {
221 if (!m_nodeList.empty()) {
222 m_defaultUserPrefix = m_nodeList.begin()->second.userPrefix;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800223 }
224 else {
225 m_defaultUserPrefix = EMPTY_NAME;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800226 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700227 }
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800228 reset(false);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800229 }
230}
Yingdi Yuf7ede412014-08-30 20:37:52 -0700231
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800232const Name&
233Logic::getSessionName(Name prefix)
234{
235 if (prefix == EMPTY_NAME)
236 prefix = m_defaultUserPrefix;
237 auto node = m_nodeList.find(prefix);
238 if (node != m_nodeList.end())
239 return node->second.sessionName;
240 else
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800241 BOOST_THROW_EXCEPTION(Error("Refer to non-existent node:" + prefix.toUri()));
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800242}
Yingdi Yuf7ede412014-08-30 20:37:52 -0700243
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800244const SeqNo&
245Logic::getSeqNo(Name prefix)
246{
247 if (prefix == EMPTY_NAME)
248 prefix = m_defaultUserPrefix;
249 auto node = m_nodeList.find(prefix);
250 if (node != m_nodeList.end())
251 return node->second.seqNo;
252 else
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800253 BOOST_THROW_EXCEPTION(Logic::Error("Refer to non-existent node:" + prefix.toUri()));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700254
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800255}
256
257void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800258Logic::updateSeqNo(const SeqNo& seqNo, const Name& updatePrefix)
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800259{
260 Name prefix;
261 if (updatePrefix == EMPTY_NAME) {
262 if (m_defaultUserPrefix == EMPTY_NAME)
263 return;
264 prefix = m_defaultUserPrefix;
265 }
266 else
267 prefix = updatePrefix;
268
269 auto it = m_nodeList.find(prefix);
270 if (it != m_nodeList.end()) {
271 NodeInfo& node = it->second;
272 _LOG_DEBUG_ID(">> Logic::updateSeqNo");
273 _LOG_DEBUG_ID("seqNo: " << seqNo << " m_seqNo: " << node.seqNo);
274 if (seqNo < node.seqNo || seqNo == 0)
275 return;
276
277 node.seqNo = seqNo;
278 _LOG_DEBUG_ID("updateSeqNo: m_seqNo " << node.seqNo);
279
280 if (!m_isInReset) {
281 _LOG_DEBUG_ID("updateSeqNo: not in Reset ");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500282 ConstBufferPtr previousRoot = m_state.getRootDigest();
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800283 {
Davide Pesavento5473abe2017-10-09 01:35:33 -0400284 std::string hash = ndn::toHex(previousRoot->data(), previousRoot->size(), false);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800285 _LOG_DEBUG_ID("Hash: " << hash);
286 }
287
288 bool isInserted = false;
289 bool isUpdated = false;
290 SeqNo oldSeq;
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500291 std::tie(isInserted, isUpdated, oldSeq) = m_state.update(node.sessionName, node.seqNo);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800292
293 _LOG_DEBUG_ID("Insert: " << std::boolalpha << isInserted);
294 _LOG_DEBUG_ID("Updated: " << std::boolalpha << isUpdated);
295 if (isInserted || isUpdated) {
296 DiffStatePtr commit = make_shared<DiffState>();
297 commit->update(node.sessionName, node.seqNo);
298 commit->setRootDigest(m_state.getRootDigest());
299 insertToDiffLog(commit, previousRoot);
300
301 satisfyPendingSyncInterests(prefix, commit);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800302 formAndSendExcludeInterest(prefix, *commit, previousRoot);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800303 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700304 }
305 }
306}
307
308ConstBufferPtr
309Logic::getRootDigest() const
310{
311 return m_state.getRootDigest();
312}
313
314void
315Logic::printState(std::ostream& os) const
316{
317 BOOST_FOREACH(ConstLeafPtr leaf, m_state.getLeaves())
318 {
319 os << *leaf << "\n";
320 }
321}
322
323std::set<Name>
324Logic::getSessionNames() const
325{
326 std::set<Name> sessionNames;
327
328 BOOST_FOREACH(ConstLeafPtr leaf, m_state.getLeaves())
329 {
330 sessionNames.insert(leaf->getSessionName());
331 }
332
333 return sessionNames;
334}
335
336void
337Logic::onSyncInterest(const Name& prefix, const Interest& interest)
338{
339 _LOG_DEBUG_ID(">> Logic::onSyncInterest");
340 Name name = interest.getName();
341
342 _LOG_DEBUG_ID("InterestName: " << name);
343
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800344 if (name.size() >= 1 && RESET_COMPONENT == name.get(-1)) {
345 processResetInterest(interest);
346 }
347 else if (name.size() >= 2 && RECOVERY_COMPONENT == name.get(-2)) {
348 processRecoveryInterest(interest);
349 }
Ashlesh Gawande8ba7d5a2017-07-24 14:43:12 -0500350 // Do not process exclude interests, they should be answered by CS
351 else if (interest.getExclude().empty()) {
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500352 processSyncInterest(interest);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700353 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700354
355 _LOG_DEBUG_ID("<< Logic::onSyncInterest");
356}
357
358void
359Logic::onSyncRegisterFailed(const Name& prefix, const std::string& msg)
360{
361 //Sync prefix registration failed
362 _LOG_DEBUG_ID(">> Logic::onSyncRegisterFailed");
363}
364
365void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800366Logic::onSyncData(const Interest& interest, const Data& data)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700367{
368 _LOG_DEBUG_ID(">> Logic::onSyncData");
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800369 // if (static_cast<bool>(m_validator))
370 // m_validator->validate(data,
371 // bind(&Logic::onSyncDataValidated, this, _1),
372 // bind(&Logic::onSyncDataValidationFailed, this, _1));
373 // else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500374 // onSyncDataValidated(data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800375
376 if (interest.getExclude().empty()) {
377 _LOG_DEBUG_ID("First data");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500378 onSyncDataValidated(data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800379 }
380 else {
381 _LOG_DEBUG_ID("Data obtained using exclude filter");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500382 onSyncDataValidated(data, false);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800383 }
384 sendExcludeInterest(interest, data);
385
Yingdi Yuf7ede412014-08-30 20:37:52 -0700386 _LOG_DEBUG_ID("<< Logic::onSyncData");
387}
388
389void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800390Logic::onResetData(const Interest& interest, const Data& data)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700391{
392 // This should not happened, drop the received data.
393}
394
395void
396Logic::onSyncTimeout(const Interest& interest)
397{
398 // It is OK. Others will handle the time out situation.
399 _LOG_DEBUG_ID(">> Logic::onSyncTimeout");
400 _LOG_DEBUG_ID("Interest: " << interest.getName());
401 _LOG_DEBUG_ID("<< Logic::onSyncTimeout");
402}
403
404void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500405Logic::onSyncDataValidationFailed(const Data& data)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700406{
407 // SyncReply cannot be validated.
408}
409
410void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500411Logic::onSyncDataValidated(const Data& data, bool firstData)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700412{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500413 Name name = data.getName();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700414 ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
415
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500416 processSyncData(name, digest, data.getContent().blockFromValue(), firstData);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700417}
418
419void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500420Logic::processSyncInterest(const Interest& interest, bool isTimedProcessing/*=false*/)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700421{
422 _LOG_DEBUG_ID(">> Logic::processSyncInterest");
423
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500424 Name name = interest.getName();
425 ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
Yingdi Yuf7ede412014-08-30 20:37:52 -0700426
427 ConstBufferPtr rootDigest = m_state.getRootDigest();
428
429 // If the digest of the incoming interest is the same as root digest
430 // Put the interest into InterestTable
431 if (*rootDigest == *digest) {
432 _LOG_DEBUG_ID("Oh, we are in the same state");
433 m_interestTable.insert(interest, digest, false);
434
435 if (!m_isInReset)
436 return;
437
438 if (!isTimedProcessing) {
439 _LOG_DEBUG_ID("Non timed processing in reset");
440 // Still in reset, our own seq has not been put into state yet
441 // Do not hurry, some others may be also resetting and may send their reply
442 if (static_cast<bool>(m_delayedInterestProcessingId))
443 m_scheduler.cancelEvent(m_delayedInterestProcessingId);
444
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600445 time::milliseconds after(m_rangeUniformRandom(m_rng));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700446 _LOG_DEBUG_ID("After: " << after);
447 m_delayedInterestProcessingId =
448 m_scheduler.scheduleEvent(after,
449 bind(&Logic::processSyncInterest, this, interest, true));
450 }
451 else {
452 _LOG_DEBUG_ID("Timed processing in reset");
453 // Now we can get out of reset state by putting our own stuff into m_state.
454 cancelReset();
455 }
456
457 return;
458 }
459
460 // If the digest of incoming interest is an "empty" digest
Sonu Mishrae10acbc2017-01-18 14:14:05 -0800461 if (*digest == *EMPTY_DIGEST) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700462 _LOG_DEBUG_ID("Poor guy, he knows nothing");
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800463 sendSyncData(m_defaultUserPrefix, name, m_state);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700464 return;
465 }
466
467 DiffStateContainer::iterator stateIter = m_log.find(digest);
468 // If the digest of incoming interest can be found from the log
469 if (stateIter != m_log.end()) {
470 _LOG_DEBUG_ID("It is ok, you are so close");
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800471 sendSyncData(m_defaultUserPrefix, name, *(*stateIter)->diff());
Yingdi Yuf7ede412014-08-30 20:37:52 -0700472 return;
473 }
474
475 if (!isTimedProcessing) {
476 _LOG_DEBUG_ID("Let's wait, just wait for a while");
477 // Do not hurry, some incoming SyncReplies may help us to recognize the digest
Yingdi Yu53f5f042015-01-31 16:33:25 -0800478 bool doesExist = m_interestTable.has(digest);
479 m_interestTable.insert(interest, digest, true);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700480 if (doesExist)
481 // Original comment (not sure): somebody else replied, so restart random-game timer
482 // YY: Get the same SyncInterest again, refresh the timer
483 m_scheduler.cancelEvent(m_delayedInterestProcessingId);
484
485 m_delayedInterestProcessingId =
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600486 m_scheduler.scheduleEvent(time::milliseconds(m_rangeUniformRandom(m_rng)),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700487 bind(&Logic::processSyncInterest, this, interest, true));
488 }
489 else {
490 // OK, nobody is helping us, just tell the truth.
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800491 _LOG_DEBUG_ID("OK, nobody is helping us, let us try to recover");
Yingdi Yuf7ede412014-08-30 20:37:52 -0700492 m_interestTable.erase(digest);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800493 sendRecoveryInterest(digest);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700494 }
495
496 _LOG_DEBUG_ID("<< Logic::processSyncInterest");
497}
498
499void
500Logic::processResetInterest(const Interest& interest)
501{
502 _LOG_DEBUG_ID(">> Logic::processResetInterest");
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800503 reset(true);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700504}
505
506void
507Logic::processSyncData(const Name& name,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500508 ConstBufferPtr digest,
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800509 const Block& syncReplyBlock,
510 bool firstData)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700511{
512 _LOG_DEBUG_ID(">> Logic::processSyncData");
Yingdi Yuf7ede412014-08-30 20:37:52 -0700513 DiffStatePtr commit = make_shared<DiffState>();
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500514 ConstBufferPtr previousRoot = m_state.getRootDigest();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700515
516 try {
517 m_interestTable.erase(digest); // Remove satisfied interest from PIT
518
519 State reply;
520 reply.wireDecode(syncReplyBlock);
521
522 std::vector<MissingDataInfo> v;
523 BOOST_FOREACH(ConstLeafPtr leaf, reply.getLeaves().get<ordered>())
524 {
525 BOOST_ASSERT(leaf != 0);
526
527 const Name& info = leaf->getSessionName();
528 SeqNo seq = leaf->getSeq();
529
530 bool isInserted = false;
531 bool isUpdated = false;
532 SeqNo oldSeq;
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500533 std::tie(isInserted, isUpdated, oldSeq) = m_state.update(info, seq);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700534 if (isInserted || isUpdated) {
535 commit->update(info, seq);
536
537 oldSeq++;
538 MissingDataInfo mdi = {info, oldSeq, seq};
539 v.push_back(mdi);
540 }
541 }
542
543 if (!v.empty()) {
544 m_onUpdate(v);
545
546 commit->setRootDigest(m_state.getRootDigest());
547 insertToDiffLog(commit, previousRoot);
548 }
549 else {
550 _LOG_DEBUG_ID("What? nothing new");
551 }
552 }
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800553 catch (const State::Error&) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700554 _LOG_DEBUG_ID("Something really fishy happened during state decoding");
555 // Something really fishy happened during state decoding;
556 commit.reset();
557 return;
558 }
559
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800560 if (static_cast<bool>(commit) && !commit->getLeaves().empty() && firstData) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700561 // state changed and it is safe to express a new interest
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600562 time::steady_clock::Duration after = time::milliseconds(m_reexpressionJitter(m_rng));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700563 _LOG_DEBUG_ID("Reschedule sync interest after: " << after);
564 EventId eventId = m_scheduler.scheduleEvent(after,
565 bind(&Logic::sendSyncInterest, this));
566
567 m_scheduler.cancelEvent(m_reexpressingInterestId);
568 m_reexpressingInterestId = eventId;
569 }
570}
571
572void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800573Logic::satisfyPendingSyncInterests(const Name& updatedPrefix, ConstDiffStatePtr commit)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700574{
575 _LOG_DEBUG_ID(">> Logic::satisfyPendingSyncInterests");
576 try {
577 _LOG_DEBUG_ID("InterestTable size: " << m_interestTable.size());
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500578 auto it = m_interestTable.begin();
579 while (it != m_interestTable.end()) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700580 ConstUnsatisfiedInterestPtr request = *it;
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500581 ++it;
Yingdi Yuf7ede412014-08-30 20:37:52 -0700582 if (request->isUnknown)
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500583 sendSyncData(updatedPrefix, request->interest.getName(), m_state);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700584 else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500585 sendSyncData(updatedPrefix, request->interest.getName(), *commit);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700586 }
587 m_interestTable.clear();
588 }
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800589 catch (const InterestTable::Error&) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700590 // ok. not really an error
591 }
592 _LOG_DEBUG_ID("<< Logic::satisfyPendingSyncInterests");
593}
594
595void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500596Logic::insertToDiffLog(DiffStatePtr commit, ConstBufferPtr previousRoot)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700597{
598 _LOG_DEBUG_ID(">> Logic::insertToDiffLog");
599 // Connect to the history
600 if (!m_log.empty())
601 (*m_log.find(previousRoot))->setNext(commit);
602
603 // Insert the commit
604 m_log.erase(commit->getRootDigest());
605 m_log.insert(commit);
606 _LOG_DEBUG_ID("<< Logic::insertToDiffLog");
607}
608
609void
610Logic::sendResetInterest()
611{
612 _LOG_DEBUG_ID(">> Logic::sendResetInterest");
613
614 if (m_needPeriodReset) {
615 _LOG_DEBUG_ID("Need Period Reset");
616 _LOG_DEBUG_ID("ResetTimer: " << m_resetTimer);
617
618 EventId eventId =
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600619 m_scheduler.scheduleEvent(m_resetTimer + ndn::time::milliseconds(m_reexpressionJitter(m_rng)),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700620 bind(&Logic::sendResetInterest, this));
621 m_scheduler.cancelEvent(m_resetInterestId);
622 m_resetInterestId = eventId;
623 }
624
625 Interest interest(m_syncReset);
626 interest.setMustBeFresh(true);
627 interest.setInterestLifetime(m_resetInterestLifetime);
628 m_face.expressInterest(interest,
629 bind(&Logic::onResetData, this, _1, _2),
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800630 bind(&Logic::onSyncTimeout, this, _1), // Nack
Yingdi Yuf7ede412014-08-30 20:37:52 -0700631 bind(&Logic::onSyncTimeout, this, _1));
632
633 _LOG_DEBUG_ID("<< Logic::sendResetInterest");
634}
635
636void
637Logic::sendSyncInterest()
638{
639 _LOG_DEBUG_ID(">> Logic::sendSyncInterest");
640
641 Name interestName;
642 interestName.append(m_syncPrefix)
643 .append(ndn::name::Component(*m_state.getRootDigest()));
644
645 m_outstandingInterestName = interestName;
646
647#ifdef _DEBUG
648 printDigest(m_state.getRootDigest());
649#endif
650
651 EventId eventId =
Sonu Mishra0dadc572016-12-12 23:59:41 -0800652 m_scheduler.scheduleEvent(m_syncInterestLifetime / 2 +
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600653 ndn::time::milliseconds(m_reexpressionJitter(m_rng)),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700654 bind(&Logic::sendSyncInterest, this));
655 m_scheduler.cancelEvent(m_reexpressingInterestId);
656 m_reexpressingInterestId = eventId;
657
658 Interest interest(interestName);
659 interest.setMustBeFresh(true);
660 interest.setInterestLifetime(m_syncInterestLifetime);
661
662 m_outstandingInterestId = m_face.expressInterest(interest,
663 bind(&Logic::onSyncData, this, _1, _2),
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800664 bind(&Logic::onSyncTimeout, this, _1), // Nack
Yingdi Yuf7ede412014-08-30 20:37:52 -0700665 bind(&Logic::onSyncTimeout, this, _1));
666
667 _LOG_DEBUG_ID("Send interest: " << interest.getName());
668 _LOG_DEBUG_ID("<< Logic::sendSyncInterest");
669}
670
671void
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600672Logic::trimState(State& partialState, const State& state, size_t maxSize)
673{
674 partialState.reset();
675 State tmp;
676 std::vector<ConstLeafPtr> leaves;
677 for (const ConstLeafPtr& leaf : state.getLeaves()) {
678 leaves.push_back(leaf);
679 }
680
681 std::shuffle(leaves.begin(), leaves.end(), m_rng);
682
683 for (const auto& constLeafPtr : leaves) {
684 tmp.update(constLeafPtr->getSessionName(), constLeafPtr->getSeq());
685 if (tmp.wireEncode().size() >= maxSize) {
686 break;
687 }
688 partialState.update(constLeafPtr->getSessionName(), constLeafPtr->getSeq());
689 }
690}
691
692void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800693Logic::sendSyncData(const Name& nodePrefix, const Name& name, const State& state)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700694{
695 _LOG_DEBUG_ID(">> Logic::sendSyncData");
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600696 if (m_nodeList.find(nodePrefix) == m_nodeList.end())
697 return;
698
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500699 Data syncReply(name);
700 syncReply.setContent(state.wireEncode());
701 syncReply.setFreshnessPeriod(m_syncReplyFreshness);
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600702
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800703 if (m_nodeList[nodePrefix].signingId.empty())
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500704 m_keyChain.sign(syncReply);
Yingdi Yucd339022014-11-05 17:51:19 -0800705 else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500706 m_keyChain.sign(syncReply, security::signingByIdentity(m_nodeList[nodePrefix].signingId));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700707
Alexander Afanasyev89036292018-02-13 17:19:50 -0500708 if (syncReply.wireEncode().size() > getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) {
709 _LOG_DEBUG("Sync reply size exceeded maximum packet limit (" << getMaxPacketLimit() << ")");
710 auto maxContentSize = getMaxPacketLimit() - (syncReply.wireEncode().size() - syncReply.getContent().size());
711 maxContentSize -= NDNLP_EXPECTED_OVERHEAD;
712
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600713 State partialState;
714 trimState(partialState, state, maxContentSize);
715 syncReply.setContent(partialState.wireEncode());
716
717 if (m_nodeList[nodePrefix].signingId.empty())
718 m_keyChain.sign(syncReply);
719 else
720 m_keyChain.sign(syncReply, security::signingByIdentity(m_nodeList[nodePrefix].signingId));
721 }
722
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500723 m_face.put(syncReply);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700724
725 // checking if our own interest got satisfied
726 if (m_outstandingInterestName == name) {
727 // remove outstanding interest
728 if (m_outstandingInterestId != 0) {
729 m_face.removePendingInterest(m_outstandingInterestId);
730 m_outstandingInterestId = 0;
731 }
732
733 // re-schedule sending Sync interest
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600734 time::milliseconds after(m_reexpressionJitter(m_rng));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700735 _LOG_DEBUG_ID("Satisfy our own interest");
736 _LOG_DEBUG_ID("Reschedule sync interest after " << after);
737 EventId eventId = m_scheduler.scheduleEvent(after, bind(&Logic::sendSyncInterest, this));
738 m_scheduler.cancelEvent(m_reexpressingInterestId);
739 m_reexpressingInterestId = eventId;
740 }
741 _LOG_DEBUG_ID("<< Logic::sendSyncData");
742}
743
744void
745Logic::cancelReset()
746{
747 _LOG_DEBUG_ID(">> Logic::cancelReset");
748 if (!m_isInReset)
749 return;
750
751 m_isInReset = false;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800752 for (const auto& node : m_nodeList) {
753 updateSeqNo(node.second.seqNo, node.first);
754 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700755 _LOG_DEBUG_ID("<< Logic::cancelReset");
756}
757
758void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500759Logic::printDigest(ConstBufferPtr digest)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700760{
Davide Pesavento5473abe2017-10-09 01:35:33 -0400761 std::string hash = ndn::toHex(digest->data(), digest->size(), false);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700762 _LOG_DEBUG_ID("Hash: " << hash);
763}
764
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800765void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500766Logic::sendRecoveryInterest(ConstBufferPtr digest)
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800767{
768 _LOG_DEBUG_ID(">> Logic::sendRecoveryInterest");
769
770 Name interestName;
771 interestName.append(m_syncPrefix)
772 .append(RECOVERY_COMPONENT)
773 .append(ndn::name::Component(*digest));
774
775 Interest interest(interestName);
776 interest.setMustBeFresh(true);
777 interest.setInterestLifetime(m_recoveryInterestLifetime);
778
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800779 m_face.expressInterest(interest,
780 bind(&Logic::onRecoveryData, this, _1, _2),
781 bind(&Logic::onRecoveryTimeout, this, _1), // Nack
782 bind(&Logic::onRecoveryTimeout, this, _1));
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800783
784 _LOG_DEBUG_ID("interest: " << interest.getName());
785 _LOG_DEBUG_ID("<< Logic::sendRecoveryInterest");
786}
787
788void
789Logic::processRecoveryInterest(const Interest& interest)
790{
791 _LOG_DEBUG_ID(">> Logic::processRecoveryInterest");
792
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500793 Name name = interest.getName();
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800794 ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
795
796 ConstBufferPtr rootDigest = m_state.getRootDigest();
797
798 DiffStateContainer::iterator stateIter = m_log.find(digest);
799
800 if (stateIter != m_log.end() || *digest == *EMPTY_DIGEST || *rootDigest == *digest) {
801 _LOG_DEBUG_ID("I can help you recover");
802 sendSyncData(m_defaultUserPrefix, name, m_state);
803 return;
804 }
805 _LOG_DEBUG_ID("<< Logic::processRecoveryInterest");
806}
807
808void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800809Logic::onRecoveryData(const Interest& interest, const Data& data)
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800810{
811 _LOG_DEBUG_ID(">> Logic::onRecoveryData");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500812 onSyncDataValidated(data);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800813 _LOG_DEBUG_ID("<< Logic::onRecoveryData");
814}
815
816void
817Logic::onRecoveryTimeout(const Interest& interest)
818{
819 _LOG_DEBUG_ID(">> Logic::onRecoveryTimeout");
820 _LOG_DEBUG_ID("Interest: " << interest.getName());
821 _LOG_DEBUG_ID("<< Logic::onRecoveryTimeout");
822}
823
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800824void
825Logic::sendExcludeInterest(const Interest& interest, const Data& data)
826{
827 _LOG_DEBUG_ID(">> Logic::sendExcludeInterest");
828
829 Name interestName = interest.getName();
830 Interest excludeInterest(interestName);
831
832 Exclude exclude = interest.getExclude();
833 exclude.excludeOne(data.getFullName().get(-1));
834 excludeInterest.setExclude(exclude);
Ashlesh Gawande04e8d492018-02-04 13:08:15 -0600835 excludeInterest.setMustBeFresh(true);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800836
837 excludeInterest.setInterestLifetime(m_syncInterestLifetime);
838
Ashlesh Gawanded31d6b12017-03-31 11:43:22 -0500839 if (excludeInterest.wireEncode().size() > ndn::MAX_NDN_PACKET_SIZE) {
840 return;
841 }
842
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800843 m_face.expressInterest(excludeInterest,
844 bind(&Logic::onSyncData, this, _1, _2),
845 bind(&Logic::onSyncTimeout, this, _1), // Nack
846 bind(&Logic::onSyncTimeout, this, _1));
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800847
848 _LOG_DEBUG_ID("Send interest: " << excludeInterest.getName());
849 _LOG_DEBUG_ID("<< Logic::sendExcludeInterest");
850}
851
852void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500853Logic::formAndSendExcludeInterest(const Name& nodePrefix, const State& commit, ConstBufferPtr previousRoot)
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800854{
855 _LOG_DEBUG_ID(">> Logic::formAndSendExcludeInterest");
856 Name interestName;
857 interestName.append(m_syncPrefix)
858 .append(ndn::name::Component(*previousRoot));
859 Interest interest(interestName);
860
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500861 Data data(interestName);
862 data.setContent(commit.wireEncode());
863 data.setFreshnessPeriod(m_syncReplyFreshness);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800864 if (m_nodeList.find(nodePrefix) == m_nodeList.end())
865 return;
866 if (m_nodeList[nodePrefix].signingId.empty())
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500867 m_keyChain.sign(data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800868 else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500869 m_keyChain.sign(data, security::signingByIdentity(m_nodeList[nodePrefix].signingId));
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800870
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500871 sendExcludeInterest(interest, data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800872
873 _LOG_DEBUG_ID("<< Logic::formAndSendExcludeInterest");
874}
875
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800876} // namespace chronosync