blob: 9d0f3faf5a0c79d91e48be04e124c386aef38505 [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"
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -050028#include "bzip2-helper.hpp"
Yingdi Yuf7ede412014-08-30 20:37:52 -070029
Alexander Afanasyev89036292018-02-13 17:19:50 -050030#include <ndn-cxx/util/backports.hpp>
Ashlesh Gawande687cf922017-05-30 15:04:16 -050031#include <ndn-cxx/util/string-helper.hpp>
32
Alexander Afanasyev36eb3ed2017-01-11 12:35:58 -080033INIT_LOGGER(Logic);
Yingdi Yuf7ede412014-08-30 20:37:52 -070034
Yingdi Yuf7ede412014-08-30 20:37:52 -070035#define _LOG_DEBUG_ID(v) _LOG_DEBUG("Instance" << m_instanceId << ": " << v)
Yingdi Yuf7ede412014-08-30 20:37:52 -070036
37namespace chronosync {
38
Yingdi Yuf7ede412014-08-30 20:37:52 -070039using ndn::EventId;
40
41const uint8_t EMPTY_DIGEST_VALUE[] = {
42 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
43 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
44 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
45 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
46};
47
Ashlesh Gawande08784d42017-09-06 23:40:21 -050048int Logic::s_instanceCounter = 0;
Yingdi Yuf7ede412014-08-30 20:37:52 -070049
Yingdi Yucd339022014-11-05 17:51:19 -080050const ndn::Name Logic::DEFAULT_NAME;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -080051const ndn::Name Logic::EMPTY_NAME;
Ashlesh Gawande08784d42017-09-06 23:40:21 -050052const std::shared_ptr<Validator> Logic::DEFAULT_VALIDATOR;
Yingdi Yuf7ede412014-08-30 20:37:52 -070053const time::steady_clock::Duration Logic::DEFAULT_RESET_TIMER = time::seconds(0);
54const time::steady_clock::Duration Logic::DEFAULT_CANCEL_RESET_TIMER = time::milliseconds(500);
55const time::milliseconds Logic::DEFAULT_RESET_INTEREST_LIFETIME(1000);
56const time::milliseconds Logic::DEFAULT_SYNC_INTEREST_LIFETIME(1000);
57const time::milliseconds Logic::DEFAULT_SYNC_REPLY_FRESHNESS(1000);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -080058const time::milliseconds Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME(1000);
Yingdi Yuf7ede412014-08-30 20:37:52 -070059
Ashlesh Gawande08784d42017-09-06 23:40:21 -050060const ConstBufferPtr Logic::EMPTY_DIGEST(new ndn::Buffer(EMPTY_DIGEST_VALUE, 32));
Yingdi Yuf7ede412014-08-30 20:37:52 -070061const ndn::name::Component Logic::RESET_COMPONENT("reset");
Sonu Mishra4d3a2e02017-01-18 20:27:51 -080062const ndn::name::Component Logic::RECOVERY_COMPONENT("recovery");
Yingdi Yuf7ede412014-08-30 20:37:52 -070063
Alexander Afanasyev89036292018-02-13 17:19:50 -050064const size_t NDNLP_EXPECTED_OVERHEAD = 20;
65
66/**
67 * Get maximum packet limit
68 *
69 * By default, it returns `ndn::MAX_NDN_PACKET_SIZE`.
70 * The returned value can be customized using the environment variable `CHRONOSYNC_MAX_PACKET_SIZE`,
71 * but the returned value will be at least 500 and no more than `ndn::MAX_NDN_PACKET_SIZE`.
72 */
73#ifndef CHRONOSYNC_HAVE_TESTS
74static
75#endif // CHRONOSYNC_HAVE_TESTS
76size_t
77getMaxPacketLimit()
78{
79 static size_t limit = 0;
80#ifndef CHRONOSYNC_HAVE_TESTS
81 if (limit != 0) {
82 return limit;
83 }
84#endif // CHRONOSYNC_HAVE_TESTS
85
86 if (getenv("CHRONOSYNC_MAX_PACKET_SIZE") != nullptr) {
87 try {
88 limit = ndn::clamp<size_t>(boost::lexical_cast<size_t>(getenv("CHRONOSYNC_MAX_PACKET_SIZE")),
89 500, ndn::MAX_NDN_PACKET_SIZE);
90 }
91 catch (const boost::bad_lexical_cast&) {
92 limit = ndn::MAX_NDN_PACKET_SIZE;
93 }
94 }
95 else {
96 limit = ndn::MAX_NDN_PACKET_SIZE;
97 }
98
99 return limit;
100}
101
Yingdi Yuf7ede412014-08-30 20:37:52 -0700102Logic::Logic(ndn::Face& face,
103 const Name& syncPrefix,
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800104 const Name& defaultUserPrefix,
Yingdi Yuf7ede412014-08-30 20:37:52 -0700105 const UpdateCallback& onUpdate,
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800106 const Name& defaultSigningId,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500107 std::shared_ptr<Validator> validator,
Yingdi Yuf7ede412014-08-30 20:37:52 -0700108 const time::steady_clock::Duration& resetTimer,
109 const time::steady_clock::Duration& cancelResetTimer,
110 const time::milliseconds& resetInterestLifetime,
111 const time::milliseconds& syncInterestLifetime,
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800112 const time::milliseconds& syncReplyFreshness,
113 const time::milliseconds& recoveryInterestLifetime)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700114 : m_face(face)
115 , m_syncPrefix(syncPrefix)
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800116 , m_defaultUserPrefix(defaultUserPrefix)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700117 , m_interestTable(m_face.getIoService())
118 , m_outstandingInterestId(0)
119 , m_isInReset(false)
120 , m_needPeriodReset(resetTimer > time::steady_clock::Duration::zero())
121 , m_onUpdate(onUpdate)
122 , m_scheduler(m_face.getIoService())
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600123 , m_rng(std::random_device{}())
124 , m_rangeUniformRandom(100, 500)
125 , m_reexpressionJitter(100, 500)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700126 , m_resetTimer(resetTimer)
127 , m_cancelResetTimer(cancelResetTimer)
128 , m_resetInterestLifetime(resetInterestLifetime)
129 , m_syncInterestLifetime(syncInterestLifetime)
130 , m_syncReplyFreshness(syncReplyFreshness)
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800131 , m_recoveryInterestLifetime(recoveryInterestLifetime)
Yingdi Yucd339022014-11-05 17:51:19 -0800132 , m_validator(validator)
Alexander Afanasyev90587b82018-02-11 20:36:53 -0500133 , m_instanceId(s_instanceCounter++)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700134{
Yingdi Yuf7ede412014-08-30 20:37:52 -0700135 _LOG_DEBUG_ID(">> Logic::Logic");
136
Ashlesh Gawande687cf922017-05-30 15:04:16 -0500137 addUserNode(m_defaultUserPrefix, defaultSigningId);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800138
Yingdi Yuf7ede412014-08-30 20:37:52 -0700139 m_syncReset = m_syncPrefix;
140 m_syncReset.append("reset");
141
142 _LOG_DEBUG_ID("Listen to: " << m_syncPrefix);
143 m_syncRegisteredPrefixId =
Junxiao Shi4e010bc2017-11-16 14:11:00 +0000144 m_face.setInterestFilter(ndn::InterestFilter(m_syncPrefix).allowLoopback(false),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700145 bind(&Logic::onSyncInterest, this, _1, _2),
146 bind(&Logic::onSyncRegisterFailed, this, _1, _2));
147
Qiuhan Dinge246b622014-12-03 21:57:48 -0800148 sendSyncInterest();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700149 _LOG_DEBUG_ID("<< Logic::Logic");
150}
151
152Logic::~Logic()
153{
Yingdi Yuf7ede412014-08-30 20:37:52 -0700154 m_scheduler.cancelAllEvents();
Yingdi Yu9d5679a2015-02-01 00:17:58 -0800155 m_interestTable.clear();
156 m_face.shutdown();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700157}
158
159void
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800160Logic::reset(bool isOnInterest)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700161{
162 m_isInReset = true;
163
164 m_state.reset();
165 m_log.clear();
166
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800167 if (!isOnInterest)
168 sendResetInterest();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700169
170 // reset outstanding interest name, so that data for previous interest will be dropped.
171 if (m_outstandingInterestId != 0) {
172 m_face.removePendingInterest(m_outstandingInterestId);
173 m_outstandingInterestId = 0;
174 }
175
176 sendSyncInterest();
177
178 if (static_cast<bool>(m_delayedInterestProcessingId))
179 m_scheduler.cancelEvent(m_delayedInterestProcessingId);
180
181 m_delayedInterestProcessingId =
182 m_scheduler.scheduleEvent(m_cancelResetTimer,
183 bind(&Logic::cancelReset, this));
184}
185
186void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800187Logic::setDefaultUserPrefix(const Name& defaultUserPrefix)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700188{
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800189 if (defaultUserPrefix != EMPTY_NAME) {
190 if (m_nodeList.find(defaultUserPrefix) != m_nodeList.end()) {
191 m_defaultUserPrefix = defaultUserPrefix;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800192 }
193 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700194}
195
196void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800197Logic::addUserNode(const Name& userPrefix, const Name& signingId)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700198{
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800199 if (userPrefix == EMPTY_NAME)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700200 return;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800201 if (m_defaultUserPrefix == EMPTY_NAME) {
202 m_defaultUserPrefix = userPrefix;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800203 }
204 if (m_nodeList.find(userPrefix) == m_nodeList.end()) {
205 m_nodeList[userPrefix].userPrefix = userPrefix;
206 m_nodeList[userPrefix].signingId = signingId;
207 Name sessionName = userPrefix;
208 sessionName.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
209 m_nodeList[userPrefix].sessionName = sessionName;
210 m_nodeList[userPrefix].seqNo = 0;
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800211 reset(false);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800212 }
213}
Yingdi Yuf7ede412014-08-30 20:37:52 -0700214
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800215void
216Logic::removeUserNode(const Name& userPrefix)
217{
218 auto userNode = m_nodeList.find(userPrefix);
219 if (userNode != m_nodeList.end()) {
220 m_nodeList.erase(userNode);
221 if (m_defaultUserPrefix == userPrefix) {
222 if (!m_nodeList.empty()) {
223 m_defaultUserPrefix = m_nodeList.begin()->second.userPrefix;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800224 }
225 else {
226 m_defaultUserPrefix = EMPTY_NAME;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800227 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700228 }
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800229 reset(false);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800230 }
231}
Yingdi Yuf7ede412014-08-30 20:37:52 -0700232
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800233const Name&
234Logic::getSessionName(Name prefix)
235{
236 if (prefix == EMPTY_NAME)
237 prefix = m_defaultUserPrefix;
238 auto node = m_nodeList.find(prefix);
239 if (node != m_nodeList.end())
240 return node->second.sessionName;
241 else
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800242 BOOST_THROW_EXCEPTION(Error("Refer to non-existent node:" + prefix.toUri()));
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800243}
Yingdi Yuf7ede412014-08-30 20:37:52 -0700244
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800245const SeqNo&
246Logic::getSeqNo(Name prefix)
247{
248 if (prefix == EMPTY_NAME)
249 prefix = m_defaultUserPrefix;
250 auto node = m_nodeList.find(prefix);
251 if (node != m_nodeList.end())
252 return node->second.seqNo;
253 else
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800254 BOOST_THROW_EXCEPTION(Logic::Error("Refer to non-existent node:" + prefix.toUri()));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700255
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800256}
257
258void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800259Logic::updateSeqNo(const SeqNo& seqNo, const Name& updatePrefix)
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800260{
261 Name prefix;
262 if (updatePrefix == EMPTY_NAME) {
263 if (m_defaultUserPrefix == EMPTY_NAME)
264 return;
265 prefix = m_defaultUserPrefix;
266 }
267 else
268 prefix = updatePrefix;
269
270 auto it = m_nodeList.find(prefix);
271 if (it != m_nodeList.end()) {
272 NodeInfo& node = it->second;
273 _LOG_DEBUG_ID(">> Logic::updateSeqNo");
274 _LOG_DEBUG_ID("seqNo: " << seqNo << " m_seqNo: " << node.seqNo);
275 if (seqNo < node.seqNo || seqNo == 0)
276 return;
277
278 node.seqNo = seqNo;
279 _LOG_DEBUG_ID("updateSeqNo: m_seqNo " << node.seqNo);
280
281 if (!m_isInReset) {
282 _LOG_DEBUG_ID("updateSeqNo: not in Reset ");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500283 ConstBufferPtr previousRoot = m_state.getRootDigest();
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800284 {
Davide Pesavento5473abe2017-10-09 01:35:33 -0400285 std::string hash = ndn::toHex(previousRoot->data(), previousRoot->size(), false);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800286 _LOG_DEBUG_ID("Hash: " << hash);
287 }
288
289 bool isInserted = false;
290 bool isUpdated = false;
291 SeqNo oldSeq;
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500292 std::tie(isInserted, isUpdated, oldSeq) = m_state.update(node.sessionName, node.seqNo);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800293
294 _LOG_DEBUG_ID("Insert: " << std::boolalpha << isInserted);
295 _LOG_DEBUG_ID("Updated: " << std::boolalpha << isUpdated);
296 if (isInserted || isUpdated) {
297 DiffStatePtr commit = make_shared<DiffState>();
298 commit->update(node.sessionName, node.seqNo);
299 commit->setRootDigest(m_state.getRootDigest());
300 insertToDiffLog(commit, previousRoot);
301
302 satisfyPendingSyncInterests(prefix, commit);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800303 formAndSendExcludeInterest(prefix, *commit, previousRoot);
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800304 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700305 }
306 }
307}
308
309ConstBufferPtr
310Logic::getRootDigest() const
311{
312 return m_state.getRootDigest();
313}
314
315void
316Logic::printState(std::ostream& os) const
317{
318 BOOST_FOREACH(ConstLeafPtr leaf, m_state.getLeaves())
319 {
320 os << *leaf << "\n";
321 }
322}
323
324std::set<Name>
325Logic::getSessionNames() const
326{
327 std::set<Name> sessionNames;
328
329 BOOST_FOREACH(ConstLeafPtr leaf, m_state.getLeaves())
330 {
331 sessionNames.insert(leaf->getSessionName());
332 }
333
334 return sessionNames;
335}
336
337void
338Logic::onSyncInterest(const Name& prefix, const Interest& interest)
339{
340 _LOG_DEBUG_ID(">> Logic::onSyncInterest");
341 Name name = interest.getName();
342
343 _LOG_DEBUG_ID("InterestName: " << name);
344
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800345 if (name.size() >= 1 && RESET_COMPONENT == name.get(-1)) {
346 processResetInterest(interest);
347 }
348 else if (name.size() >= 2 && RECOVERY_COMPONENT == name.get(-2)) {
349 processRecoveryInterest(interest);
350 }
Ashlesh Gawande8ba7d5a2017-07-24 14:43:12 -0500351 // Do not process exclude interests, they should be answered by CS
352 else if (interest.getExclude().empty()) {
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500353 processSyncInterest(interest);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700354 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700355
356 _LOG_DEBUG_ID("<< Logic::onSyncInterest");
357}
358
359void
360Logic::onSyncRegisterFailed(const Name& prefix, const std::string& msg)
361{
362 //Sync prefix registration failed
363 _LOG_DEBUG_ID(">> Logic::onSyncRegisterFailed");
364}
365
366void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800367Logic::onSyncData(const Interest& interest, const Data& data)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700368{
369 _LOG_DEBUG_ID(">> Logic::onSyncData");
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800370 // if (static_cast<bool>(m_validator))
371 // m_validator->validate(data,
372 // bind(&Logic::onSyncDataValidated, this, _1),
373 // bind(&Logic::onSyncDataValidationFailed, this, _1));
374 // else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500375 // onSyncDataValidated(data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800376
377 if (interest.getExclude().empty()) {
378 _LOG_DEBUG_ID("First data");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500379 onSyncDataValidated(data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800380 }
381 else {
382 _LOG_DEBUG_ID("Data obtained using exclude filter");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500383 onSyncDataValidated(data, false);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800384 }
385 sendExcludeInterest(interest, data);
386
Yingdi Yuf7ede412014-08-30 20:37:52 -0700387 _LOG_DEBUG_ID("<< Logic::onSyncData");
388}
389
390void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800391Logic::onResetData(const Interest& interest, const Data& data)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700392{
393 // This should not happened, drop the received data.
394}
395
396void
397Logic::onSyncTimeout(const Interest& interest)
398{
399 // It is OK. Others will handle the time out situation.
400 _LOG_DEBUG_ID(">> Logic::onSyncTimeout");
401 _LOG_DEBUG_ID("Interest: " << interest.getName());
402 _LOG_DEBUG_ID("<< Logic::onSyncTimeout");
403}
404
405void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500406Logic::onSyncDataValidationFailed(const Data& data)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700407{
408 // SyncReply cannot be validated.
409}
410
411void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500412Logic::onSyncDataValidated(const Data& data, bool firstData)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700413{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500414 Name name = data.getName();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700415 ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
416
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500417 auto contentBuffer = bzip2::decompress(reinterpret_cast<const char*>(data.getContent().value()),
418 data.getContent().value_size());
419 processSyncData(name, digest, Block(contentBuffer), firstData);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700420}
421
422void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500423Logic::processSyncInterest(const Interest& interest, bool isTimedProcessing/*=false*/)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700424{
425 _LOG_DEBUG_ID(">> Logic::processSyncInterest");
426
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500427 Name name = interest.getName();
428 ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
Yingdi Yuf7ede412014-08-30 20:37:52 -0700429
430 ConstBufferPtr rootDigest = m_state.getRootDigest();
431
432 // If the digest of the incoming interest is the same as root digest
433 // Put the interest into InterestTable
434 if (*rootDigest == *digest) {
435 _LOG_DEBUG_ID("Oh, we are in the same state");
436 m_interestTable.insert(interest, digest, false);
437
438 if (!m_isInReset)
439 return;
440
441 if (!isTimedProcessing) {
442 _LOG_DEBUG_ID("Non timed processing in reset");
443 // Still in reset, our own seq has not been put into state yet
444 // Do not hurry, some others may be also resetting and may send their reply
445 if (static_cast<bool>(m_delayedInterestProcessingId))
446 m_scheduler.cancelEvent(m_delayedInterestProcessingId);
447
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600448 time::milliseconds after(m_rangeUniformRandom(m_rng));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700449 _LOG_DEBUG_ID("After: " << after);
450 m_delayedInterestProcessingId =
451 m_scheduler.scheduleEvent(after,
452 bind(&Logic::processSyncInterest, this, interest, true));
453 }
454 else {
455 _LOG_DEBUG_ID("Timed processing in reset");
456 // Now we can get out of reset state by putting our own stuff into m_state.
457 cancelReset();
458 }
459
460 return;
461 }
462
463 // If the digest of incoming interest is an "empty" digest
Sonu Mishrae10acbc2017-01-18 14:14:05 -0800464 if (*digest == *EMPTY_DIGEST) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700465 _LOG_DEBUG_ID("Poor guy, he knows nothing");
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800466 sendSyncData(m_defaultUserPrefix, name, m_state);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700467 return;
468 }
469
470 DiffStateContainer::iterator stateIter = m_log.find(digest);
471 // If the digest of incoming interest can be found from the log
472 if (stateIter != m_log.end()) {
473 _LOG_DEBUG_ID("It is ok, you are so close");
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800474 sendSyncData(m_defaultUserPrefix, name, *(*stateIter)->diff());
Yingdi Yuf7ede412014-08-30 20:37:52 -0700475 return;
476 }
477
478 if (!isTimedProcessing) {
479 _LOG_DEBUG_ID("Let's wait, just wait for a while");
480 // Do not hurry, some incoming SyncReplies may help us to recognize the digest
Yingdi Yu53f5f042015-01-31 16:33:25 -0800481 bool doesExist = m_interestTable.has(digest);
482 m_interestTable.insert(interest, digest, true);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700483 if (doesExist)
484 // Original comment (not sure): somebody else replied, so restart random-game timer
485 // YY: Get the same SyncInterest again, refresh the timer
486 m_scheduler.cancelEvent(m_delayedInterestProcessingId);
487
488 m_delayedInterestProcessingId =
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600489 m_scheduler.scheduleEvent(time::milliseconds(m_rangeUniformRandom(m_rng)),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700490 bind(&Logic::processSyncInterest, this, interest, true));
491 }
492 else {
493 // OK, nobody is helping us, just tell the truth.
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800494 _LOG_DEBUG_ID("OK, nobody is helping us, let us try to recover");
Yingdi Yuf7ede412014-08-30 20:37:52 -0700495 m_interestTable.erase(digest);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800496 sendRecoveryInterest(digest);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700497 }
498
499 _LOG_DEBUG_ID("<< Logic::processSyncInterest");
500}
501
502void
503Logic::processResetInterest(const Interest& interest)
504{
505 _LOG_DEBUG_ID(">> Logic::processResetInterest");
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800506 reset(true);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700507}
508
509void
510Logic::processSyncData(const Name& name,
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500511 ConstBufferPtr digest,
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800512 const Block& syncReplyBlock,
513 bool firstData)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700514{
515 _LOG_DEBUG_ID(">> Logic::processSyncData");
Yingdi Yuf7ede412014-08-30 20:37:52 -0700516 DiffStatePtr commit = make_shared<DiffState>();
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500517 ConstBufferPtr previousRoot = m_state.getRootDigest();
Yingdi Yuf7ede412014-08-30 20:37:52 -0700518
519 try {
520 m_interestTable.erase(digest); // Remove satisfied interest from PIT
521
522 State reply;
523 reply.wireDecode(syncReplyBlock);
524
525 std::vector<MissingDataInfo> v;
526 BOOST_FOREACH(ConstLeafPtr leaf, reply.getLeaves().get<ordered>())
527 {
528 BOOST_ASSERT(leaf != 0);
529
530 const Name& info = leaf->getSessionName();
531 SeqNo seq = leaf->getSeq();
532
533 bool isInserted = false;
534 bool isUpdated = false;
535 SeqNo oldSeq;
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500536 std::tie(isInserted, isUpdated, oldSeq) = m_state.update(info, seq);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700537 if (isInserted || isUpdated) {
538 commit->update(info, seq);
539
540 oldSeq++;
541 MissingDataInfo mdi = {info, oldSeq, seq};
542 v.push_back(mdi);
543 }
544 }
545
546 if (!v.empty()) {
547 m_onUpdate(v);
548
549 commit->setRootDigest(m_state.getRootDigest());
550 insertToDiffLog(commit, previousRoot);
551 }
552 else {
553 _LOG_DEBUG_ID("What? nothing new");
554 }
555 }
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800556 catch (const State::Error&) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700557 _LOG_DEBUG_ID("Something really fishy happened during state decoding");
558 // Something really fishy happened during state decoding;
559 commit.reset();
560 return;
561 }
562
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800563 if (static_cast<bool>(commit) && !commit->getLeaves().empty() && firstData) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700564 // state changed and it is safe to express a new interest
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600565 time::steady_clock::Duration after = time::milliseconds(m_reexpressionJitter(m_rng));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700566 _LOG_DEBUG_ID("Reschedule sync interest after: " << after);
567 EventId eventId = m_scheduler.scheduleEvent(after,
568 bind(&Logic::sendSyncInterest, this));
569
570 m_scheduler.cancelEvent(m_reexpressingInterestId);
571 m_reexpressingInterestId = eventId;
572 }
573}
574
575void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800576Logic::satisfyPendingSyncInterests(const Name& updatedPrefix, ConstDiffStatePtr commit)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700577{
578 _LOG_DEBUG_ID(">> Logic::satisfyPendingSyncInterests");
579 try {
580 _LOG_DEBUG_ID("InterestTable size: " << m_interestTable.size());
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500581 auto it = m_interestTable.begin();
582 while (it != m_interestTable.end()) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700583 ConstUnsatisfiedInterestPtr request = *it;
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500584 ++it;
Yingdi Yuf7ede412014-08-30 20:37:52 -0700585 if (request->isUnknown)
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500586 sendSyncData(updatedPrefix, request->interest.getName(), m_state);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700587 else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500588 sendSyncData(updatedPrefix, request->interest.getName(), *commit);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700589 }
590 m_interestTable.clear();
591 }
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800592 catch (const InterestTable::Error&) {
Yingdi Yuf7ede412014-08-30 20:37:52 -0700593 // ok. not really an error
594 }
595 _LOG_DEBUG_ID("<< Logic::satisfyPendingSyncInterests");
596}
597
598void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500599Logic::insertToDiffLog(DiffStatePtr commit, ConstBufferPtr previousRoot)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700600{
601 _LOG_DEBUG_ID(">> Logic::insertToDiffLog");
602 // Connect to the history
603 if (!m_log.empty())
604 (*m_log.find(previousRoot))->setNext(commit);
605
606 // Insert the commit
607 m_log.erase(commit->getRootDigest());
608 m_log.insert(commit);
609 _LOG_DEBUG_ID("<< Logic::insertToDiffLog");
610}
611
612void
613Logic::sendResetInterest()
614{
615 _LOG_DEBUG_ID(">> Logic::sendResetInterest");
616
617 if (m_needPeriodReset) {
618 _LOG_DEBUG_ID("Need Period Reset");
619 _LOG_DEBUG_ID("ResetTimer: " << m_resetTimer);
620
621 EventId eventId =
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600622 m_scheduler.scheduleEvent(m_resetTimer + ndn::time::milliseconds(m_reexpressionJitter(m_rng)),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700623 bind(&Logic::sendResetInterest, this));
624 m_scheduler.cancelEvent(m_resetInterestId);
625 m_resetInterestId = eventId;
626 }
627
628 Interest interest(m_syncReset);
629 interest.setMustBeFresh(true);
630 interest.setInterestLifetime(m_resetInterestLifetime);
631 m_face.expressInterest(interest,
632 bind(&Logic::onResetData, this, _1, _2),
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800633 bind(&Logic::onSyncTimeout, this, _1), // Nack
Yingdi Yuf7ede412014-08-30 20:37:52 -0700634 bind(&Logic::onSyncTimeout, this, _1));
635
636 _LOG_DEBUG_ID("<< Logic::sendResetInterest");
637}
638
639void
640Logic::sendSyncInterest()
641{
642 _LOG_DEBUG_ID(">> Logic::sendSyncInterest");
643
644 Name interestName;
645 interestName.append(m_syncPrefix)
646 .append(ndn::name::Component(*m_state.getRootDigest()));
647
648 m_outstandingInterestName = interestName;
649
650#ifdef _DEBUG
651 printDigest(m_state.getRootDigest());
652#endif
653
654 EventId eventId =
Sonu Mishra0dadc572016-12-12 23:59:41 -0800655 m_scheduler.scheduleEvent(m_syncInterestLifetime / 2 +
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600656 ndn::time::milliseconds(m_reexpressionJitter(m_rng)),
Yingdi Yuf7ede412014-08-30 20:37:52 -0700657 bind(&Logic::sendSyncInterest, this));
658 m_scheduler.cancelEvent(m_reexpressingInterestId);
659 m_reexpressingInterestId = eventId;
660
661 Interest interest(interestName);
662 interest.setMustBeFresh(true);
663 interest.setInterestLifetime(m_syncInterestLifetime);
664
665 m_outstandingInterestId = m_face.expressInterest(interest,
666 bind(&Logic::onSyncData, this, _1, _2),
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800667 bind(&Logic::onSyncTimeout, this, _1), // Nack
Yingdi Yuf7ede412014-08-30 20:37:52 -0700668 bind(&Logic::onSyncTimeout, this, _1));
669
670 _LOG_DEBUG_ID("Send interest: " << interest.getName());
671 _LOG_DEBUG_ID("<< Logic::sendSyncInterest");
672}
673
674void
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500675Logic::trimState(State& partialState, const State& state, size_t nExcludedStates)
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600676{
677 partialState.reset();
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500678
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600679 std::vector<ConstLeafPtr> leaves;
680 for (const ConstLeafPtr& leaf : state.getLeaves()) {
681 leaves.push_back(leaf);
682 }
683
684 std::shuffle(leaves.begin(), leaves.end(), m_rng);
685
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500686 size_t statesToEncode = leaves.size() - std::min(leaves.size() - 1, nExcludedStates);
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600687 for (const auto& constLeafPtr : leaves) {
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500688 if (statesToEncode == 0) {
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600689 break;
690 }
691 partialState.update(constLeafPtr->getSessionName(), constLeafPtr->getSeq());
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500692 --statesToEncode;
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600693 }
694}
695
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500696Data
697Logic::encodeSyncReply(const Name& nodePrefix, const Name& name, const State& state)
698{
699 Data syncReply(name);
700 syncReply.setFreshnessPeriod(m_syncReplyFreshness);
701
702 auto finalizeReply = [this, &nodePrefix, &syncReply] (const State& state) {
703 auto contentBuffer = bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().wire()),
704 state.wireEncode().size());
705 syncReply.setContent(contentBuffer);
706
707 if (m_nodeList[nodePrefix].signingId.empty())
708 m_keyChain.sign(syncReply);
709 else
710 m_keyChain.sign(syncReply, security::signingByIdentity(m_nodeList[nodePrefix].signingId));
711 };
712
713 finalizeReply(state);
714
715 size_t nExcludedStates = 1;
716 while (syncReply.wireEncode().size() > getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) {
717 if (nExcludedStates == 1) {
718 // To show this debug message only once
719 _LOG_DEBUG("Sync reply size exceeded maximum packet limit (" << (getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) << ")");
720 }
721 State partialState;
722 trimState(partialState, state, nExcludedStates);
723 finalizeReply(partialState);
724
725 BOOST_ASSERT(state.getLeaves().size() != 0);
726 nExcludedStates *= 2;
727 }
728
729 return syncReply;
730}
731
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600732void
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800733Logic::sendSyncData(const Name& nodePrefix, const Name& name, const State& state)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700734{
735 _LOG_DEBUG_ID(">> Logic::sendSyncData");
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600736 if (m_nodeList.find(nodePrefix) == m_nodeList.end())
737 return;
738
Alexander Afanasyev6ee98ff2018-02-13 19:12:28 -0500739 m_face.put(encodeSyncReply(nodePrefix, name, state));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700740
741 // checking if our own interest got satisfied
742 if (m_outstandingInterestName == name) {
743 // remove outstanding interest
744 if (m_outstandingInterestId != 0) {
745 m_face.removePendingInterest(m_outstandingInterestId);
746 m_outstandingInterestId = 0;
747 }
748
749 // re-schedule sending Sync interest
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600750 time::milliseconds after(m_reexpressionJitter(m_rng));
Yingdi Yuf7ede412014-08-30 20:37:52 -0700751 _LOG_DEBUG_ID("Satisfy our own interest");
752 _LOG_DEBUG_ID("Reschedule sync interest after " << after);
753 EventId eventId = m_scheduler.scheduleEvent(after, bind(&Logic::sendSyncInterest, this));
754 m_scheduler.cancelEvent(m_reexpressingInterestId);
755 m_reexpressingInterestId = eventId;
756 }
757 _LOG_DEBUG_ID("<< Logic::sendSyncData");
758}
759
760void
761Logic::cancelReset()
762{
763 _LOG_DEBUG_ID(">> Logic::cancelReset");
764 if (!m_isInReset)
765 return;
766
767 m_isInReset = false;
Qiuhan Ding8c095fd2014-11-19 17:38:32 -0800768 for (const auto& node : m_nodeList) {
769 updateSeqNo(node.second.seqNo, node.first);
770 }
Yingdi Yuf7ede412014-08-30 20:37:52 -0700771 _LOG_DEBUG_ID("<< Logic::cancelReset");
772}
773
774void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500775Logic::printDigest(ConstBufferPtr digest)
Yingdi Yuf7ede412014-08-30 20:37:52 -0700776{
Davide Pesavento5473abe2017-10-09 01:35:33 -0400777 std::string hash = ndn::toHex(digest->data(), digest->size(), false);
Yingdi Yuf7ede412014-08-30 20:37:52 -0700778 _LOG_DEBUG_ID("Hash: " << hash);
779}
780
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800781void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500782Logic::sendRecoveryInterest(ConstBufferPtr digest)
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800783{
784 _LOG_DEBUG_ID(">> Logic::sendRecoveryInterest");
785
786 Name interestName;
787 interestName.append(m_syncPrefix)
788 .append(RECOVERY_COMPONENT)
789 .append(ndn::name::Component(*digest));
790
791 Interest interest(interestName);
792 interest.setMustBeFresh(true);
793 interest.setInterestLifetime(m_recoveryInterestLifetime);
794
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800795 m_face.expressInterest(interest,
796 bind(&Logic::onRecoveryData, this, _1, _2),
797 bind(&Logic::onRecoveryTimeout, this, _1), // Nack
798 bind(&Logic::onRecoveryTimeout, this, _1));
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800799
800 _LOG_DEBUG_ID("interest: " << interest.getName());
801 _LOG_DEBUG_ID("<< Logic::sendRecoveryInterest");
802}
803
804void
805Logic::processRecoveryInterest(const Interest& interest)
806{
807 _LOG_DEBUG_ID(">> Logic::processRecoveryInterest");
808
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500809 Name name = interest.getName();
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800810 ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
811
812 ConstBufferPtr rootDigest = m_state.getRootDigest();
813
814 DiffStateContainer::iterator stateIter = m_log.find(digest);
815
816 if (stateIter != m_log.end() || *digest == *EMPTY_DIGEST || *rootDigest == *digest) {
817 _LOG_DEBUG_ID("I can help you recover");
818 sendSyncData(m_defaultUserPrefix, name, m_state);
819 return;
820 }
821 _LOG_DEBUG_ID("<< Logic::processRecoveryInterest");
822}
823
824void
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800825Logic::onRecoveryData(const Interest& interest, const Data& data)
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800826{
827 _LOG_DEBUG_ID(">> Logic::onRecoveryData");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500828 onSyncDataValidated(data);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800829 _LOG_DEBUG_ID("<< Logic::onRecoveryData");
830}
831
832void
833Logic::onRecoveryTimeout(const Interest& interest)
834{
835 _LOG_DEBUG_ID(">> Logic::onRecoveryTimeout");
836 _LOG_DEBUG_ID("Interest: " << interest.getName());
837 _LOG_DEBUG_ID("<< Logic::onRecoveryTimeout");
838}
839
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800840void
841Logic::sendExcludeInterest(const Interest& interest, const Data& data)
842{
843 _LOG_DEBUG_ID(">> Logic::sendExcludeInterest");
844
845 Name interestName = interest.getName();
846 Interest excludeInterest(interestName);
847
848 Exclude exclude = interest.getExclude();
849 exclude.excludeOne(data.getFullName().get(-1));
850 excludeInterest.setExclude(exclude);
Ashlesh Gawande04e8d492018-02-04 13:08:15 -0600851 excludeInterest.setMustBeFresh(true);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800852
853 excludeInterest.setInterestLifetime(m_syncInterestLifetime);
854
Ashlesh Gawanded31d6b12017-03-31 11:43:22 -0500855 if (excludeInterest.wireEncode().size() > ndn::MAX_NDN_PACKET_SIZE) {
856 return;
857 }
858
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800859 m_face.expressInterest(excludeInterest,
860 bind(&Logic::onSyncData, this, _1, _2),
861 bind(&Logic::onSyncTimeout, this, _1), // Nack
862 bind(&Logic::onSyncTimeout, this, _1));
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800863
864 _LOG_DEBUG_ID("Send interest: " << excludeInterest.getName());
865 _LOG_DEBUG_ID("<< Logic::sendExcludeInterest");
866}
867
868void
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500869Logic::formAndSendExcludeInterest(const Name& nodePrefix, const State& commit, ConstBufferPtr previousRoot)
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800870{
871 _LOG_DEBUG_ID(">> Logic::formAndSendExcludeInterest");
872 Name interestName;
873 interestName.append(m_syncPrefix)
874 .append(ndn::name::Component(*previousRoot));
875 Interest interest(interestName);
876
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500877 Data data(interestName);
878 data.setContent(commit.wireEncode());
879 data.setFreshnessPeriod(m_syncReplyFreshness);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800880 if (m_nodeList.find(nodePrefix) == m_nodeList.end())
881 return;
882 if (m_nodeList[nodePrefix].signingId.empty())
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500883 m_keyChain.sign(data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800884 else
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500885 m_keyChain.sign(data, security::signingByIdentity(m_nodeList[nodePrefix].signingId));
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800886
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500887 sendExcludeInterest(interest, data);
Sonu Mishraf42aa2c2017-01-22 18:47:33 -0800888
889 _LOG_DEBUG_ID("<< Logic::formAndSendExcludeInterest");
890}
891
Alexander Afanasyeve9eda8a2017-03-09 14:40:03 -0800892} // namespace chronosync