blob: 67fb3420b11bb3f11f9004fa27019b7c6c9923dc [file] [log] [blame]
Zhenkai Zhu8d935c82012-03-06 10:44:12 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
Chaoyi Bian3e1eb162012-04-03 16:59:32 -070019 * Chaoyi Bian <bcy@pku.edu.cn>
Zhenkai Zhu8d935c82012-03-06 10:44:12 -080020 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Yingdi Yu6d638f02014-01-24 11:01:21 -080021 * Yingdi Yu <yingdi@cs.ucla.edu>
Zhenkai Zhu8d935c82012-03-06 10:44:12 -080022 */
Chaoyi Bian44fff0c2012-03-07 21:07:22 -080023
Alexander Afanasyevb6cf56e2012-05-29 19:33:49 -070024#ifdef NS3_MODULE
Alexander Afanasyev0ac399e2012-04-27 13:28:28 -070025#include <ns3/ccnx-pit.h>
26#include <ns3/ccnx.h>
Alexander Afanasyevb6cf56e2012-05-29 19:33:49 -070027#endif
Alexander Afanasyev0ac399e2012-04-27 13:28:28 -070028
Chaoyi Bian11f294f2012-03-08 14:28:06 -080029#include "sync-logic.h"
Chaoyi Bian89ee2dc2012-03-09 14:06:01 -080030#include "sync-diff-leaf.h"
31#include "sync-full-leaf.h"
Alexander Afanasyevce001692013-07-14 11:34:41 -070032#include "sync-logging.h"
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -070033#include "sync-state.h"
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070034
Chaoyi Bian89ee2dc2012-03-09 14:06:01 -080035#include <boost/make_shared.hpp>
36#include <boost/foreach.hpp>
Alexander Afanasyev387ac952012-03-11 23:49:27 -070037#include <boost/lexical_cast.hpp>
Zhenkai Zhua5d06d72012-03-09 15:16:24 -080038#include <vector>
Chaoyi Bian44fff0c2012-03-07 21:07:22 -080039
40using namespace std;
Yingdi Yu43e71612013-10-30 22:19:31 -070041using namespace ndn;
Yingdi Yu46c9f1a2013-12-18 15:15:46 +080042using namespace ndn::ptr_lib;
43using namespace ndn::func_lib;
Chaoyi Bian44fff0c2012-03-07 21:07:22 -080044
Chaoyi Bianf007f922012-04-09 20:05:37 -070045INIT_LOGGER ("SyncLogic");
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070046
Alexander Afanasyev983b0e92012-04-26 12:44:18 -070047#ifdef NS3_MODULE
48#define GET_RANDOM(var) var.GetValue ()
49#else
50#define GET_RANDOM(var) var ()
51#endif
52
53#define TIME_SECONDS_WITH_JITTER(sec) \
54 (TIME_SECONDS (sec) + TIME_MILLISECONDS (GET_RANDOM (m_reexpressionJitter)))
55
Alexander Afanasyev42612262012-05-05 10:58:37 -070056#define TIME_MILLISECONDS_WITH_JITTER(ms) \
57 (TIME_MILLISECONDS (ms) + TIME_MILLISECONDS (GET_RANDOM (m_reexpressionJitter)))
Alexander Afanasyev983b0e92012-04-26 12:44:18 -070058
59
Chaoyi Bian44fff0c2012-03-07 21:07:22 -080060namespace Sync
61{
62
Yingdi Yu43e71612013-10-30 22:19:31 -070063 SyncLogic::SyncLogic (const Name& syncPrefix,
Yingdi Yu5e0af3e2014-01-15 19:33:25 -080064 shared_ptr<SecPolicySync> policy,
Yingdi Yu6e235db2013-12-27 08:40:53 +080065 shared_ptr<Face> face,
Yingdi Yu43e71612013-10-30 22:19:31 -070066 LogicUpdateCallback onUpdate,
67 LogicRemoveCallback onRemove)
68 : m_state (new FullState)
69 , m_syncInterestTable (TIME_SECONDS (m_syncInterestReexpress))
70 , m_syncPrefix (syncPrefix)
71 , m_onUpdate (onUpdate)
72 , m_onRemove (onRemove)
73 , m_perBranch (false)
Yingdi Yu5e0af3e2014-01-15 19:33:25 -080074 , m_policy(policy)
75 , m_verifier(new Verifier(policy))
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -080076 , m_keyChain(new KeyChain())
Yingdi Yu6e235db2013-12-27 08:40:53 +080077 , m_face(face)
Alexander Afanasyev73f7f9a2012-04-09 15:45:47 -070078#ifndef NS3_MODULE
Yingdi Yu43e71612013-10-30 22:19:31 -070079 , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
80 , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
81 , m_reexpressionJitter (m_randomGenerator, uniform_int<> (100,500))
Alexander Afanasyev73f7f9a2012-04-09 15:45:47 -070082#else
Yingdi Yu43e71612013-10-30 22:19:31 -070083 , m_rangeUniformRandom (200,1000)
84 , m_reexpressionJitter (10,500)
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -070085#endif
Yingdi Yu43e71612013-10-30 22:19:31 -070086 , m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -070087{
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -070088#ifndef NS3_MODULE
89 // In NS3 module these functions are moved to StartApplication method
Yingdi Yu43e71612013-10-30 22:19:31 -070090
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -080091 m_syncRegisteredPrefixId = m_face->setInterestFilter(m_syncPrefix,
92 func_lib::bind(&SyncLogic::onSyncInterest, this, _1, _2, _3, _4),
93 func_lib::bind(&SyncLogic::onSyncRegisterFailed, this, _1));
Yingdi Yu46c9f1a2013-12-18 15:15:46 +080094
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070095
Alexander Afanasyev983b0e92012-04-26 12:44:18 -070096 m_scheduler.schedule (TIME_SECONDS (0), // no need to add jitter
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -080097 func_lib::bind (&SyncLogic::sendSyncInterest, this),
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070098 REEXPRESSING_INTEREST);
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -070099#endif
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800100}
101
Yingdi Yu43e71612013-10-30 22:19:31 -0700102SyncLogic::SyncLogic (const Name& syncPrefix,
Yingdi Yu5e0af3e2014-01-15 19:33:25 -0800103 shared_ptr<SecPolicySync> policy,
Yingdi Yu6e235db2013-12-27 08:40:53 +0800104 shared_ptr<Face> face,
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700105 LogicPerBranchCallback onUpdateBranch)
106 : m_state (new FullState)
107 , m_syncInterestTable (TIME_SECONDS (m_syncInterestReexpress))
108 , m_syncPrefix (syncPrefix)
109 , m_onUpdateBranch (onUpdateBranch)
110 , m_perBranch(true)
Yingdi Yu5e0af3e2014-01-15 19:33:25 -0800111 , m_policy(policy)
112 , m_verifier(new Verifier(policy))
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800113 , m_keyChain(new KeyChain())
Yingdi Yu6e235db2013-12-27 08:40:53 +0800114 , m_face(face)
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700115#ifndef NS3_MODULE
116 , m_randomGenerator (static_cast<unsigned int> (std::time (0)))
117 , m_rangeUniformRandom (m_randomGenerator, uniform_int<> (200,1000))
118 , m_reexpressionJitter (m_randomGenerator, uniform_int<> (100,500))
119#else
120 , m_rangeUniformRandom (200,1000)
121 , m_reexpressionJitter (10,500)
122#endif
Alexander Afanasyevce001692013-07-14 11:34:41 -0700123 , m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700124{
125#ifndef NS3_MODULE
126 // In NS3 module these functions are moved to StartApplication method
127
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800128 m_syncRegisteredPrefixId = m_face->setInterestFilter(m_syncPrefix,
129 func_lib::bind(&SyncLogic::onSyncInterest, this, _1, _2, _3, _4),
130 func_lib::bind(&SyncLogic::onSyncRegisterFailed, this, _1));
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700131
132 m_scheduler.schedule (TIME_SECONDS (0), // no need to add jitter
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800133 func_lib::bind (&SyncLogic::sendSyncInterest, this),
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700134 REEXPRESSING_INTEREST);
135#endif
136}
137
Alexander Afanasyevc1030192012-03-08 22:21:28 -0800138SyncLogic::~SyncLogic ()
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800139{
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800140 m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800141}
142
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700143#ifdef NS3_MODULE
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700144void
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700145SyncLogic::StartApplication ()
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700146{
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700147 m_ccnxHandle->SetNode (GetNode ());
148 m_ccnxHandle->StartApplication ();
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700149
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700150 m_ccnxHandle->setInterestFilter (m_syncPrefix,
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800151 func_lib::bind (&SyncLogic::respondSyncInterest, this, _1));
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700152
Alexander Afanasyev983b0e92012-04-26 12:44:18 -0700153 m_scheduler.schedule (TIME_SECONDS (0), // need to send first interests at exactly the same time
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800154 func_lib::bind (&SyncLogic::sendSyncInterest, this),
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700155 REEXPRESSING_INTEREST);
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700156}
157
158void
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700159SyncLogic::StopApplication ()
160{
Alexander Afanasyev434f1612012-04-21 21:19:15 -0700161 m_ccnxHandle->clearInterestFilter (m_syncPrefix);
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700162 m_ccnxHandle->StopApplication ();
Alexander Afanasyev40942f42012-04-21 20:53:16 -0700163 m_scheduler.cancel (REEXPRESSING_INTEREST);
164 m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
Alexander Afanasyevb550d6a2012-04-09 15:03:16 -0700165}
166#endif
167
Zhenkai Zhueb1d8652012-12-23 15:25:39 -0800168void
169SyncLogic::stop()
170{
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800171 m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
Zhenkai Zhueb1d8652012-12-23 15:25:39 -0800172 m_scheduler.cancel (REEXPRESSING_INTEREST);
173 m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
174}
175
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700176/**
177 * Two types of intersts
178 *
179 * Normal name: .../<hash>
180 * Recovery name: .../recovery/<hash>
181 */
182boost::tuple<DigestConstPtr, std::string>
Yingdi Yu6d638f02014-01-24 11:01:21 -0800183SyncLogic::convertNameToDigestAndType (const Name &name)
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700184{
Yingdi Yu6d638f02014-01-24 11:01:21 -0800185 BOOST_ASSERT (m_syncPrefix.isPrefixOf(name));
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700186
Yingdi Yu6d638f02014-01-24 11:01:21 -0800187 int nameLengthDiff = name.size() - m_syncPrefix.size();
188 BOOST_ASSERT (nameLengthDiff > 0);
189 BOOST_ASSERT (nameLengthDiff < 3);
190
191 string hash = name.get(-1).toEscapedString();
192 string interestType;
193
194 if(nameLengthDiff == 1)
195 interestType = "normal";
196 else
197 interestType = name.get(-2).toEscapedString();
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700198
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700199 _LOG_TRACE (hash << ", " << interestType);
200
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800201 DigestPtr digest = boost::make_shared<Digest> ();
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700202 istringstream is (hash);
203 is >> *digest;
204
205 return make_tuple (digest, interestType);
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700206}
207
208void
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800209SyncLogic::onSyncInterest (const shared_ptr<const Name>& prefix,
210 const shared_ptr<const ndn::Interest>& interest,
211 Transport& transport,
212 uint64_t registeredPrefixId)
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700213{
Yingdi Yu6d638f02014-01-24 11:01:21 -0800214 Name name = interest->getName();
215
216 _LOG_DEBUG("respondSyncInterest: " << name);
217
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700218 try
219 {
220 _LOG_TRACE ("<< I " << name);
221
222 DigestConstPtr digest;
223 string type;
224 tie (digest, type) = convertNameToDigestAndType (name);
225
226 if (type == "normal") // kind of ineffective...
227 {
228 processSyncInterest (name, digest);
229 }
230 else if (type == "recovery")
231 {
232 processSyncRecoveryInterest (name, digest);
233 }
234 }
235 catch (Error::DigestCalculationError &e)
236 {
237 _LOG_TRACE ("Something fishy happened...");
238 // log error. ignoring it for now, later we should log it
239 return ;
240 }
241}
242
243void
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800244SyncLogic::onSyncRegisterFailed(const shared_ptr<const Name>& prefix)
245{
246 _LOG_DEBUG("Sync prefix registration failed!");
247}
248
249void
250SyncLogic::onSyncData(const shared_ptr<const ndn::Interest>& interest,
251 const shared_ptr<Data>& data,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800252 const OnVerified& onVerified,
253 const OnVerifyFailed& onVerifyFailed)
254{
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800255 m_verifier->verifyData(data, onVerified, onVerifyFailed);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800256}
257
258void
259SyncLogic::onSyncDataTimeout(const shared_ptr<const ndn::Interest>& interest,
260 int retry,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800261 const OnVerified& onVerified,
262 const OnVerifyFailed& onVerifyFailed)
263{
264 if(retry > 0)
265 {
266 m_face->expressInterest(*interest,
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800267 func_lib::bind(&SyncLogic::onSyncData,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800268 this,
269 _1,
270 _2,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800271 onVerified,
272 onVerifyFailed),
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800273 func_lib::bind(&SyncLogic::onSyncDataTimeout,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800274 this,
275 _1,
276 retry - 1,
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800277 onVerified,
278 onVerifyFailed));
279 }
280 else
281 _LOG_DEBUG("Sync interest eventually times out!");
282}
283
284void
285SyncLogic::onSyncDataVerifyFailed(const shared_ptr<Data>& data)
286{
287 _LOG_DEBUG("Sync data cannot be verified!");
288}
289
290void
291SyncLogic::onSyncDataVerified(const shared_ptr<Data>& data)
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700292{
Yingdi Yu6d638f02014-01-24 11:01:21 -0800293 Name name = data->getName();
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800294 const char* wireData = (const char*)data->getContent().value();
295 size_t len = data->getContent().value_size();
Yingdi Yu43e71612013-10-30 22:19:31 -0700296
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700297 try
298 {
299 _LOG_TRACE ("<< D " << name);
300
301 DigestConstPtr digest;
302 string type;
303 tie (digest, type) = convertNameToDigestAndType (name);
304
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700305 if (type == "normal")
306 {
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700307 processSyncData (name, digest, wireData, len);
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700308 }
309 else
310 {
Alexander Afanasyeva76010b2012-05-24 21:31:49 -0700311 // timer is always restarted when we schedule recovery
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700312 m_scheduler.cancel (REEXPRESSING_RECOVERY_INTEREST);
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700313 processSyncData (name, digest, wireData, len);
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700314 }
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700315 }
316 catch (Error::DigestCalculationError &e)
317 {
318 _LOG_TRACE ("Something fishy happened...");
319 // log error. ignoring it for now, later we should log it
320 return;
321 }
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700322}
323
Yingdi Yu43e71612013-10-30 22:19:31 -0700324void
Yingdi Yu6d638f02014-01-24 11:01:21 -0800325SyncLogic::processSyncInterest (const Name &name, DigestConstPtr digest, bool timedProcessing/*=false*/)
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700326{
Yingdi Yu43e71612013-10-30 22:19:31 -0700327 _LOG_DEBUG("processSyncInterest");
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700328 DigestConstPtr rootDigest;
329 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800330 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700331 rootDigest = m_state->getDigest();
332 }
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700333
Alexander Afanasyevdd0eba72012-03-13 13:57:10 -0700334 // Special case when state is not empty and we have received request with zero-root digest
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700335 if (digest->isZero () && !rootDigest->isZero ())
Alexander Afanasyevdd0eba72012-03-13 13:57:10 -0700336 {
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700337
338 SyncStateMsg ssm;
339 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800340 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700341 ssm << (*m_state);
342 }
343 sendSyncData (name, digest, ssm);
Alexander Afanasyevdd0eba72012-03-13 13:57:10 -0700344 return;
345 }
Alexander Afanasyev763855a2012-03-13 14:17:37 -0700346
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700347 if (*rootDigest == *digest)
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -0700348 {
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700349 _LOG_TRACE ("processSyncInterest (): Same state. Adding to PIT");
Yingdi Yu6d638f02014-01-24 11:01:21 -0800350 m_syncInterestTable.insert (digest, name.toUri(), false);
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -0700351 return;
352 }
Alexander Afanasyevdd0eba72012-03-13 13:57:10 -0700353
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700354 DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
355
356 if (stateInDiffLog != m_log.end ())
357 {
Alexander Afanasyev235c6d72012-03-15 22:28:43 -0700358 DiffStateConstPtr stateDiff = (*stateInDiffLog)->diff ();
Alexander Afanasyev235c6d72012-03-15 22:28:43 -0700359
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700360 sendSyncData (name, digest, stateDiff);
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700361 return;
362 }
363
364 if (!timedProcessing)
365 {
Yingdi Yu6d638f02014-01-24 11:01:21 -0800366 bool exists = m_syncInterestTable.insert (digest, name.toUri(), true);
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700367 if (exists) // somebody else replied, so restart random-game timer
Alexander Afanasyev3a229132012-04-25 15:07:26 -0700368 {
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700369 _LOG_DEBUG ("Unknown digest, but somebody may have already replied, so restart our timer");
370 m_scheduler.cancel (DELAYED_INTEREST_PROCESSING);
Alexander Afanasyev3a229132012-04-25 15:07:26 -0700371 }
Alexander Afanasyev03793b42012-05-01 13:03:07 -0700372
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700373 uint32_t waitDelay = GET_RANDOM (m_rangeUniformRandom);
374 _LOG_DEBUG ("Digest is not in the log. Schedule processing after small delay: " << waitDelay << "ms");
Alexander Afanasyev983b0e92012-04-26 12:44:18 -0700375
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700376 m_scheduler.schedule (TIME_MILLISECONDS (waitDelay),
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800377 func_lib::bind (&SyncLogic::processSyncInterest, this, name, digest, true),
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700378 DELAYED_INTEREST_PROCESSING);
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700379 }
380 else
381 {
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700382 _LOG_TRACE (" (timed processing)");
Alexander Afanasyeva76010b2012-05-24 21:31:49 -0700383
384 m_recoveryRetransmissionInterval = m_defaultRecoveryRetransmitInterval;
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700385 sendSyncRecoveryInterests (digest);
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700386 }
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800387}
388
Alexander Afanasyevc1030192012-03-08 22:21:28 -0800389void
Yingdi Yu6d638f02014-01-24 11:01:21 -0800390SyncLogic::processSyncData (const Name &name, DigestConstPtr digest, const char *wireData, size_t len)
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800391{
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800392 DiffStatePtr diffLog = boost::make_shared<DiffState> ();
Alexander Afanasyev2b6fbfb2012-05-24 10:57:14 -0700393 bool ownInterestSatisfied = false;
Alexander Afanasyeve4e2bf72012-03-12 12:44:54 -0700394
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700395 try
396 {
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700397
Yingdi Yu6d638f02014-01-24 11:01:21 -0800398 m_syncInterestTable.remove (name.toUri()); // Remove satisfied interest from PIT
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700399
Alexander Afanasyev2b6fbfb2012-05-24 10:57:14 -0700400 ownInterestSatisfied = (name == m_outstandingInterestName);
401
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700402 DiffState diff;
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700403 SyncStateMsg msg;
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -0700404 if (!msg.ParseFromArray(wireData, len) || !msg.IsInitialized())
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700405 {
406 //Throw
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -0700407 BOOST_THROW_EXCEPTION (Error::SyncStateMsgDecodingFailure () );
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700408 }
409 msg >> diff;
410
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700411 vector<MissingDataInfo> v;
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700412 BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
Alexander Afanasyev04fd8a82012-03-12 15:40:48 -0700413 {
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700414 DiffLeafConstPtr diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
415 BOOST_ASSERT (diffLeaf != 0);
416
417 NameInfoConstPtr info = diffLeaf->getInfo();
Zhenkai Zhuba3c1d12012-10-03 23:26:35 -0700418 if (diffLeaf->getOperation() == UPDATE)
Alexander Afanasyev04fd8a82012-03-12 15:40:48 -0700419 {
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700420 SeqNo seq = diffLeaf->getSeq();
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700421
422 bool inserted = false;
423 bool updated = false;
424 SeqNo oldSeq;
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700425 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800426 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700427 tie (inserted, updated, oldSeq) = m_state->update (info, seq);
428 }
Chaoyi Bian89ee2dc2012-03-09 14:06:01 -0800429
Alexander Afanasyevd4adce52012-03-13 13:59:39 -0700430 if (inserted || updated)
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700431 {
432 diffLog->update (info, seq);
Zhenkai Zhu68f04d52012-06-05 14:07:41 -0700433 if (!oldSeq.isValid())
434 {
435 oldSeq = SeqNo(seq.getSession(), 0);
436 }
437 else
438 {
439 ++oldSeq;
440 }
Zhenkai Zhuba3c1d12012-10-03 23:26:35 -0700441 // there is no need for application to process update on forwarder node
442 if (info->toString() != forwarderPrefix)
443 {
444 MissingDataInfo mdi = {info->toString(), oldSeq, seq};
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700445 if (m_perBranch)
446 {
447 ostringstream interestName;
448 interestName << mdi.prefix << "/" << mdi.high.getSession() << "/" << mdi.high.getSeq();
449 m_onUpdateBranch(interestName.str());
450 }
451 else
452 {
453 v.push_back(mdi);
454 }
Zhenkai Zhuba3c1d12012-10-03 23:26:35 -0700455 }
Alexander Afanasyev04fd8a82012-03-12 15:40:48 -0700456 }
457 }
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700458 else if (diffLeaf->getOperation() == REMOVE)
Alexander Afanasyev04fd8a82012-03-12 15:40:48 -0700459 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800460 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700461 if (m_state->remove (info))
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700462 {
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700463 diffLog->remove (info);
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700464 if (!m_perBranch)
465 {
466 m_onRemove (info->toString ());
467 }
Alexander Afanasyev04fd8a82012-03-12 15:40:48 -0700468 }
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700469 }
470 else
471 {
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700472 }
473 }
474
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700475 if (!v.empty())
476 {
Zhenkai Zhub9f19592012-10-16 14:27:38 -0700477 if (!m_perBranch)
478 {
479 m_onUpdate(v);
480 }
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700481 }
482
Alexander Afanasyev235c6d72012-03-15 22:28:43 -0700483 insertToDiffLog (diffLog);
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700484 }
Zhenkai Zhu97e36bd2012-06-06 13:55:03 -0700485 catch (Error::SyncStateMsgDecodingFailure &e)
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700486 {
Alexander Afanasyev282a10b2012-05-09 12:56:38 -0700487 _LOG_TRACE ("Something really fishy happened during state decoding " <<
488 diagnostic_information (e));
Alexander Afanasyevd4cca472012-03-13 14:25:46 -0700489 diffLog.reset ();
490 // don't do anything
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700491 }
492
Alexander Afanasyev2b6fbfb2012-05-24 10:57:14 -0700493 if ((diffLog != 0 && diffLog->getLeaves ().size () > 0) ||
494 ownInterestSatisfied)
Alexander Afanasyev750d1872012-03-12 15:33:56 -0700495 {
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700496 // Do it only if everything went fine and state changed
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700497
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700498 // this is kind of wrong
499 // satisfyPendingSyncInterests (diffLog); // if there are interests in PIT, there is a point to satisfy them using new state
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700500
Alexander Afanasyev282a10b2012-05-09 12:56:38 -0700501 // if state has changed, then it is safe to express a new interest
Alexander Afanasyevd4cca472012-03-13 14:25:46 -0700502 m_scheduler.cancel (REEXPRESSING_INTEREST);
Alexander Afanasyev282a10b2012-05-09 12:56:38 -0700503 m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (0),
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800504 func_lib::bind (&SyncLogic::sendSyncInterest, this),
Alexander Afanasyevd4cca472012-03-13 14:25:46 -0700505 REEXPRESSING_INTEREST);
Alexander Afanasyev04fd8a82012-03-12 15:40:48 -0700506 }
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800507}
508
Alexander Afanasyevc1030192012-03-08 22:21:28 -0800509void
Yingdi Yu6d638f02014-01-24 11:01:21 -0800510SyncLogic::processSyncRecoveryInterest (const Name &name, DigestConstPtr digest)
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800511{
Yingdi Yu43e71612013-10-30 22:19:31 -0700512 _LOG_DEBUG("processSyncRecoveryInterest");
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700513 DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
514
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700515 if (stateInDiffLog == m_log.end ())
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700516 {
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700517 _LOG_TRACE ("Could not find " << *digest << " in digest log");
518 return;
519 }
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700520
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700521 SyncStateMsg ssm;
522 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800523 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700524 ssm << (*m_state);
525 }
526 sendSyncData (name, digest, ssm);
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700527}
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700528
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700529void
530SyncLogic::satisfyPendingSyncInterests (DiffStateConstPtr diffLog)
531{
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800532 DiffStatePtr fullStateLog = boost::make_shared<DiffState> ();
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700533 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800534 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700535 BOOST_FOREACH (LeafConstPtr leaf, m_state->getLeaves ()/*.get<timed> ()*/)
536 {
537 fullStateLog->update (leaf->getInfo (), leaf->getSeq ());
538 /// @todo Impose limit on how many state info should be send out
539 }
540 }
541
542 try
Alexander Afanasyevc1030192012-03-08 22:21:28 -0800543 {
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700544 uint32_t counter = 0;
545 while (m_syncInterestTable.size () > 0)
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700546 {
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800547 Sync::Interest interest = m_syncInterestTable.pop ();
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700548
549 if (!interest.m_unknown)
550 {
551 _LOG_TRACE (">> D " << interest.m_name);
552 sendSyncData (interest.m_name, interest.m_digest, diffLog);
553 }
554 else
555 {
556 _LOG_TRACE (">> D (unknown)" << interest.m_name);
557 sendSyncData (interest.m_name, interest.m_digest, fullStateLog);
558 }
559 counter ++;
Alexander Afanasyevf07ab352012-03-13 12:57:46 -0700560 }
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700561 _LOG_DEBUG ("Satisfied " << counter << " pending interests");
Alexander Afanasyevf07ab352012-03-13 12:57:46 -0700562 }
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700563 catch (Error::InterestTableIsEmpty &e)
564 {
565 // ok. not really an error
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800566 }
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800567}
568
Alexander Afanasyevc1030192012-03-08 22:21:28 -0800569void
Alexander Afanasyev235c6d72012-03-15 22:28:43 -0700570SyncLogic::insertToDiffLog (DiffStatePtr diffLog)
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700571{
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700572 diffLog->setDigest (m_state->getDigest());
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700573 if (m_log.size () > 0)
574 {
575 m_log.get<sequenced> ().front ()->setNext (diffLog);
576 }
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700577 m_log.erase (m_state->getDigest()); // remove diff state with the same digest. next pointers are still valid
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700578 /// @todo Optimization
Alexander Afanasyev7df73332012-03-15 12:31:49 -0700579 m_log.get<sequenced> ().push_front (diffLog);
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700580}
581
582void
Yingdi Yu6d638f02014-01-24 11:01:21 -0800583SyncLogic::addLocalNames (const Name &prefix, uint32_t session, uint32_t seq)
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700584{
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700585 DiffStatePtr diff;
586 {
587 //cout << "Add local names" <<endl;
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800588 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Yingdi Yu6d638f02014-01-24 11:01:21 -0800589 NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700590
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700591 _LOG_DEBUG ("addLocalNames (): old state " << *m_state->getDigest ());
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700592
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700593 SeqNo seqN (session, seq);
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700594 m_state->update(info, seqN);
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700595
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700596 _LOG_DEBUG ("addLocalNames (): new state " << *m_state->getDigest ());
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700597
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800598 diff = boost::make_shared<DiffState>();
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700599 diff->update(info, seqN);
Alexander Afanasyev235c6d72012-03-15 22:28:43 -0700600 insertToDiffLog (diff);
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700601 }
602
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700603 // _LOG_DEBUG ("PIT size: " << m_syncInterestTable.size ());
604 satisfyPendingSyncInterests (diff);
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700605}
606
607void
Yingdi Yu6d638f02014-01-24 11:01:21 -0800608SyncLogic::remove(const Name &prefix)
Alexander Afanasyevd91497c2012-03-12 15:39:30 -0700609{
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700610 DiffStatePtr diff;
611 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800612 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Yingdi Yu6d638f02014-01-24 11:01:21 -0800613 NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700614 m_state->remove(info);
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700615
Zhenkai Zhua2e0b082012-09-26 10:34:15 -0700616 // increment the sequence number for the forwarder node
617 NameInfoConstPtr forwarderInfo = StdNameInfo::FindOrCreate(forwarderPrefix);
Zhenkai Zhua2e0b082012-09-26 10:34:15 -0700618
Alexander Afanasyev7e1986f2012-10-04 10:21:10 -0700619 LeafContainer::iterator item = m_state->getLeaves ().find (forwarderInfo);
620 SeqNo seqNo (0);
621 if (item != m_state->getLeaves ().end ())
622 {
623 seqNo = (*item)->getSeq ();
624 ++seqNo;
625 }
626 m_state->update (forwarderInfo, seqNo);
Zhenkai Zhua2e0b082012-09-26 10:34:15 -0700627
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800628 diff = boost::make_shared<DiffState>();
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700629 diff->remove(info);
Alexander Afanasyev7e1986f2012-10-04 10:21:10 -0700630 diff->update(forwarderInfo, seqNo);
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700631
Alexander Afanasyev235c6d72012-03-15 22:28:43 -0700632 insertToDiffLog (diff);
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700633 }
634
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700635 satisfyPendingSyncInterests (diff);
Zhenkai Zhu0efa37b2012-03-12 13:54:12 -0700636}
637
638void
Alexander Afanasyevc1030192012-03-08 22:21:28 -0800639SyncLogic::sendSyncInterest ()
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800640{
Yingdi Yu43e71612013-10-30 22:19:31 -0700641 _LOG_DEBUG("sendSyncInterest");
Chaoyi Bian89ee2dc2012-03-09 14:06:01 -0800642
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700643 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800644 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Yingdi Yu6d638f02014-01-24 11:01:21 -0800645 m_outstandingInterestName = m_syncPrefix;
646 ostringstream os;
647 os << *m_state->getDigest();
648 m_outstandingInterestName.append(os.str());
649 _LOG_TRACE (">> I " << m_outstandingInterestName);
Alexander Afanasyev860e6fe2012-03-15 17:30:31 -0700650 }
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700651
Yingdi Yu6d638f02014-01-24 11:01:21 -0800652 _LOG_DEBUG("sendSyncInterest: " << m_outstandingInterestName);
Yingdi Yu43e71612013-10-30 22:19:31 -0700653
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700654 m_scheduler.cancel (REEXPRESSING_INTEREST);
Alexander Afanasyev983b0e92012-04-26 12:44:18 -0700655 m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (m_syncInterestReexpress),
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800656 func_lib::bind (&SyncLogic::sendSyncInterest, this),
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700657 REEXPRESSING_INTEREST);
Yingdi Yu43e71612013-10-30 22:19:31 -0700658
Yingdi Yu6d638f02014-01-24 11:01:21 -0800659 ndn::Interest interest(m_outstandingInterestName);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800660
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800661 OnVerified onVerified = func_lib::bind(&SyncLogic::onSyncDataVerified, this, _1);
662 OnVerifyFailed onVerifyFailed = func_lib::bind(&SyncLogic::onSyncDataVerifyFailed, this, _1);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800663
Yingdi Yu6d638f02014-01-24 11:01:21 -0800664 m_face->expressInterest(interest,
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800665 func_lib::bind(&SyncLogic::onSyncData, this, _1, _2, onVerified, onVerifyFailed),
Yingdi Yu6d638f02014-01-24 11:01:21 -0800666 func_lib::bind(&SyncLogic::onSyncDataTimeout, this, _1, 0, onVerified, onVerifyFailed));
Chaoyi Bian44fff0c2012-03-07 21:07:22 -0800667}
668
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700669void
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700670SyncLogic::sendSyncRecoveryInterests (DigestConstPtr digest)
671{
672 ostringstream os;
Yingdi Yu6d638f02014-01-24 11:01:21 -0800673 os << *digest;
674
675 Name interestName = m_syncPrefix;
676 interestName.append("recovery").append(os.str());
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700677
Alexander Afanasyeva76010b2012-05-24 21:31:49 -0700678 TimeDuration nextRetransmission = TIME_MILLISECONDS_WITH_JITTER (m_recoveryRetransmissionInterval);
679 m_recoveryRetransmissionInterval <<= 1;
680
681 m_scheduler.cancel (REEXPRESSING_RECOVERY_INTEREST);
682 if (m_recoveryRetransmissionInterval < 100*1000) // <100 seconds
683 {
684 m_scheduler.schedule (nextRetransmission,
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800685 func_lib::bind (&SyncLogic::sendSyncRecoveryInterests, this, digest),
Alexander Afanasyeva76010b2012-05-24 21:31:49 -0700686 REEXPRESSING_RECOVERY_INTEREST);
687 }
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700688
Yingdi Yu6d638f02014-01-24 11:01:21 -0800689 ndn::Interest interest(interestName);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800690
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800691 OnVerified onVerified = func_lib::bind(&SyncLogic::onSyncDataVerified, this, _1);
692 OnVerifyFailed onVerifyFailed = func_lib::bind(&SyncLogic::onSyncDataVerifyFailed, this, _1);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800693
Yingdi Yu6d638f02014-01-24 11:01:21 -0800694 m_face->expressInterest(interest,
Yingdi Yu0cb0f2b2014-01-09 13:51:16 -0800695 func_lib::bind(&SyncLogic::onSyncData, this, _1, _2, onVerified, onVerifyFailed),
Yingdi Yu6d638f02014-01-24 11:01:21 -0800696 func_lib::bind(&SyncLogic::onSyncDataTimeout, this, _1, 0, onVerified, onVerifyFailed));
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700697}
698
699
700void
Yingdi Yu6d638f02014-01-24 11:01:21 -0800701SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, StateConstPtr state)
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700702{
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700703 SyncStateMsg msg;
704 msg << (*state);
705 sendSyncData(name, digest, msg);
706}
707
708// pass in state msg instead of state, so that there is no need to lock the state until
709// this function returns
710void
Yingdi Yu6d638f02014-01-24 11:01:21 -0800711SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, SyncStateMsg &ssm)
Zhenkai Zhu2d3e2702012-10-15 14:18:05 -0700712{
Alexander Afanasyev46eb5262012-05-10 16:30:35 -0700713 _LOG_TRACE (">> D " << name);
Zhenkai Zhu3cfdcb92012-06-06 15:20:10 -0700714 int size = ssm.ByteSize();
715 char *wireData = new char[size];
Yingdi Yu6d638f02014-01-24 11:01:21 -0800716 Name signingIdentity = m_policy->inferSigningIdentity(name);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800717
Yingdi Yu6d638f02014-01-24 11:01:21 -0800718 Data syncData(name);
719 syncData.setContent(reinterpret_cast<const uint8_t*>(wireData), size);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800720
Yingdi Yu6d638f02014-01-24 11:01:21 -0800721 m_keyChain->signByIdentity(syncData, signingIdentity);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800722
Yingdi Yu6d638f02014-01-24 11:01:21 -0800723 m_face->put(syncData);
Yingdi Yu46c9f1a2013-12-18 15:15:46 +0800724
Chaoyi Bian6665d5a2012-06-07 14:16:44 -0700725 delete []wireData;
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700726
Alexander Afanasyev282a10b2012-05-09 12:56:38 -0700727 // checking if our own interest got satisfied
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700728 bool satisfiedOwnInterest = false;
729 {
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800730 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700731 satisfiedOwnInterest = (m_outstandingInterestName == name);
732 }
733
734 if (satisfiedOwnInterest)
735 {
736 _LOG_TRACE ("Satisfied our own Interest. Re-expressing (hopefully with a new digest)");
737
738 m_scheduler.cancel (REEXPRESSING_INTEREST);
739 m_scheduler.schedule (TIME_SECONDS_WITH_JITTER (0),
740 bind (&SyncLogic::sendSyncInterest, this),
741 REEXPRESSING_INTEREST);
742 }
743}
744
Zhenkai Zhue5660932012-06-04 15:25:20 -0700745string
746SyncLogic::getRootDigest()
747{
748 ostringstream os;
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800749 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Zhenkai Zhue5660932012-06-04 15:25:20 -0700750 os << *m_state->getDigest();
751 return os.str();
752}
753
Alexander Afanasyev80237382012-10-04 10:20:47 -0700754size_t
755SyncLogic::getNumberOfBranches () const
756{
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800757 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Alexander Afanasyev80237382012-10-04 10:20:47 -0700758 return m_state->getLeaves ().size ();
759}
760
Alexander Afanasyev5548c042012-10-04 19:10:09 -0700761void
762SyncLogic::printState () const
763{
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800764 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Alexander Afanasyev5548c042012-10-04 19:10:09 -0700765
766 BOOST_FOREACH (const boost::shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
767 {
768 std::cout << *leaf << std::endl;
769 }
770}
771
Zhenkai Zhud5aec4b2012-10-09 12:01:19 -0700772std::map<std::string, bool>
773SyncLogic::getBranchPrefixes() const
774{
Alexander Afanasyevd95c2312013-11-07 13:45:34 -0800775 boost::recursive_mutex::scoped_lock lock (m_stateMutex);
Zhenkai Zhud5aec4b2012-10-09 12:01:19 -0700776
777 std::map<std::string, bool> m;
778
779 BOOST_FOREACH (const boost::shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
780 {
781 std::string prefix = leaf->getInfo()->toString();
782 // do not return forwarder prefix
783 if (prefix != forwarderPrefix)
784 {
785 m.insert(pair<std::string, bool>(prefix, false));
786 }
787 }
788
789 return m;
790}
Alexander Afanasyevf3c03a92012-05-09 12:00:37 -0700791
Alexander Afanasyevc1030192012-03-08 22:21:28 -0800792}