make chronosync a dependency
refs: #2400 Change-Id: I8b488f165a4f9a2c9a7731931be3b6d2e3c43c89
This commit is contained in:
1 parent
c780a6986b
commit
415676b6cc
59 files changed
+165
-5533
No files matched your search
@@ -9,8 +9,8 @@ if has OSX $NODE_LABELS && ! has OSX-10.8-c++11-64bit $NODE_LABELS; then
|
||||
set -x
|
||||
brew update
|
||||
brew upgrade
|
||||
brew install boost pkg-config sqlite cryptopp log4cxx protobuf openssl
|
||||
brew link --force openssl log4cxx protobuf
|
||||
brew install boost pkg-config sqlite cryptopp log4cxx openssl
|
||||
brew link --force openssl log4cxx
|
||||
brew cleanup
|
||||
fi
|
||||
|
||||
@@ -24,5 +24,5 @@ if has Ubuntu $NODE_LABELS; then
|
||||
sudo apt-get update -qq -y
|
||||
sudo apt-get -qq -y install build-essential pkg-config $BOOST_PKG \
|
||||
libcrypto++-dev libsqlite3-dev \
|
||||
liblog4cxx10-dev protobuf-compiler libprotobuf-dev libssl-dev
|
||||
liblog4cxx10-dev libssl-dev
|
||||
fi
|
||||
@@ -49,6 +49,6 @@ popd >/dev/null
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
sudo ldconfig
|
||||
elif has FreeBSD $NODE_LABELS; then
|
||||
sudo ldconfig -a
|
||||
elif has FreeBSD10 $NODE_LABELS; then
|
||||
sudo ldconfig -m
|
||||
fi
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
pushd /tmp >/dev/null
|
||||
|
||||
INSTALLED_VERSION=
|
||||
if has OSX $NODE_LABELS; then
|
||||
BOOST=$(brew ls --versions boost)
|
||||
OLD_BOOST=$(cat boost_chrono.txt || :)
|
||||
if [[ $OLD_BOOST != $BOOST ]]; then
|
||||
echo "$BOOST" > boost_chrono.txt
|
||||
INSTALLED_VERSION=NONE
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z $INSTALLED_VERSION ]]; then
|
||||
INSTALLED_VERSION=$((cd ChronoSync && git rev-parse HEAD) 2>/dev/null || echo NONE)
|
||||
fi
|
||||
|
||||
sudo rm -Rf ChronoSync-latest
|
||||
|
||||
git clone --depth 1 git://github.com/named-data/ChronoSync ChronoSync-latest
|
||||
|
||||
LATEST_VERSION=$((cd ChronoSync-latest && git rev-parse HEAD) 2>/dev/null || echo UNKNOWN)
|
||||
|
||||
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
|
||||
sudo rm -Rf ChronoSync
|
||||
mv ChronoSync-latest ChronoSync
|
||||
else
|
||||
sudo rm -Rf ChronoSync-latest
|
||||
fi
|
||||
|
||||
sudo rm -Rf /usr/local/include/ChronoSync
|
||||
sudo rm -f /usr/local/lib/libChronoSync*
|
||||
sudo rm -f /usr/local/lib/pkgconfig/ChronoSync*
|
||||
|
||||
pushd ChronoSync >/dev/null
|
||||
|
||||
if has FreeBSD10 $NODE_LABELS; then
|
||||
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
|
||||
fi
|
||||
|
||||
./waf -j1 --color=yes configure
|
||||
./waf -j1 --color=yes build
|
||||
sudo ./waf install -j1 --color=yes
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
sudo ldconfig
|
||||
elif has FreeBSD10 $NODE_LABELS; then
|
||||
sudo ldconfig -m
|
||||
fi
|
||||
@@ -1,47 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
'''
|
||||
|
||||
When using this tool, the wscript will look like:
|
||||
|
||||
def options(opt):
|
||||
opt.tool_options('openssl')
|
||||
|
||||
def configure(conf):
|
||||
conf.load('compiler_cxx openssl')
|
||||
conf.check_openssl()
|
||||
|
||||
def build(bld):
|
||||
bld(source='main.cpp', target='app', use='OPENSSL')
|
||||
|
||||
'''
|
||||
|
||||
from waflib import Options
|
||||
from waflib.Configure import conf
|
||||
|
||||
@conf
|
||||
def check_openssl(self,*k,**kw):
|
||||
root = k and k[0] or kw.get('path', None) or Options.options.with_openssl
|
||||
mandatory = kw.get('mandatory', True)
|
||||
var = kw.get('uselib_store', 'OPENSSL')
|
||||
|
||||
if root:
|
||||
libcrypto = self.check_cxx(lib=['ssl', 'crypto'],
|
||||
msg='Checking for OpenSSL library',
|
||||
define_name='HAVE_%s' % var,
|
||||
global_define=True,
|
||||
uselib_store=var,
|
||||
mandatory=mandatory,
|
||||
includes="%s/include" % root,
|
||||
libpath="%s/lib" % root)
|
||||
else:
|
||||
libcrypto = self.check_cxx(lib=['ssl', 'crypto'],
|
||||
msg='Checking for OpenSSL library',
|
||||
define_name='HAVE_%s' % var,
|
||||
uselib_store=var,
|
||||
mandatory=mandatory)
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--with-openssl', type='string', default=None,
|
||||
dest='with_openssl', help='''Path to OpenSSL''')
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# Philipp Bender, 2012
|
||||
# Matt Clarkson, 2012
|
||||
|
||||
from waflib.Task import Task
|
||||
from waflib.TaskGen import extension
|
||||
|
||||
"""
|
||||
A simple tool to integrate protocol buffers into your build system.
|
||||
|
||||
def configure(conf):
|
||||
conf.load('compiler_cxx cxx protoc')
|
||||
|
||||
def build(bld):
|
||||
bld(
|
||||
features = 'cxx cxxprogram'
|
||||
source = 'main.cpp file1.proto proto/file2.proto',
|
||||
include = '. proto',
|
||||
target = 'executable')
|
||||
|
||||
"""
|
||||
|
||||
class protoc(Task):
|
||||
run_str = '${PROTOC} ${PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${SRC[0].abspath()}'
|
||||
color = 'BLUE'
|
||||
ext_out = ['.h', 'pb.cc']
|
||||
|
||||
@extension('.proto')
|
||||
def process_protoc(self, node):
|
||||
cpp_node = node.change_ext('.pb.cc')
|
||||
hpp_node = node.change_ext('.pb.h')
|
||||
self.create_task('protoc', node, [cpp_node, hpp_node])
|
||||
self.source.append(cpp_node)
|
||||
|
||||
if 'cxx' in self.features and not self.env.PROTOC_FLAGS:
|
||||
self.env.PROTOC_FLAGS = '--cpp_out=%s' % node.parent.get_bld().abspath()
|
||||
|
||||
use = getattr(self, 'use', '')
|
||||
if not 'PROTOBUF' in use:
|
||||
self.use = self.to_list(use) + ['PROTOBUF']
|
||||
|
||||
def configure(conf):
|
||||
conf.check_cfg(package="protobuf", uselib_store="PROTOBUF", args=['--cflags', '--libs'])
|
||||
conf.find_program('protoc', var='PROTOC')
|
||||
conf.env.PROTOC_ST = '-I%s'
|
||||
|
||||
+6
-28
@@ -12,6 +12,12 @@ Prerequisites
|
||||
Refer to `Getting started with NFD <http://named-data.net/doc/NFD/current/INSTALL.html>`_
|
||||
for detailed installation and running instruction.
|
||||
|
||||
- ChronoSync library
|
||||
|
||||
::
|
||||
|
||||
https://github.com/named-data/ChronoSync#build
|
||||
|
||||
- log4cxx library
|
||||
|
||||
On Ubuntu Linux:
|
||||
@@ -26,34 +32,6 @@ for detailed installation and running instruction.
|
||||
|
||||
sudo port install log4cxx
|
||||
|
||||
- protobuf
|
||||
|
||||
On Ubuntu Linux:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install libprotobuf-dev protobuf-compiler
|
||||
|
||||
On OS X with MacPorts:
|
||||
|
||||
::
|
||||
|
||||
sudo port install protobuf-cpp
|
||||
|
||||
- openssl
|
||||
|
||||
On Ubuntu Linux:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install libssl-dev
|
||||
|
||||
On OS X with MacPorts:
|
||||
|
||||
::
|
||||
|
||||
sudo port install openssl
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
nsync is a copy of ChronoSync (https://github.com/bruinfish/ChronoSync/tree/master).
|
||||
|
||||
ChonoSync's license is GPL2.
|
||||
@@ -1,15 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* See COPYING.md for copyright and distribution information.
|
||||
*/
|
||||
|
||||
// suppress Boost::archive warnings
|
||||
#pragma GCC system_header
|
||||
#pragma clang system_header
|
||||
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/archive/iterators/dataflow_exception.hpp>
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef NLSR_NSYNC_OPENSSL_H
|
||||
#define NLSR_NSYNC_OPENSSL_H
|
||||
|
||||
// suppress deprecation warnings in OSX >= 10.7
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif // __clang__
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif // __GNUC__
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#endif // NLSR_NSYNC_OPENSSL_H
|
||||
@@ -1,49 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_COMMON_H
|
||||
#define NLSR_NSYNC_SYNC_COMMON_H
|
||||
|
||||
#include <boost/exception/all.hpp>
|
||||
|
||||
#include <ndn-cxx/common.hpp>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
using std::bind;
|
||||
using std::function;
|
||||
|
||||
using std::make_shared;
|
||||
using std::shared_ptr;
|
||||
using std::weak_ptr;
|
||||
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::static_pointer_cast;
|
||||
|
||||
using std::tuple;
|
||||
using std::make_tuple;
|
||||
using std::tie;
|
||||
|
||||
} // namespace Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_COMMON_H
|
||||
@@ -1,74 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-diff-leaf.h"
|
||||
#include <boost/throw_exception.hpp>
|
||||
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;
|
||||
|
||||
using namespace Sync::Error;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
DiffLeaf::DiffLeaf (NameInfoConstPtr info, const SeqNo &seq)
|
||||
: Leaf (info, seq)
|
||||
, m_op (UPDATE)
|
||||
{
|
||||
}
|
||||
|
||||
DiffLeaf::DiffLeaf (NameInfoConstPtr info)
|
||||
: Leaf (info, SeqNo (0,0))
|
||||
, m_op (REMOVE)
|
||||
{
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, Operation op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case UPDATE:
|
||||
os << "update";
|
||||
break;
|
||||
case REMOVE:
|
||||
os << "remove";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Operation &op)
|
||||
{
|
||||
std::string operation;
|
||||
is >> operation;
|
||||
if (operation == "update")
|
||||
op = UPDATE;
|
||||
else if (operation == "remove")
|
||||
op = REMOVE;
|
||||
else
|
||||
BOOST_THROW_EXCEPTION (SyncDiffLeafOperationParseError () << errmsg_info (operation));
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_DIFF_LEAF_H
|
||||
#define NLSR_NSYNC_SYNC_DIFF_LEAF_H
|
||||
|
||||
#include "sync-leaf.h"
|
||||
#include <boost/exception/all.hpp>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* @ingroup sync
|
||||
* @brief Annotation for SYNC leaf
|
||||
*/
|
||||
enum Operation
|
||||
{
|
||||
UPDATE, ///< @brief Leaf was added or updated
|
||||
REMOVE ///< @brief Leaf was removed
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup sync
|
||||
* @brief Annotated SYNC leaf
|
||||
*/
|
||||
class DiffLeaf : public Leaf
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor to create an UPDATE diff leaf
|
||||
* @param info Smart pointer to leaf's name
|
||||
* @param seq Initial sequence number of the pointer
|
||||
*/
|
||||
DiffLeaf (NameInfoConstPtr info, const SeqNo &seq);
|
||||
|
||||
/**
|
||||
* @brief Constructor to create an REMOVE diff leaf
|
||||
* @param info Smart pointer to leaf's name
|
||||
*
|
||||
* This constructor creates a leaf with phony sequence number
|
||||
* with 0 session ID and 0 sequence number
|
||||
*/
|
||||
DiffLeaf (NameInfoConstPtr info);
|
||||
|
||||
virtual ~DiffLeaf () { }
|
||||
|
||||
/**
|
||||
* @brief Get diff leaf type
|
||||
*/
|
||||
Operation
|
||||
getOperation () const { return m_op; }
|
||||
|
||||
private:
|
||||
Operation m_op;
|
||||
};
|
||||
|
||||
typedef shared_ptr<DiffLeaf> DiffLeafPtr;
|
||||
typedef shared_ptr<const DiffLeaf> DiffLeafConstPtr;
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, Operation op);
|
||||
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Operation &op);
|
||||
|
||||
namespace Error {
|
||||
struct SyncDiffLeafOperationParseError : virtual boost::exception, virtual std::exception { };
|
||||
} // Error
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_DIFF_LEAF_H
|
||||
@@ -1,72 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_DIFF_STATE_CONTAINER_H
|
||||
#define NLSR_NSYNC_SYNC_DIFF_STATE_CONTAINER_H
|
||||
|
||||
#include "sync-diff-state.h"
|
||||
#include "sync-digest.h"
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
// #include <boost/multi_index/ordered_index.hpp>
|
||||
// #include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
// #include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/// @cond include_hidden
|
||||
struct sequenced { };
|
||||
struct timed { };
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief Container for differential states
|
||||
*/
|
||||
struct DiffStateContainer : public mi::multi_index_container<
|
||||
DiffStatePtr,
|
||||
mi::indexed_by<
|
||||
// For fast access to elements using DiffState hashes
|
||||
mi::hashed_unique<
|
||||
mi::tag<hashed>,
|
||||
mi::const_mem_fun<DiffState, DigestConstPtr, &DiffState::getDigest>,
|
||||
DigestPtrHash,
|
||||
DigestPtrEqual
|
||||
>
|
||||
,
|
||||
// sequenced index to access older/newer element (like in list)
|
||||
mi::sequenced<mi::tag<sequenced> >
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_DIFF_STATE_CONTAINER_H
|
||||
@@ -1,98 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-diff-state.h"
|
||||
#include "sync-diff-leaf.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
DiffState::DiffState ()
|
||||
{
|
||||
}
|
||||
|
||||
DiffState::~DiffState ()
|
||||
{
|
||||
}
|
||||
|
||||
DiffStatePtr
|
||||
DiffState::diff () const
|
||||
{
|
||||
DiffStatePtr ret = make_shared<DiffState> ();
|
||||
|
||||
DiffStatePtr state = m_next;
|
||||
while (state != 0)
|
||||
{
|
||||
*ret += *state;
|
||||
state = state->m_next;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DiffState &
|
||||
DiffState::operator += (const DiffState &state)
|
||||
{
|
||||
BOOST_FOREACH (LeafConstPtr _leaf, state.getLeaves ())
|
||||
{
|
||||
DiffLeafConstPtr leaf = dynamic_pointer_cast<const DiffLeaf> (_leaf);
|
||||
BOOST_ASSERT (leaf != 0);
|
||||
|
||||
if (leaf->getOperation () == UPDATE)
|
||||
update (leaf->getInfo (), leaf->getSeq ());
|
||||
else if (leaf->getOperation () == REMOVE)
|
||||
remove (leaf->getInfo ());
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT (false);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// from State
|
||||
tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
|
||||
DiffState::update (NameInfoConstPtr info, const SeqNo &seq)
|
||||
{
|
||||
m_leaves.erase (info);
|
||||
|
||||
DiffLeafPtr leaf = make_shared<DiffLeaf> (info, seq);
|
||||
m_leaves.insert (leaf);
|
||||
|
||||
return make_tuple (true, false, SeqNo ());
|
||||
}
|
||||
|
||||
bool
|
||||
DiffState::remove (NameInfoConstPtr info)
|
||||
{
|
||||
m_leaves.erase (info);
|
||||
|
||||
DiffLeafPtr leaf = make_shared<DiffLeaf> (info);
|
||||
m_leaves.insert (leaf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // ns3
|
||||
@@ -1,102 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_DIFF_STATE_H
|
||||
#define NLSR_NSYNC_SYNC_DIFF_STATE_H
|
||||
|
||||
#include "sync-state.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
class DiffState;
|
||||
typedef shared_ptr<DiffState> DiffStatePtr;
|
||||
typedef shared_ptr<DiffState> DiffStateConstPtr;
|
||||
|
||||
/**
|
||||
* @ingroup ccnx
|
||||
* @brief Differential SYNC state
|
||||
*/
|
||||
class DiffState : public State
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @see Default constructor
|
||||
*/
|
||||
DiffState ();
|
||||
virtual ~DiffState ();
|
||||
|
||||
/**
|
||||
* @brief Set successor for the diff state
|
||||
* @param next successor state
|
||||
*/
|
||||
void
|
||||
setNext (DiffStatePtr next)
|
||||
{
|
||||
m_next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set digest for the diff state (obtained from a corresponding full state)
|
||||
* @param digest A read only smart pointer to a digest object (that should be unmodified anywhere else)
|
||||
*/
|
||||
void
|
||||
setDigest (DigestConstPtr digest) { m_digest = digest; }
|
||||
|
||||
/**
|
||||
* @brief Get digest for the diff state
|
||||
*/
|
||||
DigestConstPtr
|
||||
getDigest () const { return m_digest; }
|
||||
|
||||
/**
|
||||
* @brief Accumulate differences from `this' state to the most current state
|
||||
* @returns Accumulated differences from `this' state to the most current state
|
||||
*/
|
||||
DiffStatePtr
|
||||
diff () const;
|
||||
|
||||
/**
|
||||
* @brief Combine differences from `this' and `state'
|
||||
* @param state Differential state to combine with
|
||||
* @return Combined differences
|
||||
*
|
||||
* In case of collisions, `this' leaf will be replaced with the leaf of `state'
|
||||
*/
|
||||
DiffState&
|
||||
operator += (const DiffState &state);
|
||||
|
||||
// from State
|
||||
virtual tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
|
||||
update (NameInfoConstPtr info, const SeqNo &seq);
|
||||
|
||||
virtual bool
|
||||
remove (NameInfoConstPtr info);
|
||||
|
||||
private:
|
||||
DiffStatePtr m_next;
|
||||
DigestConstPtr m_digest;
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_DIFF_STATE_H
|
||||
@@ -1,262 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-digest.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
|
||||
typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
|
||||
|
||||
// for printing, may be disabled in optimized build
|
||||
|
||||
// #ifdef DIGEST_BASE64
|
||||
// #include <boost/archive/iterators/base64_from_binary.hpp>
|
||||
// #include <boost/archive/iterators/binary_from_base64.hpp>
|
||||
// #endif
|
||||
|
||||
#include "boost-archive.h"
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::archive::iterators;
|
||||
using namespace std;
|
||||
|
||||
// Other options: VP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha256, EVP_dss, EVP_dss1, EVP_mdc2, EVP_ripemd160
|
||||
#define HASH_FUNCTION EVP_sha256
|
||||
#define HASH_FUNCTION_LEN 32
|
||||
|
||||
|
||||
// #ifndef DIGEST_BASE64
|
||||
|
||||
template<class CharType>
|
||||
struct hex_from_4_bit
|
||||
{
|
||||
typedef CharType result_type;
|
||||
CharType operator () (CharType ch) const
|
||||
{
|
||||
const char *lookup_table = "0123456789abcdef";
|
||||
// cout << "New character: " << (int) ch << " (" << (char) ch << ")" << "\n";
|
||||
BOOST_ASSERT (ch < 16);
|
||||
return lookup_table[static_cast<size_t>(ch)];
|
||||
}
|
||||
};
|
||||
|
||||
typedef transform_iterator<hex_from_4_bit<std::vector<uint8_t>::const_iterator::value_type>,
|
||||
transform_width<std::vector<uint8_t>::const_iterator, 4, 8, std::vector<uint8_t>::const_iterator::value_type> > string_from_binary;
|
||||
|
||||
|
||||
template<class CharType>
|
||||
struct hex_to_4_bit
|
||||
{
|
||||
typedef CharType result_type;
|
||||
CharType operator () (CharType ch) const
|
||||
{
|
||||
const signed char lookup_table [] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
||||
};
|
||||
|
||||
// cout << "New character: " << hex << (int) ch << " (" << (char) ch << ")" << "\n";
|
||||
signed char value = -1;
|
||||
if ((unsigned)ch < 128)
|
||||
value = lookup_table [(unsigned)ch];
|
||||
if (value == -1)
|
||||
BOOST_THROW_EXCEPTION (Sync::Error::DigestCalculationError () << errmsg_info_int ((int)ch));
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
typedef transform_width<transform_iterator<hex_to_4_bit<string::const_iterator::value_type>, string::const_iterator>, 8, 4> string_to_binary;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
Digest::Digest ()
|
||||
{
|
||||
m_context = EVP_MD_CTX_create ();
|
||||
|
||||
reset ();
|
||||
}
|
||||
|
||||
Digest::~Digest ()
|
||||
{
|
||||
EVP_MD_CTX_destroy (m_context);
|
||||
}
|
||||
|
||||
bool
|
||||
Digest::empty () const
|
||||
{
|
||||
return m_buffer.empty ();
|
||||
}
|
||||
|
||||
bool
|
||||
Digest::isZero () const
|
||||
{
|
||||
if (m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has not been yet finalized"));
|
||||
|
||||
return (m_buffer.size () == 1 && m_buffer[0] == 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Digest::reset ()
|
||||
{
|
||||
m_buffer.clear ();
|
||||
|
||||
int ok = EVP_DigestInit_ex (m_context, HASH_FUNCTION (), 0);
|
||||
if (!ok)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("EVP_DigestInit_ex returned error")
|
||||
<< errmsg_info_int (ok));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Digest::finalize ()
|
||||
{
|
||||
if (!m_buffer.empty ()) return;
|
||||
|
||||
m_buffer.resize (HASH_FUNCTION_LEN);
|
||||
|
||||
unsigned int tmp;
|
||||
int ok = EVP_DigestFinal_ex (m_context,
|
||||
&m_buffer[0], &tmp);
|
||||
if (!ok)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("EVP_DigestFinal_ex returned error")
|
||||
<< errmsg_info_int (ok));
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Digest::getHash () const
|
||||
{
|
||||
if (isZero ()) return 0;
|
||||
|
||||
if (sizeof (std::size_t) > m_buffer.size ())
|
||||
{
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Hash is not zero and length is less than size_t")
|
||||
<< errmsg_info_int (m_buffer.size ()));
|
||||
}
|
||||
|
||||
// just getting first sizeof(std::size_t) bytes
|
||||
// not ideal, but should work pretty well
|
||||
return *(reinterpret_cast<const std::size_t*> (&m_buffer[0]));
|
||||
}
|
||||
|
||||
bool
|
||||
Digest::operator == (const Digest &digest) const
|
||||
{
|
||||
if (m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest1 is empty"));
|
||||
|
||||
if (digest.m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest2 is empty"));
|
||||
|
||||
return m_buffer == digest.m_buffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Digest::update (const uint8_t *buffer, size_t size)
|
||||
{
|
||||
// cout << "Update: " << (void*)buffer << " / size: " << size << "\n";
|
||||
|
||||
// cannot update Digest when it has been finalized
|
||||
if (!m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has been already finalized"));
|
||||
|
||||
bool ok = EVP_DigestUpdate (m_context, buffer, size);
|
||||
if (!ok)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("EVP_DigestUpdate returned error")
|
||||
<< errmsg_info_int (ok));
|
||||
}
|
||||
|
||||
|
||||
Digest &
|
||||
Digest::operator << (const Digest &src)
|
||||
{
|
||||
if (src.m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has not been yet finalized"));
|
||||
|
||||
update (&src.m_buffer[0], src.m_buffer.size ());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const Digest &digest)
|
||||
{
|
||||
BOOST_ASSERT (!digest.m_buffer.empty ());
|
||||
|
||||
ostreambuf_iterator<char> out_it (os); // ostream iterator
|
||||
// need to encode to base64
|
||||
copy (string_from_binary (digest.m_buffer.begin ()),
|
||||
string_from_binary (digest.m_buffer.end ()),
|
||||
out_it);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Digest &digest)
|
||||
{
|
||||
string str;
|
||||
is >> str; // read string first
|
||||
|
||||
if (str.size () == 0)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Input is empty"));
|
||||
|
||||
// uint8_t padding = (3 - str.size () % 3) % 3;
|
||||
// for (uint8_t i = 0; i < padding; i++) str.push_back ('=');
|
||||
|
||||
// only empty digest object can be used for reading
|
||||
if (!digest.m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has been already finalized"));
|
||||
|
||||
digest.m_buffer.clear ();
|
||||
|
||||
copy (string_to_binary (str.begin ()),
|
||||
string_to_binary (str.end ()),
|
||||
std::back_inserter (digest.m_buffer));
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
} // Sync
|
||||
@@ -1,199 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_DIGEST_H
|
||||
#define NLSR_NSYNC_SYNC_DIGEST_H
|
||||
|
||||
#include "sync-common.h"
|
||||
|
||||
#include <vector>
|
||||
#include "openssl.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* @ingroup sync
|
||||
* @brief A simple wrapper for libcrypto hash functions
|
||||
*/
|
||||
class Digest
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor. Will initialize internal libssl structures
|
||||
*/
|
||||
Digest ();
|
||||
|
||||
/**
|
||||
* @brief Check if digest is empty
|
||||
*/
|
||||
bool
|
||||
empty () const;
|
||||
|
||||
/**
|
||||
* @brief Reset digest to the initial state
|
||||
*/
|
||||
void
|
||||
reset ();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~Digest ();
|
||||
|
||||
/**
|
||||
* @brief Obtain a short version of the hash (just first sizeof(size_t) bytes
|
||||
*
|
||||
* Side effect: finalize() will be called on `this'
|
||||
*/
|
||||
std::size_t
|
||||
getHash () const;
|
||||
|
||||
/**
|
||||
* @brief Finalize digest. All subsequent calls to "operator <<" will fire an exception
|
||||
*/
|
||||
void
|
||||
finalize ();
|
||||
|
||||
/**
|
||||
* @brief Compare two full digests
|
||||
*
|
||||
* Side effect: Finalize will be called on `this' and `digest'
|
||||
*/
|
||||
bool
|
||||
operator == (const Digest &digest) const;
|
||||
|
||||
bool
|
||||
operator != (const Digest &digest) const
|
||||
{ return ! (*this == digest); }
|
||||
|
||||
|
||||
/**
|
||||
* @brief Add existing digest to digest calculation
|
||||
* @param src digest to combine with
|
||||
*
|
||||
* The result of this combination is hash (hash (...))
|
||||
*/
|
||||
Digest &
|
||||
operator << (const Digest &src);
|
||||
|
||||
/**
|
||||
* @brief Add string to digest calculation
|
||||
* @param str string to put into digest
|
||||
*/
|
||||
inline Digest &
|
||||
operator << (const std::string &str);
|
||||
|
||||
/**
|
||||
* @brief Add uint64_t value to digest calculation
|
||||
* @param value uint64_t value to put into digest
|
||||
*/
|
||||
inline Digest &
|
||||
operator << (uint64_t value);
|
||||
|
||||
/**
|
||||
* @brief Checks if the stored hash is zero-root hash
|
||||
*
|
||||
* Zero-root hash is a valid hash that optimally represents an empty state
|
||||
*/
|
||||
bool
|
||||
isZero () const;
|
||||
|
||||
private:
|
||||
Digest &
|
||||
operator = (Digest &digest) { (void)digest; return *this; }
|
||||
|
||||
/**
|
||||
* @brief Add size bytes of buffer to the hash
|
||||
*/
|
||||
void
|
||||
update (const uint8_t *buffer, size_t size);
|
||||
|
||||
friend std::ostream &
|
||||
operator << (std::ostream &os, const Digest &digest);
|
||||
|
||||
friend std::istream &
|
||||
operator >> (std::istream &is, Digest &digest);
|
||||
|
||||
private:
|
||||
EVP_MD_CTX *m_context;
|
||||
std::vector<uint8_t> m_buffer;
|
||||
};
|
||||
|
||||
namespace Error {
|
||||
struct DigestCalculationError : virtual boost::exception, virtual std::exception { };
|
||||
}
|
||||
|
||||
typedef shared_ptr<Digest> DigestPtr;
|
||||
typedef shared_ptr<const Digest> DigestConstPtr;
|
||||
|
||||
Digest &
|
||||
Digest::operator << (const std::string &str)
|
||||
{
|
||||
update (reinterpret_cast<const uint8_t*> (str.c_str ()), str.size ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Digest &
|
||||
Digest::operator << (uint64_t value)
|
||||
{
|
||||
update (reinterpret_cast<const uint8_t*> (&value), sizeof (uint64_t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const Digest &digest);
|
||||
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Digest &digest);
|
||||
|
||||
// template<class INT>
|
||||
// Digest &
|
||||
// Digest::operator << (INT value)
|
||||
// {
|
||||
// update (&value, sizeof (INT));
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
struct DigestPtrHash : public std::unary_function<Digest, std::size_t>
|
||||
{
|
||||
std::size_t
|
||||
operator() (DigestConstPtr digest) const
|
||||
{
|
||||
// std::cout << "digest->getHash: " << digest->getHash () << " (" << *digest << ")" << std::endl;
|
||||
return digest->getHash ();
|
||||
}
|
||||
};
|
||||
|
||||
struct DigestPtrEqual : public std::unary_function<Digest, std::size_t>
|
||||
{
|
||||
bool
|
||||
operator() (DigestConstPtr digest1, DigestConstPtr digest2) const
|
||||
{
|
||||
// std::cout << boost::cref(*digest1) << " == " << boost::cref(*digest2) << " : " << (*digest1 == *digest2) << std::endl;
|
||||
return *digest1 == *digest2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_DIGEST_H
|
||||
@@ -1,35 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_EVENT_H
|
||||
#define NLSR_NSYNC_SYNC_EVENT_H
|
||||
|
||||
#include "sync-common.h"
|
||||
|
||||
namespace Sync
|
||||
{
|
||||
|
||||
typedef function< void ( ) > Event;
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_EVENT_H
|
||||
@@ -1,49 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-full-leaf.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
FullLeaf::FullLeaf (NameInfoConstPtr info, const SeqNo &seq)
|
||||
: Leaf (info, seq)
|
||||
{
|
||||
updateDigest ();
|
||||
}
|
||||
|
||||
void
|
||||
FullLeaf::updateDigest ()
|
||||
{
|
||||
m_digest.reset ();
|
||||
m_digest << getInfo ()->getDigest () << *getSeq ().getDigest ();
|
||||
m_digest.finalize ();
|
||||
}
|
||||
|
||||
// from Leaf
|
||||
void
|
||||
FullLeaf::setSeq (const SeqNo &seq)
|
||||
{
|
||||
Leaf::setSeq (seq);
|
||||
updateDigest ();
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,71 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_FULL_LEAF_H
|
||||
#define NLSR_NSYNC_SYNC_FULL_LEAF_H
|
||||
|
||||
#include "sync-leaf.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* @ingroup sync
|
||||
* @brief SYNC leaf for the full state (with support of Digest calculation)
|
||||
*/
|
||||
class FullLeaf : public Leaf
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor to create an UPDATE diff leaf
|
||||
* @param info Smart pointer to leaf's name
|
||||
* @param seq Initial sequence number of the pointer
|
||||
*/
|
||||
FullLeaf (NameInfoConstPtr info, const SeqNo &seq);
|
||||
virtual ~FullLeaf () { }
|
||||
|
||||
/**
|
||||
* @brief Get hash digest of the leaf
|
||||
*
|
||||
* The underlying Digest object is recalculated on every update or removal
|
||||
* (including updates of child classes)
|
||||
*/
|
||||
const Digest &
|
||||
getDigest () const { return m_digest; }
|
||||
|
||||
// from Leaf
|
||||
virtual void
|
||||
setSeq (const SeqNo &seq);
|
||||
|
||||
private:
|
||||
void
|
||||
updateDigest ();
|
||||
|
||||
private:
|
||||
Digest m_digest;
|
||||
};
|
||||
|
||||
typedef shared_ptr<FullLeaf> FullLeafPtr;
|
||||
typedef shared_ptr<const FullLeaf> FullLeafConstPtr;
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_FULL_LEAF_H
|
||||
@@ -1,118 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-full-state.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include "sync-full-leaf.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
|
||||
FullState::FullState ()
|
||||
// m_lastUpdated is initialized to "not_a_date_time" in normal lib mode and to "0" time in NS-3 mode
|
||||
{
|
||||
}
|
||||
|
||||
FullState::~FullState ()
|
||||
{
|
||||
}
|
||||
|
||||
ndn::time::system_clock::Duration
|
||||
FullState::getTimeFromLastUpdate () const
|
||||
{
|
||||
return ndn::time::system_clock::now() - m_lastUpdated;
|
||||
}
|
||||
|
||||
DigestConstPtr
|
||||
FullState::getDigest ()
|
||||
{
|
||||
if (!m_digest)
|
||||
{
|
||||
m_digest = make_shared<Digest> ();
|
||||
if (m_leaves.get<ordered> ().size () > 0)
|
||||
{
|
||||
for (LeafConstPtr leaf : m_leaves.get<ordered> ())
|
||||
{
|
||||
FullLeafConstPtr fullLeaf = dynamic_pointer_cast<const FullLeaf> (leaf);
|
||||
BOOST_ASSERT (fullLeaf != 0);
|
||||
*m_digest << fullLeaf->getDigest ();
|
||||
}
|
||||
m_digest->finalize ();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::istringstream is ("00"); //zero state
|
||||
is >> *m_digest;
|
||||
}
|
||||
}
|
||||
|
||||
return m_digest;
|
||||
}
|
||||
|
||||
// from State
|
||||
tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
|
||||
FullState::update (NameInfoConstPtr info, const SeqNo &seq)
|
||||
{
|
||||
m_lastUpdated = ndn::time::system_clock::now();
|
||||
|
||||
|
||||
m_digest.reset ();
|
||||
|
||||
LeafContainer::iterator item = m_leaves.find (info);
|
||||
if (item == m_leaves.end ())
|
||||
{
|
||||
m_leaves.insert (make_shared<FullLeaf> (info, seq));
|
||||
return make_tuple (true, false, SeqNo ());
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*item)->getSeq () == seq || seq < (*item)->getSeq ())
|
||||
{
|
||||
return make_tuple (false, false, SeqNo ());
|
||||
}
|
||||
|
||||
SeqNo old = (*item)->getSeq ();
|
||||
m_leaves.modify (item, [&seq](LeafPtr data){ data->setSeq(seq); });
|
||||
return make_tuple (false, true, old);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FullState::remove (NameInfoConstPtr info)
|
||||
{
|
||||
m_lastUpdated = ndn::time::system_clock::now();
|
||||
|
||||
m_digest.reset ();
|
||||
|
||||
LeafContainer::iterator item = m_leaves.find (info);
|
||||
if (item != m_leaves.end ())
|
||||
{
|
||||
m_leaves.erase (item);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,79 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_FULL_STATE_H
|
||||
#define NLSR_NSYNC_SYNC_FULL_STATE_H
|
||||
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
#include "sync-state.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
class FullState;
|
||||
typedef shared_ptr<FullState> FullStatePtr;
|
||||
typedef shared_ptr<FullState> FullStateConstPtr;
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief Cumulative SYNC state
|
||||
*/
|
||||
class FullState : public State
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
FullState ();
|
||||
virtual ~FullState ();
|
||||
|
||||
/**
|
||||
* @brief Get time period since last state update
|
||||
*
|
||||
* This value can be used to randomize reconciliation waiting time in SyncApp
|
||||
*/
|
||||
ndn::time::system_clock::Duration
|
||||
getTimeFromLastUpdate () const;
|
||||
|
||||
/**
|
||||
* @brief Obtain a read-only copy of the digest
|
||||
*
|
||||
* If m_digest is 0, then it is automatically created. On every update and removal, m_digest is reset to 0
|
||||
*/
|
||||
DigestConstPtr
|
||||
getDigest ();
|
||||
|
||||
// from State
|
||||
virtual tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
|
||||
update (NameInfoConstPtr info, const SeqNo &seq);
|
||||
|
||||
virtual bool
|
||||
remove (NameInfoConstPtr info);
|
||||
|
||||
private:
|
||||
ndn::time::system_clock::TimePoint m_lastUpdated; ///< @brief Time when state was updated last time
|
||||
DigestPtr m_digest;
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_FULL_STATE_H
|
||||
@@ -1,99 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_INTEREST_CONTAINER_H
|
||||
#define NLSR_NSYNC_SYNC_INTEREST_CONTAINER_H
|
||||
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
#include "sync-digest.h"
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
// #include <boost/multi_index/ordered_index.hpp>
|
||||
// #include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
// #include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
struct Interest
|
||||
{
|
||||
Interest (DigestConstPtr digest, const std::string &name, bool unknown=false)
|
||||
: m_digest (digest)
|
||||
, m_name (name)
|
||||
, m_time (ndn::time::system_clock::now())
|
||||
, m_unknown (unknown)
|
||||
{
|
||||
}
|
||||
|
||||
DigestConstPtr m_digest;
|
||||
std::string m_name;
|
||||
ndn::time::system_clock::TimePoint m_time;
|
||||
bool m_unknown;
|
||||
};
|
||||
|
||||
/// @cond include_hidden
|
||||
struct named { };
|
||||
struct hashed;
|
||||
struct timed;
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief Container for interests (application PIT)
|
||||
*/
|
||||
struct InterestContainer : public mi::multi_index_container<
|
||||
Interest,
|
||||
mi::indexed_by<
|
||||
mi::hashed_unique<
|
||||
mi::tag<named>,
|
||||
BOOST_MULTI_INDEX_MEMBER(Interest, std::string, m_name)
|
||||
>
|
||||
,
|
||||
|
||||
mi::hashed_non_unique<
|
||||
mi::tag<hashed>,
|
||||
BOOST_MULTI_INDEX_MEMBER(Interest, DigestConstPtr, m_digest),
|
||||
DigestPtrHash,
|
||||
DigestPtrEqual
|
||||
>
|
||||
,
|
||||
|
||||
mi::ordered_non_unique<
|
||||
mi::tag<timed>,
|
||||
BOOST_MULTI_INDEX_MEMBER(Interest, ndn::time::system_clock::TimePoint, m_time)
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_INTEREST_CONTAINER_H
|
||||
@@ -1,126 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-interest-table.h"
|
||||
#include "sync-logging.h"
|
||||
using namespace std;
|
||||
|
||||
INIT_LOGGER("SyncInterestTable");
|
||||
|
||||
namespace Sync
|
||||
{
|
||||
|
||||
SyncInterestTable::SyncInterestTable(boost::asio::io_service& io, ndn::time::system_clock::Duration lifetime)
|
||||
: m_entryLifetime(lifetime)
|
||||
, m_scheduler(io)
|
||||
{
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(4),
|
||||
ndn::bind(&SyncInterestTable::expireInterests, this));
|
||||
}
|
||||
|
||||
SyncInterestTable::~SyncInterestTable()
|
||||
{
|
||||
}
|
||||
|
||||
Interest
|
||||
SyncInterestTable::pop()
|
||||
{
|
||||
if (m_table.size() == 0)
|
||||
BOOST_THROW_EXCEPTION(Error::InterestTableIsEmpty());
|
||||
|
||||
Interest ret = *m_table.begin();
|
||||
m_table.erase(m_table.begin());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
SyncInterestTable::insert(DigestConstPtr digest, const string &name, bool unknownState/*=false*/)
|
||||
{
|
||||
bool existent = false;
|
||||
|
||||
InterestContainer::index<named>::type::iterator it = m_table.get<named>().find(name);
|
||||
if (it != m_table.end())
|
||||
{
|
||||
existent = true;
|
||||
m_table.erase(it);
|
||||
}
|
||||
m_table.insert(Interest(digest, name, unknownState));
|
||||
|
||||
return existent;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SyncInterestTable::size() const
|
||||
{
|
||||
return m_table.size();
|
||||
}
|
||||
|
||||
bool
|
||||
SyncInterestTable::remove(const string &name)
|
||||
{
|
||||
InterestContainer::index<named>::type::iterator item = m_table.get<named>().find(name);
|
||||
if (item != m_table.get<named>().end())
|
||||
{
|
||||
m_table.get<named>().erase(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SyncInterestTable::remove(DigestConstPtr digest)
|
||||
{
|
||||
InterestContainer::index<hashed>::type::iterator item = m_table.get<hashed>().find(digest);
|
||||
if (item != m_table.get<hashed>().end())
|
||||
{
|
||||
m_table.get<hashed>().erase(digest); // erase all records associated with the digest
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SyncInterestTable::expireInterests()
|
||||
{
|
||||
uint32_t count = 0;
|
||||
ndn::time::system_clock::TimePoint expireTime = ndn::time::system_clock::now() - m_entryLifetime;
|
||||
|
||||
while (m_table.size() > 0)
|
||||
{
|
||||
InterestContainer::index<timed>::type::iterator item = m_table.get<timed>().begin();
|
||||
|
||||
if (item->m_time <= expireTime)
|
||||
{
|
||||
m_table.get<timed>().erase(item);
|
||||
count ++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(4),
|
||||
ndn::bind(&SyncInterestTable::expireInterests, this));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_INTEREST_TABLE_H
|
||||
#define NLSR_NSYNC_SYNC_INTEREST_TABLE_H
|
||||
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "sync-digest.h"
|
||||
#include "sync-interest-container.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief A table to keep unanswered Sync Interest
|
||||
* all access operation to the table should grab the
|
||||
* mutex first
|
||||
*/
|
||||
class SyncInterestTable
|
||||
{
|
||||
public:
|
||||
SyncInterestTable (boost::asio::io_service& io, ndn::time::system_clock::Duration lifetime);
|
||||
~SyncInterestTable ();
|
||||
|
||||
/**
|
||||
* @brief Insert an interest, if interest already exists, update the
|
||||
* timestamp
|
||||
*/
|
||||
bool
|
||||
insert (DigestConstPtr interest, const std::string &name, bool unknownState=false);
|
||||
|
||||
/**
|
||||
* @brief Remove interest by digest (e.g., when it was satisfied)
|
||||
*/
|
||||
bool
|
||||
remove (DigestConstPtr interest);
|
||||
|
||||
/**
|
||||
* @brief Remove interest by name (e.g., when it was satisfied)
|
||||
*/
|
||||
bool
|
||||
remove (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief pop a non-expired Interest from PIT
|
||||
*/
|
||||
Interest
|
||||
pop ();
|
||||
|
||||
uint32_t
|
||||
size () const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief periodically called to expire Interest
|
||||
*/
|
||||
void
|
||||
expireInterests ();
|
||||
|
||||
private:
|
||||
ndn::time::system_clock::Duration m_entryLifetime;
|
||||
InterestContainer m_table;
|
||||
|
||||
ndn::Scheduler m_scheduler;
|
||||
};
|
||||
|
||||
namespace Error {
|
||||
struct InterestTableIsEmpty : virtual boost::exception, virtual std::exception { };
|
||||
}
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_INTEREST_TABLE_H
|
||||
@@ -1,43 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-leaf.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
Leaf::Leaf (NameInfoConstPtr info, const SeqNo &seq)
|
||||
: m_info (info)
|
||||
, m_seq (seq)
|
||||
{
|
||||
}
|
||||
|
||||
Leaf::~Leaf ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Leaf::setSeq (const SeqNo &seq)
|
||||
{
|
||||
m_seq = std::max (m_seq, seq);
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,84 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_LEAF_H
|
||||
#define NLSR_NSYNC_SYNC_LEAF_H
|
||||
|
||||
#include "sync-seq-no.h"
|
||||
#include "sync-name-info.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief Sync tree leaf
|
||||
*/
|
||||
class Leaf
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param info Smart pointer to leaf's name
|
||||
* @param seq Initial sequence number of the pointer
|
||||
*/
|
||||
Leaf (NameInfoConstPtr info, const SeqNo &seq);
|
||||
virtual ~Leaf ();
|
||||
|
||||
/**
|
||||
* @brief Get name of the leaf
|
||||
*/
|
||||
NameInfoConstPtr
|
||||
getInfo () const { return m_info; }
|
||||
|
||||
/**
|
||||
* @brief Get sequence number of the leaf
|
||||
*/
|
||||
const SeqNo&
|
||||
getSeq () const { return m_seq; }
|
||||
|
||||
/**
|
||||
* @brief Update sequence number of the leaf
|
||||
* @param seq Sequence number
|
||||
*
|
||||
* Sequence number is updated to the largest value among this->m_seq and seq
|
||||
*/
|
||||
virtual void
|
||||
setSeq (const SeqNo &seq);
|
||||
|
||||
private:
|
||||
NameInfoConstPtr m_info;
|
||||
SeqNo m_seq;
|
||||
};
|
||||
|
||||
typedef shared_ptr<Leaf> LeafPtr;
|
||||
typedef shared_ptr<const Leaf> LeafConstPtr;
|
||||
|
||||
inline std::ostream &
|
||||
operator << (std::ostream &os, const Leaf &leaf)
|
||||
{
|
||||
os << *leaf.getInfo () << "(" << leaf.getSeq () << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_LEAF_H
|
||||
@@ -1,61 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-logging.h"
|
||||
|
||||
#ifdef HAVE_LOG4CXX
|
||||
|
||||
#include <log4cxx/logger.h>
|
||||
#include <log4cxx/basicconfigurator.h>
|
||||
#include <log4cxx/consoleappender.h>
|
||||
#include <log4cxx/patternlayout.h>
|
||||
#include <log4cxx/level.h>
|
||||
#include <log4cxx/propertyconfigurator.h>
|
||||
#include <log4cxx/defaultconfigurator.h>
|
||||
#include <log4cxx/helpers/exception.h>
|
||||
using namespace log4cxx;
|
||||
using namespace log4cxx::helpers;
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
void
|
||||
INIT_LOGGERS ()
|
||||
{
|
||||
static bool configured = false;
|
||||
|
||||
if (configured) return;
|
||||
|
||||
if (access ("log4cxx.properties", R_OK)==0)
|
||||
PropertyConfigurator::configureAndWatch ("log4cxx.properties");
|
||||
else
|
||||
{
|
||||
PatternLayoutPtr layout (new PatternLayout ("%d{HH:mm:ss} %p %c{1} - %m%n"));
|
||||
ConsoleAppenderPtr appender (new ConsoleAppender (layout));
|
||||
|
||||
BasicConfigurator::configure( appender );
|
||||
Logger::getRootLogger()->setLevel (log4cxx::Level::getInfo ());
|
||||
}
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,74 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_LOGGING_H
|
||||
#define NLSR_NSYNC_SYNC_LOGGING_H
|
||||
|
||||
#ifdef HAVE_LOG4CXX
|
||||
|
||||
#include <log4cxx/logger.h>
|
||||
|
||||
#define INIT_LOGGER(name) \
|
||||
static log4cxx::LoggerPtr staticModuleLogger = log4cxx::Logger::getLogger (name)
|
||||
|
||||
#define _LOG_DEBUG(x) \
|
||||
LOG4CXX_DEBUG(staticModuleLogger, x);
|
||||
|
||||
#define _LOG_TRACE(x) \
|
||||
LOG4CXX_TRACE(staticModuleLogger, x);
|
||||
|
||||
#define _LOG_FUNCTION(x) \
|
||||
LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "(" << x << ")");
|
||||
|
||||
#define _LOG_FUNCTION_NOARGS \
|
||||
LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "()");
|
||||
|
||||
#define _LOG_ERROR(x) \
|
||||
LOG4CXX_ERROR(staticModuleLogger, x);
|
||||
|
||||
void
|
||||
INIT_LOGGERS ();
|
||||
|
||||
#else
|
||||
|
||||
#define INIT_LOGGER(name)
|
||||
#define _LOG_FUNCTION(x)
|
||||
#define _LOG_FUNCTION_NOARGS
|
||||
#define _LOG_TRACE(x)
|
||||
#define INIT_LOGGERS(x)
|
||||
#define _LOG_ERROR(x)
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#define _LOG_DEBUG(x) \
|
||||
std::clog << boost::get_system_time () << " " << boost::this_thread::get_id () << " " << x << endl;
|
||||
|
||||
#else
|
||||
#define _LOG_DEBUG(x)
|
||||
#endif
|
||||
|
||||
#endif // HAVE_LOG4CXX
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_LOGGING_H
|
||||
@@ -1,84 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_LOGIC_EVENT_CONTAINER_H
|
||||
#define NLSR_NSYNC_SYNC_LOGIC_EVENT_CONTAINER_H
|
||||
|
||||
#include "sync-event.h"
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
// #include <boost/multi_index/tag.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
// #include <boost/multi_index/composite_key.hpp>
|
||||
// #include <boost/multi_index/hashed_index.hpp>
|
||||
// #include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
// #include <boost/multi_index/mem_fun.hpp>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace Sync
|
||||
{
|
||||
|
||||
struct LogicEvent
|
||||
{
|
||||
LogicEvent (const boost::system_time &_time, Event _event, uint32_t _label)
|
||||
: time (_time)
|
||||
, event (_event)
|
||||
, lbl (_label)
|
||||
{ }
|
||||
|
||||
boost::system_time time;
|
||||
Event event;
|
||||
uint32_t lbl;
|
||||
};
|
||||
|
||||
/// @cond include_hidden
|
||||
struct byLabel { } ;
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief ???
|
||||
*/
|
||||
struct EventsContainer : public mi::multi_index_container<
|
||||
LogicEvent,
|
||||
mi::indexed_by<
|
||||
|
||||
mi::ordered_non_unique<
|
||||
mi::member<LogicEvent, boost::system_time, &LogicEvent::time>
|
||||
>,
|
||||
|
||||
mi::ordered_non_unique<
|
||||
mi::tag<byLabel>,
|
||||
mi::member<LogicEvent, uint32_t, &LogicEvent::lbl>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_LOGIC_EVENT_CONTAINER_H
|
||||
@@ -1,752 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
* Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-logic.h"
|
||||
#include "sync-diff-leaf.h"
|
||||
#include "sync-full-leaf.h"
|
||||
#include "sync-logging.h"
|
||||
#include "sync-state.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using ndn::Data;
|
||||
using ndn::EventId;
|
||||
using ndn::KeyChain;
|
||||
using ndn::Face;
|
||||
using ndn::Name;
|
||||
using ndn::OnDataValidated;
|
||||
using ndn::OnDataValidationFailed;
|
||||
using ndn::Validator;
|
||||
|
||||
INIT_LOGGER ("SyncLogic");
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define _LOG_DEBUG_ID(v) _LOG_DEBUG(m_instanceId << " " << v)
|
||||
#else
|
||||
#define _LOG_DEBUG_ID(v) _LOG_DEBUG(v)
|
||||
#endif
|
||||
|
||||
#define GET_RANDOM(var) var ()
|
||||
|
||||
#define TIME_SECONDS_WITH_JITTER(sec) \
|
||||
(ndn::time::seconds(sec) + ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
|
||||
|
||||
#define TIME_MILLISECONDS_WITH_JITTER(ms) \
|
||||
(ndn::time::seconds(ms) + ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
|
||||
|
||||
namespace Sync {
|
||||
|
||||
using ndn::shared_ptr;
|
||||
|
||||
int SyncLogic::m_instanceCounter = 0;
|
||||
|
||||
const int SyncLogic::m_syncResponseFreshness = 1000; // MUST BE dividable by 1000!!!
|
||||
const int SyncLogic::m_syncInterestReexpress = 4; // seconds
|
||||
|
||||
SyncLogic::SyncLogic (const Name& syncPrefix,
|
||||
shared_ptr<Validator> validator,
|
||||
shared_ptr<Face> face,
|
||||
LogicUpdateCallback onUpdate,
|
||||
LogicRemoveCallback onRemove)
|
||||
: m_state (new FullState)
|
||||
, m_syncInterestTable (face->getIoService(), ndn::time::seconds(m_syncInterestReexpress))
|
||||
, m_syncPrefix (syncPrefix)
|
||||
, m_onUpdate (onUpdate)
|
||||
, m_onRemove (onRemove)
|
||||
, m_perBranch (false)
|
||||
, m_validator(validator)
|
||||
, m_keyChain(new KeyChain())
|
||||
, m_face(face)
|
||||
, m_scheduler(face->getIoService())
|
||||
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
|
||||
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
|
||||
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
|
||||
, m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
|
||||
{
|
||||
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
|
||||
bind(&SyncLogic::onSyncInterest,
|
||||
this, _1, _2),
|
||||
bind(&SyncLogic::onSyncRegisterSucceed,
|
||||
this, _1),
|
||||
bind(&SyncLogic::onSyncRegisterFailed,
|
||||
this, _1, _2));
|
||||
|
||||
|
||||
m_reexpressingInterestId = m_scheduler.scheduleEvent (ndn::time::seconds (0),
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
|
||||
m_instanceId = string("Instance " + boost::lexical_cast<string>(m_instanceCounter++) + " ");
|
||||
}
|
||||
|
||||
SyncLogic::SyncLogic (const Name& syncPrefix,
|
||||
shared_ptr<Validator> validator,
|
||||
shared_ptr<Face> face,
|
||||
LogicPerBranchCallback onUpdateBranch)
|
||||
: m_state (new FullState)
|
||||
, m_syncInterestTable (face->getIoService(), ndn::time::seconds (m_syncInterestReexpress))
|
||||
, m_syncPrefix (syncPrefix)
|
||||
, m_onUpdateBranch (onUpdateBranch)
|
||||
, m_perBranch(true)
|
||||
, m_validator(validator)
|
||||
, m_keyChain(new KeyChain())
|
||||
, m_face(face)
|
||||
, m_scheduler(face->getIoService())
|
||||
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
|
||||
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
|
||||
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
|
||||
, m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
|
||||
{
|
||||
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
|
||||
bind(&SyncLogic::onSyncInterest,
|
||||
this, _1, _2),
|
||||
bind(&SyncLogic::onSyncRegisterSucceed,
|
||||
this, _1),
|
||||
bind(&SyncLogic::onSyncRegisterFailed,
|
||||
this, _1, _2));
|
||||
|
||||
m_reexpressingInterestId = m_scheduler.scheduleEvent (ndn::time::seconds (0),
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
}
|
||||
|
||||
SyncLogic::~SyncLogic ()
|
||||
{
|
||||
m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Two types of intersts
|
||||
*
|
||||
* Normal name: .../<hash>
|
||||
* Recovery name: .../recovery/<hash>
|
||||
*/
|
||||
tuple<DigestConstPtr, std::string>
|
||||
SyncLogic::convertNameToDigestAndType (const Name &name)
|
||||
{
|
||||
BOOST_ASSERT (m_syncPrefix.isPrefixOf(name));
|
||||
|
||||
int nameLengthDiff = name.size() - m_syncPrefix.size();
|
||||
BOOST_ASSERT (nameLengthDiff > 0);
|
||||
BOOST_ASSERT (nameLengthDiff < 3);
|
||||
|
||||
string hash = name.get(-1).toUri();
|
||||
string interestType;
|
||||
|
||||
if(nameLengthDiff == 1)
|
||||
interestType = "normal";
|
||||
else
|
||||
interestType = name.get(-2).toUri();
|
||||
|
||||
_LOG_DEBUG_ID (hash << ", " << interestType);
|
||||
|
||||
DigestPtr digest = make_shared<Digest> ();
|
||||
istringstream is (hash);
|
||||
is >> *digest;
|
||||
|
||||
return make_tuple(digest, interestType);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncInterest (const Name& prefix, const ndn::Interest& interest)
|
||||
{
|
||||
Name name = interest.getName();
|
||||
|
||||
_LOG_DEBUG_ID("respondSyncInterest: " << name);
|
||||
|
||||
try
|
||||
{
|
||||
_LOG_DEBUG_ID ("<< I " << name);
|
||||
|
||||
DigestConstPtr digest;
|
||||
string type;
|
||||
tie (digest, type) = convertNameToDigestAndType (name);
|
||||
|
||||
if (type == "normal") // kind of ineffective...
|
||||
{
|
||||
processSyncInterest (name, digest);
|
||||
}
|
||||
else if (type == "recovery")
|
||||
{
|
||||
processSyncRecoveryInterest (name, digest);
|
||||
}
|
||||
}
|
||||
catch (Error::DigestCalculationError &e)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Something fishy happened...");
|
||||
// log error. ignoring it for now, later we should log it
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncRegisterSucceed(const Name& prefix)
|
||||
{
|
||||
_LOG_DEBUG_ID("Sync prefix registration succeeded! " << prefix);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncRegisterFailed(const Name& prefix, const string& msg)
|
||||
{
|
||||
_LOG_DEBUG_ID("Sync prefix registration failed! " << msg);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncData(const ndn::Interest& interest, const Data& data)
|
||||
{
|
||||
OnDataValidated onValidated = bind(&SyncLogic::onSyncDataValidated, this, _1);
|
||||
OnDataValidationFailed onValidationFailed = bind(&SyncLogic::onSyncDataValidationFailed, this, _1);
|
||||
m_validator->validate(data, onValidated, onValidationFailed);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncTimeout(const ndn::Interest& interest)
|
||||
{
|
||||
// It is OK. Others will handle the time out situation.
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncDataValidationFailed(const shared_ptr<const Data>& data)
|
||||
{
|
||||
_LOG_DEBUG_ID("Sync data cannot be verified!");
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncDataValidated(const shared_ptr<const Data>& data)
|
||||
{
|
||||
Name name = data->getName();
|
||||
const char* wireData = (const char*)data->getContent().value();
|
||||
size_t len = data->getContent().value_size();
|
||||
|
||||
try
|
||||
{
|
||||
_LOG_DEBUG_ID ("<< D " << name);
|
||||
|
||||
DigestConstPtr digest;
|
||||
string type;
|
||||
tie (digest, type) = convertNameToDigestAndType (name);
|
||||
|
||||
if (type == "normal")
|
||||
{
|
||||
processSyncData (name, digest, wireData, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// timer is always restarted when we schedule recovery
|
||||
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
|
||||
processSyncData (name, digest, wireData, len);
|
||||
}
|
||||
}
|
||||
catch (Error::DigestCalculationError &e)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Something fishy happened...");
|
||||
// log error. ignoring it for now, later we should log it
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::processSyncInterest (const Name &name, DigestConstPtr digest,
|
||||
bool timedProcessing/*=false*/)
|
||||
{
|
||||
_LOG_DEBUG_ID("processSyncInterest");
|
||||
DigestConstPtr rootDigest;
|
||||
{
|
||||
rootDigest = m_state->getDigest();
|
||||
}
|
||||
|
||||
// Special case when state is not empty and we have received request with zero-root digest
|
||||
if (digest->isZero () && !rootDigest->isZero ())
|
||||
{
|
||||
|
||||
SyncStateMsg ssm;
|
||||
{
|
||||
ssm << (*m_state);
|
||||
}
|
||||
sendSyncData (name, digest, ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*rootDigest == *digest)
|
||||
{
|
||||
_LOG_DEBUG_ID ("processSyncInterest (): Same state. Adding to PIT");
|
||||
m_syncInterestTable.insert (digest, name.toUri(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
|
||||
|
||||
if (stateInDiffLog != m_log.end ())
|
||||
{
|
||||
DiffStateConstPtr stateDiff = (*stateInDiffLog)->diff ();
|
||||
|
||||
sendSyncData (name, digest, stateDiff);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!timedProcessing)
|
||||
{
|
||||
bool exists = m_syncInterestTable.insert (digest, name.toUri(), true);
|
||||
if (exists) // somebody else replied, so restart random-game timer
|
||||
{
|
||||
_LOG_DEBUG_ID("Unknown digest, but somebody may have already replied, " <<
|
||||
"so restart our timer");
|
||||
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
|
||||
}
|
||||
|
||||
uint32_t waitDelay = GET_RANDOM (m_rangeUniformRandom);
|
||||
_LOG_DEBUG_ID("Digest is not in the log. Schedule processing after small delay: " <<
|
||||
ndn::time::milliseconds (waitDelay));
|
||||
|
||||
m_delayedInterestProcessingId =
|
||||
m_scheduler.scheduleEvent(ndn::time::milliseconds (waitDelay),
|
||||
bind (&SyncLogic::processSyncInterest, this, name, digest, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
_LOG_DEBUG_ID(" (timed processing)");
|
||||
|
||||
m_recoveryRetransmissionInterval = m_defaultRecoveryRetransmitInterval;
|
||||
sendSyncRecoveryInterests (digest);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::processSyncData (const Name &name, DigestConstPtr digest,
|
||||
const char *wireData, size_t len)
|
||||
{
|
||||
DiffStatePtr diffLog = make_shared<DiffState> ();
|
||||
bool ownInterestSatisfied = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
m_syncInterestTable.remove (name.toUri()); // Remove satisfied interest from PIT
|
||||
|
||||
ownInterestSatisfied = (name == m_outstandingInterestName);
|
||||
|
||||
DiffState diff;
|
||||
SyncStateMsg msg;
|
||||
if (!msg.ParseFromArray(wireData, len) || !msg.IsInitialized())
|
||||
{
|
||||
//Throw
|
||||
BOOST_THROW_EXCEPTION (Error::SyncStateMsgDecodingFailure () );
|
||||
}
|
||||
msg >> diff;
|
||||
|
||||
vector<MissingDataInfo> v;
|
||||
BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
|
||||
{
|
||||
DiffLeafConstPtr diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
|
||||
BOOST_ASSERT (diffLeaf != 0);
|
||||
|
||||
NameInfoConstPtr info = diffLeaf->getInfo();
|
||||
if (diffLeaf->getOperation() == UPDATE)
|
||||
{
|
||||
SeqNo seq = diffLeaf->getSeq();
|
||||
|
||||
bool inserted = false;
|
||||
bool updated = false;
|
||||
SeqNo oldSeq;
|
||||
{
|
||||
tie (inserted, updated, oldSeq) = m_state->update (info, seq);
|
||||
}
|
||||
|
||||
if (inserted || updated)
|
||||
{
|
||||
diffLog->update (info, seq);
|
||||
if (!oldSeq.isValid())
|
||||
{
|
||||
oldSeq = SeqNo(seq.getSession(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
++oldSeq;
|
||||
}
|
||||
// there is no need for application to process update on forwarder node
|
||||
if (info->toString() != forwarderPrefix)
|
||||
{
|
||||
MissingDataInfo mdi = {info->toString(), oldSeq, seq};
|
||||
{
|
||||
ostringstream interestName;
|
||||
interestName << mdi.prefix <<
|
||||
"/" << mdi.high.getSession() <<
|
||||
"/" << mdi.high.getSeq();
|
||||
_LOG_DEBUG_ID("+++++++++++++++ " + interestName.str());
|
||||
}
|
||||
if (m_perBranch)
|
||||
{
|
||||
ostringstream interestName;
|
||||
interestName << mdi.prefix <<
|
||||
"/" << mdi.high.getSession() <<
|
||||
"/" << mdi.high.getSeq();
|
||||
m_onUpdateBranch(interestName.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
v.push_back(mdi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (diffLeaf->getOperation() == REMOVE)
|
||||
{
|
||||
if (m_state->remove (info))
|
||||
{
|
||||
diffLog->remove (info);
|
||||
if (!m_perBranch)
|
||||
{
|
||||
m_onRemove (info->toString ());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (!v.empty())
|
||||
{
|
||||
if (!m_perBranch)
|
||||
{
|
||||
m_onUpdate(v);
|
||||
}
|
||||
}
|
||||
|
||||
insertToDiffLog (diffLog);
|
||||
}
|
||||
catch (Error::SyncStateMsgDecodingFailure &e)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Something really fishy happened during state decoding " <<
|
||||
diagnostic_information (e));
|
||||
diffLog.reset ();
|
||||
// don't do anything
|
||||
}
|
||||
|
||||
if ((diffLog != 0 && diffLog->getLeaves ().size () > 0) ||
|
||||
ownInterestSatisfied)
|
||||
{
|
||||
_LOG_DEBUG_ID(" +++++++++++++++ state changed!!!");
|
||||
// Do it only if everything went fine and state changed
|
||||
|
||||
// this is kind of wrong
|
||||
// satisfyPendingSyncInterests (diffLog); // if there are interests in PIT,
|
||||
// // there is a point to satisfy them using new state
|
||||
|
||||
// if state has changed, then it is safe to express a new interest
|
||||
ndn::time::system_clock::Duration after =
|
||||
ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter));
|
||||
// cout << "------------ reexpress interest after: " << after << endl;
|
||||
EventId eventId = m_scheduler.scheduleEvent (after,
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_reexpressingInterestId = eventId;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::processSyncRecoveryInterest (const Name &name, DigestConstPtr digest)
|
||||
{
|
||||
_LOG_DEBUG_ID("processSyncRecoveryInterest");
|
||||
DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
|
||||
|
||||
if (stateInDiffLog == m_log.end ())
|
||||
{
|
||||
_LOG_DEBUG_ID ("Could not find " << *digest << " in digest log");
|
||||
return;
|
||||
}
|
||||
|
||||
SyncStateMsg ssm;
|
||||
{
|
||||
ssm << (*m_state);
|
||||
}
|
||||
sendSyncData (name, digest, ssm);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::satisfyPendingSyncInterests (DiffStateConstPtr diffLog)
|
||||
{
|
||||
DiffStatePtr fullStateLog = make_shared<DiffState> ();
|
||||
{
|
||||
BOOST_FOREACH (LeafConstPtr leaf, m_state->getLeaves ()/*.get<timed> ()*/)
|
||||
{
|
||||
fullStateLog->update (leaf->getInfo (), leaf->getSeq ());
|
||||
/// @todo Impose limit on how many state info should be send out
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint32_t counter = 0;
|
||||
while (m_syncInterestTable.size () > 0)
|
||||
{
|
||||
Sync::Interest interest = m_syncInterestTable.pop ();
|
||||
|
||||
if (!interest.m_unknown)
|
||||
{
|
||||
_LOG_DEBUG_ID (">> D " << interest.m_name);
|
||||
sendSyncData (interest.m_name, interest.m_digest, diffLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
_LOG_DEBUG_ID (">> D (unknown)" << interest.m_name);
|
||||
sendSyncData (interest.m_name, interest.m_digest, fullStateLog);
|
||||
}
|
||||
counter ++;
|
||||
}
|
||||
_LOG_DEBUG_ID ("Satisfied " << counter << " pending interests");
|
||||
}
|
||||
catch (Error::InterestTableIsEmpty &e)
|
||||
{
|
||||
// ok. not really an error
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::insertToDiffLog (DiffStatePtr diffLog)
|
||||
{
|
||||
diffLog->setDigest (m_state->getDigest());
|
||||
if (m_log.size () > 0)
|
||||
{
|
||||
m_log.get<sequenced> ().front ()->setNext (diffLog);
|
||||
}
|
||||
m_log.erase (m_state->getDigest()); // remove diff state with the same digest.
|
||||
// next pointers are still valid
|
||||
/// @todo Optimization
|
||||
m_log.get<sequenced> ().push_front (diffLog);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::addLocalNames (const Name &prefix, uint64_t session, uint64_t seq)
|
||||
{
|
||||
DiffStatePtr diff;
|
||||
{
|
||||
//cout << "Add local names" <<endl;
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
|
||||
|
||||
_LOG_DEBUG_ID ("addLocalNames (): old state " << *m_state->getDigest ());
|
||||
|
||||
SeqNo seqN (session, seq);
|
||||
m_state->update(info, seqN);
|
||||
|
||||
_LOG_DEBUG_ID ("addLocalNames (): new state " << *m_state->getDigest ());
|
||||
|
||||
diff = make_shared<DiffState>();
|
||||
diff->update(info, seqN);
|
||||
insertToDiffLog (diff);
|
||||
}
|
||||
|
||||
// _LOG_DEBUG_ID ("PIT size: " << m_syncInterestTable.size ());
|
||||
satisfyPendingSyncInterests (diff);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::remove(const Name &prefix)
|
||||
{
|
||||
DiffStatePtr diff;
|
||||
{
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
|
||||
m_state->remove(info);
|
||||
|
||||
// increment the sequence number for the forwarder node
|
||||
NameInfoConstPtr forwarderInfo = StdNameInfo::FindOrCreate(forwarderPrefix);
|
||||
|
||||
LeafContainer::iterator item = m_state->getLeaves ().find (forwarderInfo);
|
||||
SeqNo seqNo (0);
|
||||
if (item != m_state->getLeaves ().end ())
|
||||
{
|
||||
seqNo = (*item)->getSeq ();
|
||||
++seqNo;
|
||||
}
|
||||
m_state->update (forwarderInfo, seqNo);
|
||||
|
||||
diff = make_shared<DiffState>();
|
||||
diff->remove(info);
|
||||
diff->update(forwarderInfo, seqNo);
|
||||
|
||||
insertToDiffLog (diff);
|
||||
}
|
||||
|
||||
satisfyPendingSyncInterests (diff);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::sendSyncInterest ()
|
||||
{
|
||||
_LOG_DEBUG_ID("sendSyncInterest");
|
||||
|
||||
{
|
||||
m_outstandingInterestName = m_syncPrefix;
|
||||
ostringstream os;
|
||||
os << *m_state->getDigest();
|
||||
m_outstandingInterestName.append(os.str());
|
||||
_LOG_DEBUG_ID (">> I " << m_outstandingInterestName);
|
||||
}
|
||||
|
||||
_LOG_DEBUG_ID("sendSyncInterest: " << m_outstandingInterestName);
|
||||
|
||||
EventId eventId =
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(m_syncInterestReexpress) +
|
||||
ndn::time::milliseconds(GET_RANDOM(m_reexpressionJitter)),
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_reexpressingInterestId = eventId;
|
||||
|
||||
ndn::Interest interest(m_outstandingInterestName);
|
||||
interest.setMustBeFresh(true);
|
||||
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncLogic::onSyncData, this, _1, _2),
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1), // Nack
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::sendSyncRecoveryInterests (DigestConstPtr digest)
|
||||
{
|
||||
ostringstream os;
|
||||
os << *digest;
|
||||
|
||||
Name interestName = m_syncPrefix;
|
||||
interestName.append("recovery").append(os.str());
|
||||
|
||||
ndn::time::system_clock::Duration nextRetransmission =
|
||||
ndn::time::milliseconds(m_recoveryRetransmissionInterval + GET_RANDOM (m_reexpressionJitter));
|
||||
|
||||
m_recoveryRetransmissionInterval <<= 1;
|
||||
|
||||
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
|
||||
if (m_recoveryRetransmissionInterval < 100*1000) // <100 seconds
|
||||
m_reexpressingRecoveryInterestId =
|
||||
m_scheduler.scheduleEvent (nextRetransmission,
|
||||
bind (&SyncLogic::sendSyncRecoveryInterests, this, digest));
|
||||
|
||||
ndn::Interest interest(interestName);
|
||||
interest.setMustBeFresh(true);
|
||||
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncLogic::onSyncData, this, _1, _2),
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1), // Nack
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, StateConstPtr state)
|
||||
{
|
||||
SyncStateMsg msg;
|
||||
msg << (*state);
|
||||
sendSyncData(name, digest, msg);
|
||||
}
|
||||
|
||||
// pass in state msg instead of state, so that there is no need to lock the state until
|
||||
// this function returns
|
||||
void
|
||||
SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, SyncStateMsg &ssm)
|
||||
{
|
||||
_LOG_DEBUG_ID (">> D " << name);
|
||||
int size = ssm.ByteSize();
|
||||
char *wireData = new char[size];
|
||||
ssm.SerializeToArray(wireData, size);
|
||||
|
||||
//Data syncData(name);
|
||||
ndn::shared_ptr<ndn::Data> syncData = ndn::make_shared<ndn::Data>();
|
||||
syncData->setName(name);
|
||||
syncData->setContent(reinterpret_cast<const uint8_t*>(wireData), size);
|
||||
syncData->setFreshnessPeriod(ndn::time::seconds(m_syncResponseFreshness));
|
||||
|
||||
m_keyChain->sign(*syncData);
|
||||
|
||||
m_face->put(*syncData);
|
||||
|
||||
delete []wireData;
|
||||
|
||||
// checking if our own interest got satisfied
|
||||
bool satisfiedOwnInterest = false;
|
||||
{
|
||||
satisfiedOwnInterest = (m_outstandingInterestName == name);
|
||||
}
|
||||
|
||||
if (satisfiedOwnInterest)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Satisfied our own Interest. Re-expressing (hopefully with a new digest)");
|
||||
|
||||
ndn::time::system_clock::Duration after =
|
||||
ndn::time::milliseconds(GET_RANDOM(m_reexpressionJitter));
|
||||
// cout << "------------ reexpress interest after: " << after << endl;
|
||||
EventId eventId = m_scheduler.scheduleEvent (after,
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_reexpressingInterestId = eventId;
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
SyncLogic::getRootDigest()
|
||||
{
|
||||
ostringstream os;
|
||||
os << *m_state->getDigest();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
size_t
|
||||
SyncLogic::getNumberOfBranches () const
|
||||
{
|
||||
return m_state->getLeaves ().size ();
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::printState () const
|
||||
{
|
||||
BOOST_FOREACH (const shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
|
||||
{
|
||||
std::cout << *leaf << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, bool>
|
||||
SyncLogic::getBranchPrefixes() const
|
||||
{
|
||||
std::map<std::string, bool> m;
|
||||
|
||||
BOOST_FOREACH (const shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
|
||||
{
|
||||
std::string prefix = leaf->getInfo()->toString();
|
||||
// do not return forwarder prefix
|
||||
if (prefix != forwarderPrefix)
|
||||
{
|
||||
m.insert(pair<std::string, bool>(prefix, false));
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
* Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_LOGIC_H
|
||||
#define NLSR_NSYNC_SYNC_LOGIC_H
|
||||
|
||||
#include <boost/random.hpp>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/validator.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
#include "sync-interest-table.h"
|
||||
#include "sync-diff-state.h"
|
||||
#include "sync-full-state.h"
|
||||
#include "sync-std-name-info.h"
|
||||
|
||||
#include "sync-diff-state-container.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef HAVE_LOG4CXX
|
||||
#include <log4cxx/logger.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Sync {
|
||||
|
||||
struct MissingDataInfo {
|
||||
std::string prefix;
|
||||
SeqNo low;
|
||||
SeqNo high;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief A wrapper for SyncApp, which handles ccnx related things (process
|
||||
* interests and data)
|
||||
*/
|
||||
|
||||
class SyncLogic
|
||||
{
|
||||
public:
|
||||
typedef function< void (const std::vector<MissingDataInfo> & ) > LogicUpdateCallback;
|
||||
typedef function< void (const std::string &/*prefix*/ ) > LogicRemoveCallback;
|
||||
typedef function< void (const std::string &)> LogicPerBranchCallback;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param syncPrefix the name prefix to use for the Sync Interest
|
||||
* @param onUpdate function that will be called when new state is detected
|
||||
* @param onRemove function that will be called when state is removed
|
||||
* @param ccnxHandle ccnx handle
|
||||
* the app data when new remote names are learned
|
||||
*/
|
||||
SyncLogic (const ndn::Name& syncPrefix,
|
||||
ndn::shared_ptr<ndn::Validator> validator,
|
||||
ndn::shared_ptr<ndn::Face> face,
|
||||
LogicUpdateCallback onUpdate,
|
||||
LogicRemoveCallback onRemove);
|
||||
|
||||
SyncLogic (const ndn::Name& syncPrefix,
|
||||
ndn::shared_ptr<ndn::Validator> validator,
|
||||
ndn::shared_ptr<ndn::Face> face,
|
||||
LogicPerBranchCallback onUpdateBranch);
|
||||
|
||||
~SyncLogic ();
|
||||
|
||||
/**
|
||||
* a wrapper for the same func in SyncApp
|
||||
*/
|
||||
void addLocalNames (const ndn::Name &prefix, uint64_t session, uint64_t seq);
|
||||
|
||||
/**
|
||||
* @brief remove a participant's subtree from the sync tree
|
||||
* @param prefix the name prefix for the participant
|
||||
*/
|
||||
void remove (const ndn::Name &prefix);
|
||||
|
||||
std::string
|
||||
getRootDigest();
|
||||
|
||||
#ifdef _DEBUG
|
||||
ndn::Scheduler &
|
||||
getScheduler () { return m_scheduler; }
|
||||
#endif
|
||||
|
||||
void
|
||||
printState () const;
|
||||
|
||||
std::map<std::string, bool>
|
||||
getBranchPrefixes() const;
|
||||
|
||||
private:
|
||||
void
|
||||
delayedChecksLoop ();
|
||||
|
||||
void
|
||||
onSyncInterest (const ndn::Name& prefix, const ndn::Interest& interest);
|
||||
|
||||
void
|
||||
onSyncRegisterSucceed(const ndn::Name& prefix);
|
||||
|
||||
void
|
||||
onSyncRegisterFailed(const ndn::Name& prefix, const std::string& msg);
|
||||
|
||||
void
|
||||
onSyncData(const ndn::Interest& interest, const ndn::Data& data);
|
||||
|
||||
void
|
||||
onSyncTimeout(const ndn::Interest& interest);
|
||||
|
||||
void
|
||||
onSyncDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);
|
||||
|
||||
void
|
||||
onSyncDataValidated(const ndn::shared_ptr<const ndn::Data>& data);
|
||||
|
||||
void
|
||||
processSyncInterest (const ndn::Name &name,
|
||||
DigestConstPtr digest, bool timedProcessing=false);
|
||||
|
||||
void
|
||||
processSyncData (const ndn::Name &name,
|
||||
DigestConstPtr digest, const char *wireData, size_t len);
|
||||
|
||||
void
|
||||
processSyncRecoveryInterest (const ndn::Name &name,
|
||||
DigestConstPtr digest);
|
||||
|
||||
void
|
||||
insertToDiffLog (DiffStatePtr diff);
|
||||
|
||||
void
|
||||
satisfyPendingSyncInterests (DiffStateConstPtr diff);
|
||||
|
||||
tuple<DigestConstPtr, std::string>
|
||||
convertNameToDigestAndType (const ndn::Name &name);
|
||||
|
||||
void
|
||||
sendSyncInterest ();
|
||||
|
||||
void
|
||||
sendSyncRecoveryInterests (DigestConstPtr digest);
|
||||
|
||||
void
|
||||
sendSyncData (const ndn::Name &name,
|
||||
DigestConstPtr digest, StateConstPtr state);
|
||||
|
||||
void
|
||||
sendSyncData (const ndn::Name &name,
|
||||
DigestConstPtr digest, SyncStateMsg &msg);
|
||||
|
||||
size_t
|
||||
getNumberOfBranches () const;
|
||||
|
||||
private:
|
||||
FullStatePtr m_state;
|
||||
|
||||
DiffStateContainer m_log;
|
||||
|
||||
ndn::Name m_outstandingInterestName;
|
||||
SyncInterestTable m_syncInterestTable;
|
||||
|
||||
ndn::Name m_syncPrefix;
|
||||
LogicUpdateCallback m_onUpdate;
|
||||
LogicRemoveCallback m_onRemove;
|
||||
LogicPerBranchCallback m_onUpdateBranch;
|
||||
bool m_perBranch;
|
||||
std::shared_ptr<ndn::Validator> m_validator;
|
||||
std::shared_ptr<ndn::KeyChain> m_keyChain;
|
||||
std::shared_ptr<ndn::Face> m_face;
|
||||
const ndn::RegisteredPrefixId* m_syncRegisteredPrefixId;
|
||||
|
||||
ndn::Scheduler m_scheduler;
|
||||
|
||||
boost::mt19937 m_randomGenerator;
|
||||
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_rangeUniformRandom;
|
||||
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_reexpressionJitter;
|
||||
|
||||
|
||||
static const int m_unknownDigestStoreTime = 10; // seconds
|
||||
static const int m_syncResponseFreshness; // MUST BE dividable by 1000!!!
|
||||
static const int m_syncInterestReexpress; // seconds
|
||||
static const int m_defaultRecoveryRetransmitInterval = 200; // milliseconds
|
||||
|
||||
|
||||
uint32_t m_recoveryRetransmissionInterval; // milliseconds
|
||||
|
||||
ndn::EventId m_delayedInterestProcessingId;
|
||||
ndn::EventId m_reexpressingInterestId;
|
||||
ndn::EventId m_reexpressingRecoveryInterestId;
|
||||
|
||||
std::string m_instanceId;
|
||||
static int m_instanceCounter;
|
||||
};
|
||||
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_LOGIC_H
|
||||
@@ -1,32 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-name-info.h"
|
||||
|
||||
// #include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
NameInfo::NameMap NameInfo::m_names;
|
||||
size_t NameInfo::m_ids = 0;
|
||||
|
||||
} // Sync
|
||||
@@ -1,102 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_NAME_INFO_H
|
||||
#define NLSR_NSYNC_SYNC_NAME_INFO_H
|
||||
|
||||
#include "sync-common.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "sync-digest.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* @ingroup sync
|
||||
* @brief Templated class for the leaf name
|
||||
*/
|
||||
class NameInfo
|
||||
{
|
||||
private:
|
||||
typedef weak_ptr<const NameInfo> const_weak_ptr;
|
||||
|
||||
public:
|
||||
virtual ~NameInfo () { };
|
||||
|
||||
/**
|
||||
* @brief Get ID of the record (should be locally-unique, but not really necessary---this is be used for hashing purposes)
|
||||
*/
|
||||
size_t
|
||||
getHashId () const { return m_id; }
|
||||
|
||||
/**
|
||||
* @brief Check if two names are equal
|
||||
* @param info name to check with
|
||||
*/
|
||||
virtual bool
|
||||
operator == (const NameInfo &info) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Check if two names are in order
|
||||
* @param info name to check with
|
||||
*/
|
||||
virtual bool
|
||||
operator < (const NameInfo &info) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Calculates digest of the name
|
||||
*/
|
||||
const Digest &
|
||||
getDigest () const { return m_digest; }
|
||||
|
||||
/**
|
||||
* @brief Convert prefix to string
|
||||
* @returns string representation of prefix
|
||||
*/
|
||||
virtual std::string
|
||||
toString () const = 0;
|
||||
|
||||
protected:
|
||||
// actual stuff
|
||||
size_t m_id; ///< @brief Identifies NameInfo throughout the library (for hash container, doesn't need to be strictly unique)
|
||||
Digest m_digest;
|
||||
|
||||
// static stuff
|
||||
typedef std::map<std::string, const_weak_ptr> NameMap;
|
||||
static size_t m_ids;
|
||||
static NameMap m_names;
|
||||
};
|
||||
|
||||
typedef shared_ptr<NameInfo> NameInfoPtr;
|
||||
typedef shared_ptr<const NameInfo> NameInfoConstPtr;
|
||||
|
||||
inline std::ostream &
|
||||
operator << (std::ostream &os, const NameInfo &info)
|
||||
{
|
||||
os << info.toString ();
|
||||
return os;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_NAME_INFO_H
|
||||
@@ -1,36 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-seq-no.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
DigestConstPtr
|
||||
SeqNo::getDigest () const
|
||||
{
|
||||
DigestPtr digest = make_shared<Digest> ();
|
||||
*digest << m_session << m_seq;
|
||||
digest->finalize ();
|
||||
return digest;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,198 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
* Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_SEQ_NO_H
|
||||
#define NLSR_NSYNC_SYNC_SEQ_NO_H
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "sync-digest.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* @ingroup sync
|
||||
* @brief Sequence number abstraction
|
||||
*/
|
||||
class SeqNo
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor. Creates an zero sequence number with zero session ID (basically is an invalid object)
|
||||
*/
|
||||
SeqNo ()
|
||||
: m_valid (false)
|
||||
, m_session (0)
|
||||
, m_seq (0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
* @param seq sequence number object to copy from
|
||||
*/
|
||||
SeqNo (const SeqNo &seq)
|
||||
{
|
||||
*this = seq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment operator
|
||||
* @param seq sequence number object to copy from
|
||||
*/
|
||||
SeqNo &
|
||||
operator = (const SeqNo &seq)
|
||||
{
|
||||
m_valid = seq.m_valid;
|
||||
m_session = seq.m_session;
|
||||
m_seq = seq.m_seq;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor with just sequence number. Session assumed to be zero
|
||||
* @param seq Sequence number
|
||||
*/
|
||||
SeqNo (uint64_t seq)
|
||||
: m_valid (true)
|
||||
, m_session (0)
|
||||
, m_seq (seq)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* @brief Constructor with session and sequence id
|
||||
* @param session Session ID
|
||||
* @param seq Sequence number
|
||||
*/
|
||||
SeqNo (uint64_t session, uint64_t seq)
|
||||
: m_valid (true)
|
||||
, m_session (session)
|
||||
, m_seq (seq)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* @brief Get sequence number digest
|
||||
*
|
||||
* Digest will be calculated every time it is requested
|
||||
*/
|
||||
DigestConstPtr
|
||||
getDigest () const;
|
||||
|
||||
/**
|
||||
* @brief Compare if one sequence number is lower
|
||||
* @param seq Another sequence number to compare with
|
||||
*
|
||||
* tuple (session1, seq1) is less than (session2, seq2) in two cases:
|
||||
* 1. session1 < session2
|
||||
* 2. session1 == session2 and seq1 < seq2
|
||||
*/
|
||||
bool
|
||||
operator < (const SeqNo &seq) const
|
||||
{
|
||||
return m_session < seq.m_session || (m_session == seq.m_session && m_seq < seq.m_seq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compare if two sequence numbers are equal
|
||||
* @param seq Another sequence number to compare with
|
||||
*/
|
||||
bool
|
||||
operator == (const SeqNo &seq) const
|
||||
{
|
||||
return m_session == seq.m_session && m_seq == seq.m_seq;
|
||||
}
|
||||
|
||||
bool
|
||||
operator <= (const SeqNo &seq) const
|
||||
{
|
||||
return m_session == seq.m_session && m_seq <= seq.m_seq;
|
||||
}
|
||||
|
||||
SeqNo &
|
||||
operator ++ ()
|
||||
{
|
||||
if (m_valid) {
|
||||
m_seq ++;
|
||||
}
|
||||
else {
|
||||
m_valid = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
isValid () const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get session id
|
||||
*/
|
||||
uint64_t getSession () const
|
||||
{ return m_session; }
|
||||
|
||||
/**
|
||||
* @brief Get sequence number
|
||||
*/
|
||||
uint64_t getSeq () const
|
||||
{ return m_seq; }
|
||||
|
||||
/**
|
||||
* @brief Set sequence number
|
||||
*/
|
||||
void
|
||||
setSeq(uint64_t seq)
|
||||
{ m_seq = seq; }
|
||||
|
||||
private:
|
||||
bool m_valid;
|
||||
|
||||
/**
|
||||
* @brief Session ID (e.g., after crash, application will choose new session ID.
|
||||
*
|
||||
* Note that session IDs for the same name should always increase. So, the good choice
|
||||
* for the session ID is client's timestamp
|
||||
*/
|
||||
uint64_t m_session;
|
||||
|
||||
/**
|
||||
* @brief Sequence number
|
||||
*
|
||||
* Sequence number for a session always starts with 0 and goes to max value.
|
||||
*
|
||||
* For now, wrapping sequence number after max to zero is not supported
|
||||
*/
|
||||
uint64_t m_seq;
|
||||
};
|
||||
|
||||
inline std::ostream &
|
||||
operator << (std::ostream &os, const SeqNo &seqno)
|
||||
{
|
||||
os << "<session>" << seqno.getSession () << "</session><seqno>" << seqno.getSeq () << "</seqno>";
|
||||
return os;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_SEQ_NO_H
|
||||
@@ -1,184 +0,0 @@
|
||||
/* -*- Mode: C32++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-socket.h"
|
||||
#include "sync-logging.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using ndn::Data;
|
||||
using ndn::Face;
|
||||
using ndn::KeyChain;
|
||||
using ndn::Name;
|
||||
using ndn::OnDataValidated;
|
||||
using ndn::OnDataValidationFailed;
|
||||
using ndn::Validator;
|
||||
|
||||
INIT_LOGGER ("SyncSocket");
|
||||
|
||||
namespace Sync {
|
||||
|
||||
using ndn::shared_ptr;
|
||||
using ndn::make_shared;
|
||||
|
||||
SyncSocket::SyncSocket (const Name &syncPrefix,
|
||||
shared_ptr<Validator> validator,
|
||||
shared_ptr<Face> face,
|
||||
NewDataCallback dataCallback,
|
||||
RemoveCallback rmCallback )
|
||||
: m_newDataCallback(dataCallback)
|
||||
, m_validator(validator)
|
||||
, m_keyChain(new KeyChain())
|
||||
, m_face(face)
|
||||
, m_syncLogic (syncPrefix,
|
||||
validator,
|
||||
face,
|
||||
bind(&SyncSocket::passCallback, this, _1),
|
||||
rmCallback)
|
||||
{
|
||||
}
|
||||
|
||||
SyncSocket::~SyncSocket()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
SyncSocket::publishData(const Name &prefix, uint64_t session,
|
||||
const char *buf, size_t len,
|
||||
int freshness,uint64_t seq)
|
||||
{
|
||||
shared_ptr<Data> data = make_shared<Data>();
|
||||
data->setContent(reinterpret_cast<const uint8_t*>(buf), len);
|
||||
data->setFreshnessPeriod(ndn::time::seconds(freshness));
|
||||
|
||||
m_face->getIoService().post(bind(&SyncSocket::publishDataInternal, this,
|
||||
data, prefix, session,seq));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::publishDataInternal(shared_ptr<Data> data,
|
||||
const Name &prefix, uint64_t session, uint64_t seq)
|
||||
{
|
||||
uint64_t sequence = seq;
|
||||
Name dataName = prefix;
|
||||
dataName.append(boost::lexical_cast<string>(session))
|
||||
.append(boost::lexical_cast<string>(sequence));
|
||||
data->setName(dataName);
|
||||
|
||||
m_keyChain->sign(*data);
|
||||
m_face->put(*data);
|
||||
|
||||
SeqNo s(session, sequence + 1);
|
||||
|
||||
m_sequenceLog[prefix] = s;
|
||||
m_syncLogic.addLocalNames (prefix, session, sequence);
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::fetchData(const Name &prefix, const SeqNo &seq,
|
||||
const OnDataValidated& onValidated, int retry)
|
||||
{
|
||||
Name interestName = prefix;
|
||||
interestName.append(boost::lexical_cast<string>(seq.getSession()))
|
||||
.append(boost::lexical_cast<string>(seq.getSeq()));
|
||||
|
||||
const OnDataValidationFailed& onValidationFailed =
|
||||
bind(&SyncSocket::onDataValidationFailed, this, _1);
|
||||
|
||||
ndn::Interest interest(interestName);
|
||||
interest.setMustBeFresh(true);
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncSocket::onData, this, _1, _2,
|
||||
onValidated, onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout, this, _1, retry, // Nack
|
||||
onValidated, onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout, this, _1, retry,
|
||||
onValidated, onValidationFailed));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::onData(const ndn::Interest& interest, const Data& data,
|
||||
const OnDataValidated& onValidated,
|
||||
const OnDataValidationFailed& onValidationFailed)
|
||||
{
|
||||
m_validator->validate(data, onValidated, onValidationFailed);
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::onDataTimeout(const ndn::Interest& interest,
|
||||
int retry,
|
||||
const OnDataValidated& onValidated,
|
||||
const OnDataValidationFailed& onValidationFailed)
|
||||
{
|
||||
if(retry > 0)
|
||||
{
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncSocket::onData,
|
||||
this,
|
||||
_1,
|
||||
_2,
|
||||
onValidated,
|
||||
onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout,
|
||||
this,
|
||||
_1,
|
||||
retry - 1,
|
||||
onValidated,
|
||||
onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout,
|
||||
this,
|
||||
_1,
|
||||
retry - 1,
|
||||
onValidated,
|
||||
onValidationFailed));
|
||||
|
||||
}
|
||||
else
|
||||
_LOG_DEBUG("interest eventually time out!");
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::onDataValidationFailed(const shared_ptr<const Data>& data)
|
||||
{
|
||||
_LOG_DEBUG("data cannot be verified!");
|
||||
}
|
||||
|
||||
|
||||
uint64_t
|
||||
SyncSocket::getNextSeq (const Name &prefix, uint64_t session)
|
||||
{
|
||||
SequenceLog::iterator i = m_sequenceLog.find (prefix);
|
||||
|
||||
if (i != m_sequenceLog.end ())
|
||||
{
|
||||
SeqNo s = i->second;
|
||||
if (s.getSession() == session)
|
||||
return s.getSeq();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}//Sync
|
||||
@@ -1,134 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_SOCKET_H
|
||||
#define NLSR_NSYNC_SYNC_SOCKET_H
|
||||
|
||||
#include "sync-common.h"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/validator.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
|
||||
#include "sync-logic.h"
|
||||
#include "sync-seq-no.h"
|
||||
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief A simple interface to interact with client code
|
||||
*/
|
||||
class SyncSocket
|
||||
{
|
||||
public:
|
||||
typedef ndn::function<void(const std::vector<MissingDataInfo> &, SyncSocket *)> NewDataCallback;
|
||||
typedef ndn::function<void(const std::string &/*prefix*/)> RemoveCallback;
|
||||
|
||||
/**
|
||||
* @brief the constructor for SyncAppSocket; the parameter syncPrefix
|
||||
* should be passed to the constructor of m_syncAppWrapper; the other
|
||||
* parameter should be passed to the constructor of m_fetcher; furthermore,
|
||||
* the fetch function of m_fetcher should be a second paramter passed to
|
||||
* the constructor of m_syncAppWrapper, so that m_syncAppWrapper can tell
|
||||
* m_fetcher to fetch the actual app data after it learns the names
|
||||
*
|
||||
* @param syncPrefix the name prefix for Sync Interest
|
||||
* @param dataCallback the callback to process data
|
||||
*/
|
||||
SyncSocket (const ndn::Name &syncPrefix,
|
||||
ndn::shared_ptr<ndn::Validator> validator,
|
||||
ndn::shared_ptr<ndn::Face> face,
|
||||
NewDataCallback dataCallback,
|
||||
RemoveCallback rmCallback);
|
||||
|
||||
~SyncSocket ();
|
||||
|
||||
bool
|
||||
publishData(const ndn::Name &prefix, uint64_t session, const char *buf, size_t len,
|
||||
int freshness,uint64_t seq);
|
||||
|
||||
void
|
||||
remove (const ndn::Name &prefix)
|
||||
{ m_syncLogic.remove(prefix); }
|
||||
|
||||
void
|
||||
fetchData(const ndn::Name &prefix, const SeqNo &seq,
|
||||
const ndn::OnDataValidated& onValidated, int retry = 0);
|
||||
|
||||
std::string
|
||||
getRootDigest()
|
||||
{ return m_syncLogic.getRootDigest(); }
|
||||
|
||||
uint64_t
|
||||
getNextSeq (const ndn::Name &prefix, uint64_t session);
|
||||
|
||||
SyncLogic &
|
||||
getLogic ()
|
||||
{ return m_syncLogic; }
|
||||
|
||||
// make this a static function so we don't have to create socket instance without
|
||||
// knowing the local prefix. it's a wrong place for this function anyway
|
||||
static std::string
|
||||
GetLocalPrefix ();
|
||||
|
||||
private:
|
||||
void
|
||||
publishDataInternal(ndn::shared_ptr<ndn::Data> data,
|
||||
const ndn::Name &prefix, uint64_t session,uint64_t seq);
|
||||
|
||||
void
|
||||
passCallback(const std::vector<MissingDataInfo> &v)
|
||||
{
|
||||
m_newDataCallback(v, this);
|
||||
}
|
||||
|
||||
void
|
||||
onData(const ndn::Interest& interest, const ndn::Data& data,
|
||||
const ndn::OnDataValidated& onValidated,
|
||||
const ndn::OnDataValidationFailed& onValidationFailed);
|
||||
|
||||
void
|
||||
onDataTimeout(const ndn::Interest& interest,
|
||||
int retry,
|
||||
const ndn::OnDataValidated& onValidated,
|
||||
const ndn::OnDataValidationFailed& onValidationFailed);
|
||||
|
||||
void
|
||||
onDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);
|
||||
|
||||
private:
|
||||
typedef std::map<ndn::Name, SeqNo> SequenceLog;
|
||||
NewDataCallback m_newDataCallback;
|
||||
SequenceLog m_sequenceLog;
|
||||
ndn::shared_ptr<ndn::Validator> m_validator;
|
||||
ndn::shared_ptr<ndn::KeyChain> m_keyChain;
|
||||
ndn::shared_ptr<ndn::Face> m_face;
|
||||
SyncLogic m_syncLogic;
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_SOCKET_H
|
||||
@@ -1,101 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_STATE_LEAF_CONTAINER_H
|
||||
#define NLSR_NSYNC_SYNC_STATE_LEAF_CONTAINER_H
|
||||
|
||||
#include "sync-leaf.h"
|
||||
#include "sync-name-info.h"
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
// #include <boost/multi_index/tag.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
// #include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
// #include <boost/multi_index/random_access_index.hpp>
|
||||
// #include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
struct NameInfoHash : public std::unary_function<NameInfo, std::size_t>
|
||||
{
|
||||
std::size_t
|
||||
operator() (NameInfoConstPtr prefix) const
|
||||
{
|
||||
return prefix->getHashId ();
|
||||
}
|
||||
};
|
||||
|
||||
struct NameInfoEqual : public std::unary_function<NameInfo, std::size_t>
|
||||
{
|
||||
bool
|
||||
operator() (NameInfoConstPtr prefix1, NameInfoConstPtr prefix2) const
|
||||
{
|
||||
return *prefix1 == *prefix2;
|
||||
}
|
||||
};
|
||||
|
||||
struct NameInfoCompare : public std::unary_function<NameInfo, std::size_t>
|
||||
{
|
||||
bool
|
||||
operator() (NameInfoConstPtr prefix1, NameInfoConstPtr prefix2) const
|
||||
{
|
||||
return *prefix1 < *prefix2;
|
||||
}
|
||||
};
|
||||
|
||||
/// @cond include_hidden
|
||||
struct hashed { };
|
||||
struct ordered { };
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief Container for SYNC leaves
|
||||
*/
|
||||
struct LeafContainer : public mi::multi_index_container<
|
||||
LeafPtr,
|
||||
mi::indexed_by<
|
||||
// For fast access to elements using NameInfo
|
||||
mi::hashed_unique<
|
||||
mi::tag<hashed>,
|
||||
mi::const_mem_fun<Leaf, NameInfoConstPtr, &Leaf::getInfo>,
|
||||
NameInfoHash,
|
||||
NameInfoEqual
|
||||
>,
|
||||
|
||||
mi::ordered_unique<
|
||||
mi::tag<ordered>,
|
||||
mi::const_mem_fun<Leaf, NameInfoConstPtr, &Leaf::getInfo>,
|
||||
NameInfoCompare
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_STATE_LEAF_CONTAINER_H
|
||||
@@ -1,169 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-state.h"
|
||||
#include "sync-diff-leaf.h"
|
||||
#include "sync-std-name-info.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
typedef boost::error_info<struct tag_errmsg, std::string> info_str;
|
||||
|
||||
using namespace Sync::Error;
|
||||
using boost::lexical_cast;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/*
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const State &state)
|
||||
{
|
||||
os << "<state>"; DEBUG_ENDL;
|
||||
|
||||
BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
|
||||
{
|
||||
shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
|
||||
if (diffLeaf != 0)
|
||||
{
|
||||
os << "<item action=\"" << diffLeaf->getOperation () << "\">"; DEBUG_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "<item>"; DEBUG_ENDL;
|
||||
}
|
||||
os << "<name>" << *leaf->getInfo () << "</name>"; DEBUG_ENDL;
|
||||
if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
|
||||
{
|
||||
os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
|
||||
}
|
||||
os << "</item>"; DEBUG_ENDL;
|
||||
}
|
||||
os << "</state>";
|
||||
}
|
||||
*/
|
||||
|
||||
SyncStateMsg &
|
||||
operator << (SyncStateMsg &ossm, const State &state)
|
||||
{
|
||||
BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
|
||||
{
|
||||
SyncState *oss = ossm.add_ss();
|
||||
shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
|
||||
if (diffLeaf != 0 && diffLeaf->getOperation() != UPDATE)
|
||||
{
|
||||
oss->set_type(SyncState::DELETE);
|
||||
}
|
||||
else
|
||||
{
|
||||
oss->set_type(SyncState::UPDATE);
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os << *leaf->getInfo();
|
||||
oss->set_name(os.str());
|
||||
|
||||
if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
|
||||
{
|
||||
SyncState::SeqNo *seqNo = oss->mutable_seqno();
|
||||
seqNo->set_session(leaf->getSeq().getSession());
|
||||
seqNo->set_seq(leaf->getSeq().getSeq());
|
||||
}
|
||||
}
|
||||
return ossm;
|
||||
}
|
||||
|
||||
/*
|
||||
std::istream &
|
||||
operator >> (std::istream &in, State &state)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
in >> doc;
|
||||
|
||||
if (doc.RootElement() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("Empty XML"));
|
||||
|
||||
for (TiXmlElement *iterator = doc.RootElement()->FirstChildElement ("item");
|
||||
iterator != 0;
|
||||
iterator = iterator->NextSiblingElement("item"))
|
||||
{
|
||||
TiXmlElement *name = iterator->FirstChildElement ("name");
|
||||
if (name == 0 || name->GetText() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<name> element is missing"));
|
||||
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate (name->GetText());
|
||||
|
||||
if (iterator->Attribute("action") == 0 || strcmp(iterator->Attribute("action"), "update") == 0)
|
||||
{
|
||||
TiXmlElement *seq = iterator->FirstChildElement ("seq");
|
||||
if (seq == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seq> element is missing"));
|
||||
|
||||
TiXmlElement *session = seq->FirstChildElement ("session");
|
||||
TiXmlElement *seqno = seq->FirstChildElement ("seqno");
|
||||
|
||||
if (session == 0 || session->GetText() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<session> element is missing"));
|
||||
if (seqno == 0 || seqno->GetText() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seqno> element is missing"));
|
||||
|
||||
state.update (info, SeqNo (
|
||||
lexical_cast<uint32_t> (session->GetText()),
|
||||
lexical_cast<uint32_t> (seqno->GetText())
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
state.remove (info);
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
*/
|
||||
|
||||
SyncStateMsg &
|
||||
operator >> (SyncStateMsg &issm, State &state)
|
||||
{
|
||||
int n = issm.ss_size();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
const SyncState &ss = issm.ss(i);
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate (ss.name());
|
||||
if (ss.type() == SyncState::UPDATE)
|
||||
{
|
||||
uint64_t session = lexical_cast<uint64_t>(ss.seqno().session());
|
||||
uint64_t seq = lexical_cast<uint64_t>(ss.seqno().seq());
|
||||
SeqNo seqNo(session, seq);
|
||||
state.update(info, seqNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.remove(info);
|
||||
}
|
||||
}
|
||||
return issm;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_STATE_H
|
||||
#define NLSR_NSYNC_SYNC_STATE_H
|
||||
|
||||
#include "sync-state-leaf-container.h"
|
||||
#include <boost/exception/all.hpp>
|
||||
#include "sync-state.pb.h"
|
||||
|
||||
/**
|
||||
* \defgroup sync SYNC protocol
|
||||
*
|
||||
* Implementation of SYNC protocol
|
||||
*/
|
||||
namespace Sync {
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief this prefix will be used for the dummy node which increases its sequence number whenever
|
||||
* a remove operation happens; this is to prevent the reversion of root digest when we prune
|
||||
* a branch, i.e. help the root digest to be forward only
|
||||
* No corresponding data msg would be published and no attempt would be made to retrieve the
|
||||
* data msg
|
||||
*/
|
||||
const std::string forwarderPrefix = "/d0n0t18ak/t0ps8cr8t";
|
||||
|
||||
class State;
|
||||
typedef shared_ptr<State> StatePtr;
|
||||
typedef shared_ptr<State> StateConstPtr;
|
||||
|
||||
/**
|
||||
* \ingroup sync
|
||||
* @brief Container for state leaves and definition of the abstract interface to work with State objects
|
||||
*/
|
||||
class State
|
||||
{
|
||||
public:
|
||||
virtual ~State () { };
|
||||
|
||||
/**
|
||||
* @brief Add or update leaf to the state tree
|
||||
*
|
||||
* @param info name of the leaf
|
||||
* @param seq sequence number of the leaf
|
||||
*/
|
||||
virtual tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
|
||||
update (NameInfoConstPtr info, const SeqNo &seq) = 0;
|
||||
|
||||
/**
|
||||
* @brief Remove leaf from the state tree
|
||||
* @param info name of the leaf
|
||||
*/
|
||||
virtual bool
|
||||
remove (NameInfoConstPtr info) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get state leaves
|
||||
*/
|
||||
const LeafContainer &
|
||||
getLeaves () const
|
||||
{ return m_leaves; }
|
||||
|
||||
protected:
|
||||
LeafContainer m_leaves;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Formats a protobuf SyncStateMsg msg
|
||||
* @param oss output SyncStateMsg msg
|
||||
* @param state state
|
||||
* @returns output SyncStateMsg msg
|
||||
*/
|
||||
SyncStateMsg &
|
||||
operator << (SyncStateMsg &ossm, const State &state);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parse a protobuf SyncStateMsg msg
|
||||
* @param iss input SyncStateMsg msg
|
||||
* @param state state
|
||||
* @returns SyncStateMsg msg
|
||||
*/
|
||||
SyncStateMsg &
|
||||
operator >> (SyncStateMsg &issm, State &state);
|
||||
|
||||
namespace Error {
|
||||
/**
|
||||
* @brief Will be thrown when data cannot be properly decoded to SyncStateMsg
|
||||
*/
|
||||
struct SyncStateMsgDecodingFailure : virtual boost::exception, virtual std::exception { };
|
||||
}
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_STATE_H
|
||||
@@ -1,24 +0,0 @@
|
||||
package Sync;
|
||||
|
||||
message SyncState
|
||||
{
|
||||
required string name = 1;
|
||||
enum ActionType
|
||||
{
|
||||
UPDATE = 0;
|
||||
DELETE = 1;
|
||||
OTHER = 2;
|
||||
}
|
||||
required ActionType type = 2;
|
||||
message SeqNo
|
||||
{
|
||||
required uint64 seq = 1;
|
||||
required uint64 session = 2;
|
||||
}
|
||||
optional SeqNo seqno = 3;
|
||||
}
|
||||
|
||||
message SyncStateMsg
|
||||
{
|
||||
repeated SyncState ss = 1;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-std-name-info.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
|
||||
NameInfoConstPtr
|
||||
StdNameInfo::FindOrCreate (const std::string &key)
|
||||
{
|
||||
// std::cout << "FindOrCreate: " << m_names.size () << "\n";
|
||||
|
||||
NameInfoConstPtr ret;
|
||||
|
||||
NameMap::iterator item = m_names.find (key);
|
||||
if (item != m_names.end ())
|
||||
{
|
||||
ret = item->second.lock ();
|
||||
BOOST_ASSERT (ret != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NameInfoPtr (new StdNameInfo (key));
|
||||
weak_ptr<const NameInfo> value (ret);
|
||||
std::pair<NameMap::iterator,bool> inserted =
|
||||
m_names.insert (make_pair (key, value));
|
||||
|
||||
BOOST_ASSERT (inserted.second); // previous call has to insert value
|
||||
item = inserted.first;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
StdNameInfo::StdNameInfo (const std::string &name)
|
||||
: m_name (name)
|
||||
{
|
||||
m_id = m_ids ++; // set ID for a newly inserted element
|
||||
m_digest << name;
|
||||
m_digest.finalize ();
|
||||
|
||||
// std::cout << "StdNameInfo: " << name << " = " << m_id << "\n";
|
||||
}
|
||||
|
||||
StdNameInfo::~StdNameInfo ()
|
||||
{
|
||||
// cout << "Destructor for " << m_name << "\n";
|
||||
m_names.erase (toString ());
|
||||
}
|
||||
|
||||
std::string
|
||||
StdNameInfo::toString () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
bool
|
||||
StdNameInfo::operator == (const NameInfo &info) const
|
||||
{
|
||||
return m_name == dynamic_cast<const StdNameInfo&> (info).m_name;
|
||||
}
|
||||
|
||||
bool
|
||||
StdNameInfo::operator < (const NameInfo &info) const
|
||||
{
|
||||
return m_name < dynamic_cast<const StdNameInfo&> (info).m_name;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,74 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NSYNC_SYNC_STD_NAME_INFO_H
|
||||
#define NLSR_NSYNC_SYNC_STD_NAME_INFO_H
|
||||
|
||||
#include "sync-name-info.h"
|
||||
#include <string>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
class StdNameInfo : public NameInfo
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Lookup existing or create new NameInfo object
|
||||
* @param name routable prefix
|
||||
*/
|
||||
static NameInfoConstPtr
|
||||
FindOrCreate (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Destructor which will clean up m_names structure
|
||||
*/
|
||||
virtual ~StdNameInfo ();
|
||||
|
||||
// from NameInfo
|
||||
virtual bool
|
||||
operator == (const NameInfo &info) const;
|
||||
|
||||
virtual bool
|
||||
operator < (const NameInfo &info) const;
|
||||
|
||||
virtual std::string
|
||||
toString () const;
|
||||
|
||||
private:
|
||||
// implementing a singleton pattern.
|
||||
/**
|
||||
* @brief Disabled default constructor. NameInfo object should be created through FindOrCreate static call.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Disabled default
|
||||
*/
|
||||
StdNameInfo () {}
|
||||
StdNameInfo& operator = (const StdNameInfo &info) { (void)info; return *this; }
|
||||
StdNameInfo (const std::string &name);
|
||||
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // NLSR_NSYNC_SYNC_STD_NAME_INFO_H
|
||||
@@ -156,22 +156,19 @@ SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix)
|
||||
// of the object
|
||||
std::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
|
||||
|
||||
m_syncSocket = std::make_shared<Sync::SyncSocket>(m_syncPrefix, m_validator, facePtr,
|
||||
std::bind(&SyncLogicHandler::onNsyncUpdate,
|
||||
this, _1, _2),
|
||||
std::bind(&SyncLogicHandler::onNsyncRemoval,
|
||||
this, _1));
|
||||
m_syncSocket = std::make_shared<chronosync::Socket>(m_syncPrefix, m_updatePrefix, *facePtr,
|
||||
bind(&SyncLogicHandler::onNsyncUpdate, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::onNsyncUpdate(const vector<Sync::MissingDataInfo>& v, Sync::SyncSocket* socket)
|
||||
SyncLogicHandler::onNsyncUpdate(const vector<chronosync::MissingDataInfo>& v)
|
||||
{
|
||||
_LOG_DEBUG("Received Nsync update event");
|
||||
|
||||
for (size_t i = 0; i < v.size(); i++){
|
||||
_LOG_DEBUG("Update Name: " << v[i].prefix << " Seq no: " << v[i].high.getSeq());
|
||||
_LOG_DEBUG("Update Name: " << v[i].session.getPrefix(-1).toUri() << " Seq no: " << v[i].high);
|
||||
|
||||
SyncUpdate update(v[i].prefix, v[i].high.getSeq());
|
||||
SyncUpdate update(v[i].session.getPrefix(-1), v[i].high);
|
||||
|
||||
processUpdateFromSync(update);
|
||||
}
|
||||
@@ -299,7 +296,8 @@ SyncLogicHandler::publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqN
|
||||
ndn::Name updateName(updatePrefix);
|
||||
string data("NoData");
|
||||
|
||||
m_syncSocket->publishData(updateName.toUri(), 0, data.c_str(), data.size(), 1000, seqNo);
|
||||
m_syncSocket->publishData(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(),
|
||||
ndn::time::milliseconds(1000), seqNo, updateName);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/validator-null.hpp>
|
||||
#include <nsync/sync-socket.h>
|
||||
#include <ChronoSync/socket.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
@@ -60,10 +60,9 @@ public:
|
||||
/*! \brief Simple wrapper function to handle updates from Sync.
|
||||
|
||||
\param v The information that Sync has acquired.
|
||||
\param socket The socket that Sync is using to synchronize updates.
|
||||
*/
|
||||
void
|
||||
onNsyncUpdate(const std::vector<Sync::MissingDataInfo>& v, Sync::SyncSocket* socket);
|
||||
onNsyncUpdate(const std::vector<chronosync::MissingDataInfo>& v);
|
||||
|
||||
void
|
||||
onNsyncRemoval(const std::string& prefix);
|
||||
@@ -93,7 +92,7 @@ private:
|
||||
private:
|
||||
std::shared_ptr<ndn::ValidatorNull> m_validator;
|
||||
ndn::Face& m_syncFace;
|
||||
std::shared_ptr<Sync::SyncSocket> m_syncSocket;
|
||||
std::shared_ptr<chronosync::Socket> m_syncSocket;
|
||||
ndn::Name m_syncPrefix;
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
* \author Minsheng Zhang <mzhang4@memphis.edu>
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
#define NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
|
||||
|
||||
+4
-4
@@ -43,7 +43,7 @@ NlsrRunner::run()
|
||||
ConfFileProcessor configProcessor(m_nlsr, m_nlsr.getConfFileName());
|
||||
|
||||
if (!configProcessor.processConfFile()) {
|
||||
throw Error("Error in configuration file processing! Exiting from NLSR");
|
||||
BOOST_THROW_EXCEPTION(Error("Error in configuration file processing! Exiting from NLSR"));
|
||||
}
|
||||
|
||||
if (m_nlsr.getConfParameter().isLog4CxxConfAvailable()) {
|
||||
@@ -53,16 +53,16 @@ NlsrRunner::run()
|
||||
INIT_LOGGERS(m_nlsr.getConfParameter().getLogDir(), m_nlsr.getConfParameter().getLogLevel());
|
||||
}
|
||||
|
||||
m_nlsr.initialize();
|
||||
|
||||
if (m_nlsr.getIsSetDaemonProcess()) {
|
||||
m_nlsr.daemonize();
|
||||
}
|
||||
|
||||
m_nlsr.initialize();
|
||||
|
||||
try {
|
||||
m_nlsr.startEventLoop();
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
catch (const std::exception& e) {
|
||||
_LOG_FATAL("ERROR: " << e.what());
|
||||
std::cerr << "ERROR: " << e.what() << std::endl;
|
||||
|
||||
|
||||
@@ -1,399 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/output_test_stream.hpp>
|
||||
using boost::test_tools::output_test_stream;
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
#include "sync-logging.h"
|
||||
#include "sync-socket.h"
|
||||
#include <ndn-cpp-dev/security/validator-null.hpp>
|
||||
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
}
|
||||
|
||||
using namespace Sync;
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
INIT_LOGGER ("Test.AppSocket");
|
||||
|
||||
#define PRINT
|
||||
//std::cout << "Line: " << __LINE__ << std::endl;
|
||||
|
||||
class TestSocketApp {
|
||||
public:
|
||||
TestSocketApp()
|
||||
: sum(0)
|
||||
{}
|
||||
|
||||
map<ndn::Name, string> data;
|
||||
void set(const ndn::shared_ptr<const ndn::Data>& dataPacket) {
|
||||
// _LOG_FUNCTION (this << ", " << str1);
|
||||
ndn::Name dataName(dataPacket->getName());
|
||||
string str2(reinterpret_cast<const char*>(dataPacket->getContent().value()), dataPacket->getContent().value_size());
|
||||
data.insert(make_pair(dataName, str2));
|
||||
// cout << str1 << ", " << str2 << endl;
|
||||
}
|
||||
|
||||
void set(ndn::Name name, const char * buf, int len) {
|
||||
string str2(buf, len);
|
||||
data.insert(make_pair(name, str2));
|
||||
}
|
||||
|
||||
void setNum(const ndn::shared_ptr<const ndn::Data>& dataPacket) {
|
||||
int n = dataPacket->getContent().value_size() / 4;
|
||||
uint32_t *numbers = new uint32_t [n];
|
||||
memcpy(numbers, dataPacket->getContent().value(), dataPacket->getContent().value_size());
|
||||
for (int i = 0; i < n; i++) {
|
||||
sum += numbers[i];
|
||||
}
|
||||
delete numbers;
|
||||
|
||||
}
|
||||
|
||||
void setNum(ndn::Name name, const char * buf, int len) {
|
||||
int n = len / 4;
|
||||
int *numbers = new int [n];
|
||||
memcpy(numbers, buf, len);
|
||||
for (int i = 0; i < n; i++) {
|
||||
sum += numbers[i];
|
||||
}
|
||||
delete numbers;
|
||||
}
|
||||
|
||||
uint32_t sum;
|
||||
|
||||
void fetchAll(const vector<MissingDataInfo> &v, SyncSocket *socket) {
|
||||
int n = v.size();
|
||||
|
||||
PRINT
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
for(SeqNo s = v[i].low; s <= v[i].high; ++s) {
|
||||
//PRINT
|
||||
socket->fetchData(v[i].prefix, s, bind(&TestSocketApp::set, this, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fetchNumbers(const vector<MissingDataInfo> &v, SyncSocket *socket) {
|
||||
int n = v.size();
|
||||
|
||||
PRINT
|
||||
|
||||
// std::cout << "In fetchNumbers. size of v is: " << n << std::endl;
|
||||
for (int i = 0; i < n; i++) {
|
||||
// std::cout << "In fetchNumbers. v[i].low is (" <<v[i].low.getSession() <<", " << v[i].low.getSeq() << ") v[i].high is ("<<v[i].high.getSession() <<", " <<v[i].high.getSeq()<<")" << std::endl;
|
||||
for(SeqNo s = v[i].low; s <= v[i].high; ++s) {
|
||||
PRINT
|
||||
socket->fetchData(v[i].prefix, s, bind(&TestSocketApp::setNum, this, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pass(const string &prefix) {
|
||||
}
|
||||
|
||||
string toString(){
|
||||
map<ndn::Name, string>::iterator it = data.begin();
|
||||
string str = "\n";
|
||||
for (; it != data.end(); ++it){
|
||||
str += "<";
|
||||
str += it->first.toUri();
|
||||
str += "|";
|
||||
str += it->second;
|
||||
str += ">";
|
||||
str += "\n";
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class TestSet1{
|
||||
public:
|
||||
TestSet1(ndn::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_validator(new ndn::ValidatorNull())
|
||||
, m_face1(new ndn::Face(ioService))
|
||||
, m_face2(new ndn::Face(ioService))
|
||||
, m_face3(new ndn::Face(ioService))
|
||||
, m_p1("/irl.cs.ucla.edu")
|
||||
, m_p2("/yakshi.org")
|
||||
, m_p3("/google.com")
|
||||
, m_syncPrefix("/let/us/sync")
|
||||
{}
|
||||
|
||||
void
|
||||
createSyncSocket1()
|
||||
{
|
||||
_LOG_DEBUG ("s1");
|
||||
m_s1 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face1,
|
||||
bind(&TestSocketApp::fetchAll, &m_a1, _1, _2),
|
||||
bind(&TestSocketApp::pass, &m_a1, _1));
|
||||
}
|
||||
|
||||
void
|
||||
createSyncSocket2()
|
||||
{
|
||||
_LOG_DEBUG ("s2");
|
||||
m_s2 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face2,
|
||||
bind(&TestSocketApp::fetchAll, &m_a2, _1, _2),
|
||||
bind(&TestSocketApp::pass, &m_a2, _1));
|
||||
}
|
||||
|
||||
void
|
||||
createSyncSocket3()
|
||||
{
|
||||
_LOG_DEBUG ("s3");
|
||||
m_s3 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face3,
|
||||
bind(&TestSocketApp::fetchAll, &m_a3, _1, _2),
|
||||
bind(&TestSocketApp::pass, &m_a3, _1));
|
||||
}
|
||||
|
||||
void
|
||||
publishSocket1(uint32_t session, string data)
|
||||
{
|
||||
_LOG_DEBUG ("s1 publish");
|
||||
m_s1->publishData (m_p1, session, data.c_str(), data.size(), 1000);
|
||||
}
|
||||
|
||||
void
|
||||
publishSocket2(uint32_t session, string data)
|
||||
{
|
||||
_LOG_DEBUG ("s2 publish");
|
||||
m_s2->publishData (m_p2, session, data.c_str(), data.size(), 1000);
|
||||
}
|
||||
|
||||
void
|
||||
publishSocket3(uint32_t session, string data)
|
||||
{
|
||||
_LOG_DEBUG ("s3 publish");
|
||||
m_s3->publishData (m_p3, session, data.c_str(), data.size(), 1000);
|
||||
}
|
||||
|
||||
void
|
||||
setSocket1(string suffix, string data)
|
||||
{
|
||||
_LOG_DEBUG ("a1 set");
|
||||
ndn::Name name = m_p1;
|
||||
name.append(suffix);
|
||||
m_a1.set (name, data.c_str(), data.size());
|
||||
}
|
||||
|
||||
void
|
||||
setSocket2(string suffix, string data)
|
||||
{
|
||||
_LOG_DEBUG ("a2 set");
|
||||
ndn::Name name = m_p2;
|
||||
name.append(suffix);
|
||||
m_a2.set (name, data.c_str(), data.size());
|
||||
}
|
||||
|
||||
void
|
||||
setSocket3(string suffix, string data)
|
||||
{
|
||||
_LOG_DEBUG ("a3 set");
|
||||
ndn::Name name = m_p3;
|
||||
name.append(suffix);
|
||||
m_a3.set (name, data.c_str(), data.size());
|
||||
}
|
||||
|
||||
void
|
||||
check(int round)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(m_a1.toString(), m_a2.toString());
|
||||
BOOST_CHECK_EQUAL(m_a2.toString(), m_a3.toString());
|
||||
}
|
||||
|
||||
void
|
||||
done()
|
||||
{
|
||||
m_s1.reset();
|
||||
m_s2.reset();
|
||||
m_s3.reset();
|
||||
}
|
||||
|
||||
|
||||
TestSocketApp m_a1, m_a2, m_a3;
|
||||
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
|
||||
ndn::shared_ptr<ndn::Face> m_face1, m_face2, m_face3;
|
||||
ndn::Name m_p1, m_p2, m_p3;
|
||||
ndn::shared_ptr<SyncSocket> m_s1, m_s2, m_s3;
|
||||
ndn::Name m_syncPrefix;
|
||||
};
|
||||
|
||||
class TestSet2{
|
||||
public:
|
||||
TestSet2(ndn::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_validator(new ndn::ValidatorNull())
|
||||
, m_face1(new ndn::Face(ioService))
|
||||
, m_face2(new ndn::Face(ioService))
|
||||
, m_p1("/xiaonei.com")
|
||||
, m_p2("/mitbbs.com")
|
||||
, m_syncPrefix("/this/is/the/prefix")
|
||||
{}
|
||||
|
||||
void
|
||||
createSyncSocket1()
|
||||
{
|
||||
_LOG_DEBUG ("s1");
|
||||
m_s1 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face1,
|
||||
bind(&TestSocketApp::fetchNumbers, &m_a1, _1, _2),
|
||||
bind(&TestSocketApp::pass, &m_a1, _1));
|
||||
}
|
||||
|
||||
void
|
||||
createSyncSocket2()
|
||||
{
|
||||
_LOG_DEBUG ("s2");
|
||||
m_s2 = make_shared<SyncSocket>(m_syncPrefix, m_validator, m_face2,
|
||||
bind(&TestSocketApp::fetchNumbers, &m_a2, _1, _2),
|
||||
bind(&TestSocketApp::pass, &m_a2, _1));
|
||||
}
|
||||
|
||||
void
|
||||
publishSocket1(uint32_t session, string data)
|
||||
{
|
||||
_LOG_DEBUG ("s1 publish");
|
||||
m_s1->publishData (m_p1, session, data.c_str(), data.size(), 1000);
|
||||
}
|
||||
|
||||
void
|
||||
publishSocket2(uint32_t session, string data)
|
||||
{
|
||||
_LOG_DEBUG ("s2 publish");
|
||||
m_s2->publishData (m_p2, session, data.c_str(), data.size(), 1000);
|
||||
}
|
||||
|
||||
void
|
||||
setSocket1(const char* ptr, size_t size)
|
||||
{
|
||||
_LOG_DEBUG ("a1 setNum");
|
||||
m_a1.setNum (m_p1, ptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
setSocket2(const char* ptr, size_t size)
|
||||
{
|
||||
_LOG_DEBUG ("a2 setNum");
|
||||
m_a2.setNum (m_p2, ptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
check(int num)
|
||||
{
|
||||
_LOG_DEBUG ("codnum " << num);
|
||||
_LOG_DEBUG ("a1 sum " << m_a1.sum);
|
||||
_LOG_DEBUG ("a2 sum " << m_a2.sum);
|
||||
|
||||
BOOST_CHECK(m_a1.sum == m_a2.sum && m_a1.sum == num);
|
||||
}
|
||||
|
||||
void
|
||||
done()
|
||||
{
|
||||
m_s1.reset();
|
||||
m_s2.reset();
|
||||
}
|
||||
|
||||
TestSocketApp m_a1, m_a2;
|
||||
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
|
||||
ndn::shared_ptr<ndn::Face> m_face1, m_face2;
|
||||
ndn::Name m_p1, m_p2;
|
||||
ndn::shared_ptr<SyncSocket> m_s1, m_s2;
|
||||
ndn::Name m_syncPrefix;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE (AppSocketTest1)
|
||||
{
|
||||
INIT_LOGGERS ();
|
||||
|
||||
ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
|
||||
ndn::Scheduler scheduler(*ioService);
|
||||
TestSet1 testSet1(ioService);
|
||||
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.00), ndn::bind(&TestSet1::createSyncSocket1, &testSet1));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.05), ndn::bind(&TestSet1::createSyncSocket2, &testSet1));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.10), ndn::bind(&TestSet1::createSyncSocket3, &testSet1));
|
||||
string data0 = "Very funny Scotty, now beam down my clothes";
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.15), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data0));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.15), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/0", data0));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.16), ndn::bind(&TestSet1::check, &testSet1, 1));
|
||||
string data1 = "Yes, give me that ketchup";
|
||||
string data2 = "Don't look conspicuous, it draws fire";
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.17), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data1));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.18), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data2));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(2.15), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/1", data1));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(2.16), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/2", data2));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(2.17), ndn::bind(&TestSet1::check, &testSet1, 2));
|
||||
string data3 = "You surf the Internet, I surf the real world";
|
||||
string data4 = "I got a fortune cookie once that said 'You like Chinese food'";
|
||||
string data5 = "Real men wear pink. Why? Because their wives make them";
|
||||
scheduler.scheduleEvent(ndn::time::seconds(3.18), ndn::bind(&TestSet1::publishSocket3, &testSet1, 0, data3));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(3.20), ndn::bind(&TestSet1::publishSocket2, &testSet1, 0, data4));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(3.21), ndn::bind(&TestSet1::publishSocket2, &testSet1, 0, data5));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(4.21), ndn::bind(&TestSet1::setSocket3, &testSet1, "/0/0", data3));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(4.22), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/0", data4));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(4.23), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/1", data5));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(4.30), ndn::bind(&TestSet1::check, &testSet1, 3));
|
||||
// not sure weither this is simultanous data generation from multiple sources
|
||||
_LOG_DEBUG ("Simultaneous publishing");
|
||||
string data6 = "Shakespeare says: 'Prose before hos.'";
|
||||
string data7 = "Pick good people, talent never wears out";
|
||||
scheduler.scheduleEvent(ndn::time::seconds(5.50), ndn::bind(&TestSet1::publishSocket1, &testSet1, 0, data6));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(5.50), ndn::bind(&TestSet1::publishSocket2, &testSet1, 0, data7));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(6.80), ndn::bind(&TestSet1::setSocket1, &testSet1, "/0/3", data6));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(6.80), ndn::bind(&TestSet1::setSocket2, &testSet1, "/0/2", data7));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(6.90), ndn::bind(&TestSet1::check, &testSet1, 4));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(7.00), ndn::bind(&TestSet1::done, &testSet1));
|
||||
|
||||
ioService->run();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (AppSocketTest2)
|
||||
{
|
||||
ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
|
||||
ndn::Scheduler scheduler(*ioService);
|
||||
TestSet2 testSet2(ioService);
|
||||
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.00), ndn::bind(&TestSet2::createSyncSocket1, &testSet2));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.05), ndn::bind(&TestSet2::createSyncSocket2, &testSet2));
|
||||
uint32_t num[5] = {0, 1, 2, 3, 4};
|
||||
string data0((const char *) num, sizeof(num));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.10), ndn::bind(&TestSet2::publishSocket1, &testSet2, 0, data0));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.15), ndn::bind(&TestSet2::setSocket1, &testSet2, (const char *) num, sizeof (num)));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.00), ndn::bind(&TestSet2::check, &testSet2, 10));
|
||||
uint32_t newNum[5] = {9, 7, 2, 1, 1};
|
||||
string data1((const char *) newNum, sizeof(newNum));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.10), ndn::bind(&TestSet2::publishSocket2, &testSet2, 0, data1));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.15), ndn::bind(&TestSet2::setSocket2, &testSet2, (const char *) newNum, sizeof (newNum)));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(2.00), ndn::bind(&TestSet2::check, &testSet2, 30));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(7.00), ndn::bind(&TestSet2::done, &testSet2));
|
||||
|
||||
ioService->run();
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/output_test_stream.hpp>
|
||||
#include <map>
|
||||
using boost::test_tools::output_test_stream;
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include <ndn-cpp-dev/security/validator-null.hpp>
|
||||
#include "sync-logic.h"
|
||||
#include "sync-seq-no.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
using namespace Sync;
|
||||
|
||||
struct Handler
|
||||
{
|
||||
string instance;
|
||||
|
||||
Handler (const string &_instance)
|
||||
: instance (_instance)
|
||||
{
|
||||
}
|
||||
|
||||
void wrapper (const vector<MissingDataInfo> &v) {
|
||||
int n = v.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
onUpdate (v[i].prefix, v[i].high, v[i].low);
|
||||
}
|
||||
}
|
||||
|
||||
void onUpdate (const string &p/*prefix*/, const SeqNo &seq/*newSeq*/, const SeqNo &oldSeq/*oldSeq*/)
|
||||
{
|
||||
m_map[p] = seq.getSeq ();
|
||||
|
||||
// cout << instance << "\t";
|
||||
// if (!oldSeq.isValid ())
|
||||
// cout << "Inserted: " << p << " (" << seq << ")" << endl;
|
||||
// else
|
||||
// cout << "Updated: " << p << " ( " << oldSeq << ".." << seq << ")" << endl;
|
||||
}
|
||||
|
||||
void onRemove (const string &p/*prefix*/)
|
||||
{
|
||||
// cout << instance << "\tRemoved: " << p << endl;
|
||||
m_map.erase (p);
|
||||
}
|
||||
|
||||
map<string, uint32_t> m_map;
|
||||
};
|
||||
|
||||
class TestCore
|
||||
{
|
||||
public:
|
||||
TestCore(ndn::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_ioService(ioService)
|
||||
{
|
||||
m_l[0] = 0;
|
||||
m_l[1] = 0;
|
||||
|
||||
m_validator = ndn::make_shared<ndn::ValidatorNull>();
|
||||
}
|
||||
|
||||
~TestCore()
|
||||
{
|
||||
if(m_l[0] != 0)
|
||||
delete m_l[0];
|
||||
|
||||
if(m_l[1] != 0)
|
||||
delete m_l[1];
|
||||
}
|
||||
|
||||
void
|
||||
finish()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
createSyncLogic(int index,
|
||||
ndn::shared_ptr<Handler> h)
|
||||
{
|
||||
m_faces[index] = ndn::make_shared<ndn::Face>(m_ioService);
|
||||
m_l[index] = new SyncLogic(ndn::Name("/bcast"),
|
||||
m_validator, m_faces[index],
|
||||
bind (&Handler::wrapper, &*h, _1),
|
||||
bind (&Handler::onRemove, &*h, _1));
|
||||
}
|
||||
|
||||
void
|
||||
getOldDigestForOne()
|
||||
{
|
||||
m_oldDigest = m_l[0]->getRootDigest();
|
||||
}
|
||||
|
||||
void
|
||||
getNewDigestForOne()
|
||||
{
|
||||
m_newDigest = m_l[0]->getRootDigest();
|
||||
}
|
||||
|
||||
void
|
||||
addLocalNamesForOne(ndn::Name name, uint64_t session, uint64_t seq)
|
||||
{
|
||||
m_l[0]->addLocalNames(name, session, seq);
|
||||
}
|
||||
|
||||
void
|
||||
removeForOne(ndn::Name name)
|
||||
{
|
||||
m_l[0]->remove(name);
|
||||
}
|
||||
|
||||
void
|
||||
checkDigest()
|
||||
{
|
||||
BOOST_CHECK(m_oldDigest != m_newDigest);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
ndn::shared_ptr<boost::asio::io_service> m_ioService;
|
||||
SyncLogic* m_l[2];
|
||||
ndn::shared_ptr<ndn::Face> m_faces[2];
|
||||
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
|
||||
string m_oldDigest;
|
||||
string m_newDigest;
|
||||
};
|
||||
|
||||
void
|
||||
checkMapSize(ndn::shared_ptr<Handler> h, int size)
|
||||
{ BOOST_CHECK_EQUAL (h->m_map.size (), size); }
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE (SyncLogicTest)
|
||||
{
|
||||
ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
|
||||
ndn::Scheduler scheduler(*ioService);
|
||||
TestCore testCore(ioService);
|
||||
|
||||
ndn::shared_ptr<Handler> h1 = ndn::make_shared<Handler>("1");
|
||||
ndn::shared_ptr<Handler> h2 = ndn::make_shared<Handler>("2");
|
||||
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0), ndn::bind(&TestCore::createSyncLogic, &testCore, 0, h1));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.1), ndn::bind(&TestCore::getOldDigestForOne, &testCore));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.2), ndn::bind(&TestCore::addLocalNamesForOne, &testCore, "/one", 1, 2));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.3), ndn::bind(&checkMapSize, h1, 0));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.4), ndn::bind(&TestCore::createSyncLogic, &testCore, 1, h2));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.5), ndn::bind(&checkMapSize, h1, 0));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.6), ndn::bind(&checkMapSize, h2, 1));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.7), ndn::bind(&TestCore::removeForOne, &testCore, "/one"));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.8), ndn::bind(&TestCore::getNewDigestForOne, &testCore));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(0.9), ndn::bind(&TestCore::checkDigest, &testCore));
|
||||
scheduler.scheduleEvent(ndn::time::seconds(1.0), ndn::bind(&TestCore::finish, &testCore));
|
||||
|
||||
ioService->run();
|
||||
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/output_test_stream.hpp>
|
||||
using boost::test_tools::output_test_stream;
|
||||
|
||||
#include "sync-digest.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace Sync;
|
||||
using namespace Sync::Error;
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(DigestTests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE (BasicTest)
|
||||
{
|
||||
Digest d0;
|
||||
BOOST_REQUIRE (d0.empty ());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (DigestGenerationTest)
|
||||
{
|
||||
Digest d1;
|
||||
BOOST_CHECK_NO_THROW (d1 << "1\n");
|
||||
|
||||
// without explicit finalizing, Digest will not be complete and printing out will cause assert
|
||||
BOOST_CHECK (d1.empty ());
|
||||
|
||||
// fix hash
|
||||
d1.finalize ();
|
||||
|
||||
BOOST_CHECK_NO_THROW (d1.getHash ());
|
||||
BOOST_CHECK (!d1.empty ());
|
||||
BOOST_CHECK (d1 == d1);
|
||||
|
||||
BOOST_CHECK_THROW (d1 << "2", DigestCalculationError);
|
||||
|
||||
output_test_stream output;
|
||||
BOOST_CHECK_NO_THROW (output << d1);
|
||||
// BOOST_CHECK (output.check_length (40, false) );
|
||||
// BOOST_CHECK (output.is_equal ("e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e", true)); // for sha1
|
||||
BOOST_CHECK (output.check_length (64, false) );
|
||||
BOOST_CHECK (output.is_equal ("4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865", true)); // for sha256
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (DigestComparison)
|
||||
{
|
||||
Digest d1;
|
||||
BOOST_CHECK_NO_THROW (d1 << "1\n");
|
||||
// BOOST_CHECK_THROW (d1 == d1, DigestCalculationError);
|
||||
BOOST_CHECK_NO_THROW (d1.finalize ());
|
||||
BOOST_CHECK (d1 == d1);
|
||||
|
||||
Digest d2;
|
||||
BOOST_CHECK_NO_THROW (d2 << "2\n");
|
||||
BOOST_CHECK_NO_THROW (d2.finalize ());
|
||||
BOOST_CHECK (d1 != d2);
|
||||
|
||||
Digest d3;
|
||||
// istringstream is (string ("e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e")); // real sha-1 for "1\n"
|
||||
istringstream is (string ("4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865")); // real sha256 for "1\n"
|
||||
BOOST_CHECK_NO_THROW (is >> d3);
|
||||
BOOST_CHECK (!d3.empty ());
|
||||
BOOST_CHECK (d3 == d1);
|
||||
BOOST_CHECK (d3 != d2);
|
||||
|
||||
istringstream is2 (string ("25fa44f2b31c1fb553b6021e7360d07d5d91ff5e")); // some fake hash
|
||||
BOOST_CHECK_THROW (is2 >> d3, DigestCalculationError); // >> can be used only once
|
||||
|
||||
Digest d4;
|
||||
BOOST_CHECK_THROW (is2 >> d4, DigestCalculationError); // is2 is now empty. empty >> is not allowed
|
||||
|
||||
istringstream is3 (string ("25fa44f2b31c1fb553b6021e7360d07d5d91ff5e")); // some fake hash
|
||||
BOOST_CHECK_NO_THROW (is3 >> d4);
|
||||
|
||||
BOOST_CHECK (d4 != d1);
|
||||
BOOST_CHECK (d4 != d2);
|
||||
BOOST_CHECK (d4 != d3);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -1,108 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/output_test_stream.hpp>
|
||||
using boost::test_tools::output_test_stream;
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include "sync-full-leaf.h"
|
||||
#include "sync-diff-leaf.h"
|
||||
#include "sync-std-name-info.h"
|
||||
|
||||
using namespace Sync;
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(LeafTests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE (LeafBase)
|
||||
{
|
||||
NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
|
||||
BOOST_CHECK (name != 0);
|
||||
|
||||
// find the same name
|
||||
BOOST_CHECK (name.get () == StdNameInfo::FindOrCreate ("/test/name").get ());
|
||||
BOOST_CHECK_EQUAL (name.use_count (), 1);
|
||||
|
||||
BOOST_CHECK_NO_THROW (DiffLeaf x (name, SeqNo (12)));
|
||||
BOOST_CHECK_EQUAL (name.use_count (), 1);
|
||||
|
||||
BOOST_CHECK_NO_THROW (DiffLeaf x (name));
|
||||
BOOST_CHECK_EQUAL (name.use_count (), 1);
|
||||
|
||||
DiffLeaf updateLeaf (name, SeqNo (12));
|
||||
BOOST_CHECK_EQUAL (name.use_count (), 2);
|
||||
|
||||
DiffLeaf removeLeaf (name);
|
||||
BOOST_CHECK_EQUAL (name.use_count (), 3);
|
||||
|
||||
BOOST_CHECK_EQUAL (updateLeaf.getOperation (), UPDATE);
|
||||
BOOST_CHECK_EQUAL (updateLeaf.getSeq ().getSession (), 0);
|
||||
BOOST_CHECK_EQUAL (updateLeaf.getSeq ().getSeq (), 12);
|
||||
|
||||
BOOST_CHECK_EQUAL (removeLeaf.getOperation (), REMOVE);
|
||||
BOOST_CHECK_EQUAL (removeLeaf.getSeq ().getSession (), 0);
|
||||
BOOST_CHECK_EQUAL (removeLeaf.getSeq ().getSeq (), 0);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW (FullLeaf x (name, SeqNo (12)));
|
||||
FullLeaf fullLeaf (name, SeqNo (12));
|
||||
BOOST_CHECK_EQUAL (name.use_count (), 4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (LeafDigest)
|
||||
{
|
||||
BOOST_CHECK_EQUAL (StdNameInfo::FindOrCreate ("/test/name").use_count (), 1);
|
||||
NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
|
||||
FullLeaf fullLeaf (name, SeqNo (12));
|
||||
|
||||
// fullLeafDigest = hash ( hash(name), hash (session, seqNo) )
|
||||
|
||||
// Digest manualDigest;
|
||||
|
||||
// Digest manualNameDigest;
|
||||
// manualNameDigest << "/test/name";
|
||||
// manualNameDigest.finalize ();
|
||||
|
||||
// Digest manualSeqNoDigest;
|
||||
// manualSeqNoDigest << 0 << 13;
|
||||
// manualSeqNoDigest.finalize ();
|
||||
|
||||
// manualDigest << manualNameDigest << manualSeqNoDigest;
|
||||
// manualDigest.finalize ();
|
||||
|
||||
// cout << manualDigest << "\n\n";
|
||||
|
||||
output_test_stream output;
|
||||
output << fullLeaf.getDigest ();
|
||||
// BOOST_CHECK (output.is_equal ("991f8cf6262dfe0f519c63f6e9b92fe69e741a9b", true)); // for sha1
|
||||
BOOST_CHECK (output.is_equal ("526d63e6e1f05f97502fd500a1729c4907f3841483ae4561b7e6307c40188f35", true)); // for sha256
|
||||
|
||||
fullLeaf.setSeq (SeqNo (13));
|
||||
output << fullLeaf.getDigest ();
|
||||
BOOST_CHECK (!output.is_equal ("991f8cf6262dfe0f519c63f6e9b92fe69e741a9b", false));
|
||||
// BOOST_CHECK (output.is_equal ("585a8687ab41d5c29f86e5906c8f188ddca816b3", true)); // for sha1
|
||||
BOOST_CHECK (output.is_equal ("39fefe65b3e1021776c07d3a9a3023c6c7cdf12724ee7f3a98b813b22f46d5ec", true)); // for sha256
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -1,294 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_DYN_LINK 1
|
||||
#define BOOST_TEST_NO_MAIN 1
|
||||
// #define BOOST_TEST_MODULE StateTests
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/output_test_stream.hpp>
|
||||
using boost::test_tools::output_test_stream;
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
#include "sync-std-name-info.h"
|
||||
#include "sync-full-state.h"
|
||||
#include "sync-diff-state.h"
|
||||
|
||||
using namespace Sync;
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(StateTests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE (FullStateTest)
|
||||
{
|
||||
BOOST_CHECK_NO_THROW (FullState ());
|
||||
FullState state;
|
||||
BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
|
||||
|
||||
output_test_stream output;
|
||||
output << state.getTimeFromLastUpdate ();
|
||||
BOOST_CHECK (output.is_equal ("not-a-date-time", true));
|
||||
|
||||
NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
|
||||
BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
|
||||
BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 12);
|
||||
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (13)));
|
||||
BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 13);
|
||||
|
||||
BOOST_CHECK_NO_THROW (state.remove (name));
|
||||
BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
|
||||
|
||||
BOOST_CHECK_EQUAL (state.getTimeFromLastUpdate ().total_milliseconds (), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (DiffStateTest)
|
||||
{
|
||||
BOOST_CHECK_NO_THROW (DiffState ());
|
||||
DiffState state;
|
||||
BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
|
||||
|
||||
NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
|
||||
BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
|
||||
BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 12);
|
||||
|
||||
BOOST_CHECK_NO_THROW (state.update (name, SeqNo (13)));
|
||||
BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 13);
|
||||
|
||||
BOOST_CHECK_NO_THROW (state.remove (name));
|
||||
BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
|
||||
BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (FullStateDigestTest)
|
||||
{
|
||||
FullState state;
|
||||
BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
|
||||
|
||||
NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
|
||||
NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
|
||||
NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
|
||||
|
||||
state.update (name1, SeqNo (10));
|
||||
DigestConstPtr digest1 = state.getDigest ();
|
||||
|
||||
state.update (name2, SeqNo (12));
|
||||
DigestConstPtr digest2 = state.getDigest ();
|
||||
|
||||
BOOST_CHECK (digest1.get () != digest2.get ());
|
||||
BOOST_CHECK (!digest1->empty ());
|
||||
BOOST_CHECK (!digest2->empty ());
|
||||
|
||||
state.update (name3, SeqNo (8));
|
||||
DigestConstPtr digest3 = state.getDigest ();
|
||||
|
||||
BOOST_CHECK (digest1.get () != digest2.get ());
|
||||
BOOST_CHECK (digest2.get () != digest3.get ());
|
||||
BOOST_CHECK (digest1.get () != digest3.get ());
|
||||
|
||||
BOOST_CHECK (*digest1 != *digest2);
|
||||
BOOST_CHECK (*digest2 != *digest3);
|
||||
BOOST_CHECK (*digest1 != *digest3);
|
||||
|
||||
// removing elements. Digest should get reverted to digest1
|
||||
state.remove (name2);
|
||||
state.remove (name3);
|
||||
DigestConstPtr digest4 = state.getDigest ();
|
||||
BOOST_CHECK (*digest1 == *digest4);
|
||||
|
||||
name2.reset (); // force destructor
|
||||
name3.reset (); // force destructor
|
||||
name3 = StdNameInfo::FindOrCreate ("3"); // this will enforce different (larger) hashing ID of name
|
||||
name2 = StdNameInfo::FindOrCreate ("2"); // this will enforce different (larger) hashing ID of name
|
||||
|
||||
// adding in different order
|
||||
state.update (name3, SeqNo (8));
|
||||
state.update (name2, SeqNo (12));
|
||||
DigestConstPtr digest5 = state.getDigest ();
|
||||
BOOST_CHECK (*digest5 == *digest3);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (FullStateXml)
|
||||
{
|
||||
FullState state;
|
||||
|
||||
NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
|
||||
NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
|
||||
NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
|
||||
|
||||
state.update (name1, SeqNo (10));
|
||||
state.update (name2, SeqNo (12));
|
||||
state.update (name3, SeqNo (8));
|
||||
|
||||
string xml1 = "<state>"
|
||||
"<item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
|
||||
"<item><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item>"
|
||||
"<item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
|
||||
"</state>";
|
||||
{
|
||||
ostringstream os;
|
||||
os << state;
|
||||
string s = os.str ();
|
||||
// cout << s << endl;
|
||||
erase_all (s, "\n");
|
||||
BOOST_CHECK_EQUAL (s, xml1);
|
||||
}
|
||||
|
||||
state.remove (name2);
|
||||
string xml2 = "<state>"
|
||||
"<item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
|
||||
"<item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
|
||||
"</state>";
|
||||
{
|
||||
ostringstream os;
|
||||
os << state;
|
||||
string s = os.str ();
|
||||
erase_all (s, "\n");
|
||||
BOOST_CHECK_EQUAL (s, xml2);
|
||||
}
|
||||
|
||||
FullState state2;
|
||||
istringstream xml1_is (xml1);
|
||||
BOOST_CHECK_NO_THROW (xml1_is >> state2);
|
||||
{
|
||||
ostringstream os;
|
||||
os << state2;
|
||||
string xml1_test = os.str ();
|
||||
erase_all (xml1_test, "\n");
|
||||
BOOST_CHECK_EQUAL (xml1_test, xml1);
|
||||
}
|
||||
|
||||
istringstream xml2_is ("<state><item action=\"remove\"><name>2</name></item></state>");
|
||||
BOOST_CHECK_NO_THROW (xml2_is >> state2);
|
||||
|
||||
{
|
||||
ostringstream os;
|
||||
os << state2;
|
||||
string xml2_test = os.str ();
|
||||
erase_all (xml2_test, "\n");
|
||||
BOOST_CHECK_EQUAL (xml2_test, xml2);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (DiffStateXml)
|
||||
{
|
||||
DiffState state;
|
||||
|
||||
NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
|
||||
NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
|
||||
NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
|
||||
|
||||
state.update (name1, SeqNo (10));
|
||||
state.update (name2, SeqNo (12));
|
||||
state.update (name3, SeqNo (8));
|
||||
|
||||
string xml1 = "<state>"
|
||||
"<item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
|
||||
"<item action=\"update\"><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item>"
|
||||
"<item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
|
||||
"</state>";
|
||||
{
|
||||
ostringstream os;
|
||||
os << state;
|
||||
string xml1_test = os.str ();
|
||||
erase_all (xml1_test, "\n");
|
||||
BOOST_CHECK_EQUAL (xml1_test, xml1);
|
||||
}
|
||||
|
||||
state.remove (name2);
|
||||
string xml2 = "<state>"
|
||||
"<item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
|
||||
"<item action=\"remove\"><name>2</name></item>"
|
||||
"<item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
|
||||
"</state>";
|
||||
{
|
||||
ostringstream os;
|
||||
os << state;
|
||||
string xml2_test = os.str ();
|
||||
erase_all (xml2_test, "\n");
|
||||
BOOST_CHECK_EQUAL (xml2_test, xml2);
|
||||
}
|
||||
|
||||
//////////// //////////// //////////// //////////// //////////// ////////////
|
||||
|
||||
DiffState state2;
|
||||
istringstream xml1_is (xml1);
|
||||
BOOST_CHECK_NO_THROW (xml1_is >> state2);
|
||||
|
||||
{
|
||||
ostringstream os;
|
||||
os << state2;
|
||||
string xml1_test = os.str ();
|
||||
erase_all (xml1_test, "\n");
|
||||
BOOST_CHECK_EQUAL (xml1_test, xml1);
|
||||
}
|
||||
|
||||
istringstream xml2_is ("<state><item action=\"remove\"><name>2</name></item></state>");
|
||||
BOOST_CHECK_NO_THROW (xml2_is >> state2);
|
||||
|
||||
{
|
||||
ostringstream os;
|
||||
os << state2;
|
||||
string xml2_test = os.str ();
|
||||
erase_all (xml2_test, "\n");
|
||||
BOOST_CHECK_EQUAL (xml2_test, xml2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE (DiffStateDiffTest)
|
||||
{
|
||||
DiffStatePtr root = make_shared<DiffState> ();
|
||||
|
||||
DiffStatePtr head = make_shared<DiffState> ();
|
||||
root->setNext (head);
|
||||
|
||||
head->update (StdNameInfo::FindOrCreate ("3"), SeqNo (1));
|
||||
head->remove (StdNameInfo::FindOrCreate ("1"));
|
||||
|
||||
DiffStatePtr tail = make_shared<DiffState> ();
|
||||
head->setNext (tail);
|
||||
|
||||
tail->update (StdNameInfo::FindOrCreate ("3"), SeqNo (2));
|
||||
|
||||
{
|
||||
ostringstream os;
|
||||
os << *root->diff ();
|
||||
string diffState = os.str ();
|
||||
erase_all (diffState, "\n");
|
||||
BOOST_CHECK_EQUAL (diffState,
|
||||
"<state>"
|
||||
"<item action=\"remove\"><name>1</name></item>"
|
||||
"<item action=\"update\"><name>3</name><seq><session>0</session><seqno>2</seqno></seq></item>"
|
||||
"</state>");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -76,6 +76,7 @@ BOOST_AUTO_TEST_CASE(HyperbolicOn_ZeroCostNeighbors)
|
||||
neighbors.insert(neighborC);
|
||||
|
||||
nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
|
||||
nlsr.getConfParameter().setNetwork(ndn::Name("/test"));
|
||||
|
||||
nlsr.initialize();
|
||||
|
||||
|
||||
@@ -51,15 +51,15 @@ public:
|
||||
void
|
||||
receiveUpdate(std::string prefix, uint64_t seqNo, SyncLogicHandler& p_sync)
|
||||
{
|
||||
Sync::MissingDataInfo info = {prefix, 0, seqNo};
|
||||
chronosync::MissingDataInfo info = {ndn::Name(prefix).appendNumber(1), 0, seqNo};
|
||||
|
||||
std::vector<Sync::MissingDataInfo> updates;
|
||||
std::vector<chronosync::MissingDataInfo> updates;
|
||||
updates.push_back(info);
|
||||
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
face->sentInterests.clear();
|
||||
|
||||
p_sync.onNsyncUpdate(updates, nullptr);
|
||||
p_sync.onNsyncUpdate(updates);
|
||||
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#include "adjacency-list.hpp"
|
||||
#include "nlsr.hpp"
|
||||
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/util/dummy-client-face.hpp>
|
||||
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
@@ -49,7 +49,12 @@ public:
|
||||
|
||||
// Initialize NLSR so a sync socket is created
|
||||
nlsr.initialize();
|
||||
this->advanceClocks(ndn::time::milliseconds(10), 1);
|
||||
|
||||
// Saving clock::now before any advanceClocks so that it will
|
||||
// be the same value as what ChronoSync uses in setting the sessionName
|
||||
sessionTime.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
|
||||
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
face.sentInterests.clear();
|
||||
}
|
||||
|
||||
@@ -63,9 +68,24 @@ public:
|
||||
return interest;
|
||||
}
|
||||
|
||||
void sendInterestForPublishedData() {
|
||||
// Need to send an interest now since ChronoSync
|
||||
// no longer does face->put(*data) in publishData.
|
||||
// Instead it does it in onInterest
|
||||
ndn::Name lsaInterestName("/localhop/ndn/NLSR/LSA");
|
||||
// The part after LSA is Chronosync getSession
|
||||
lsaInterestName.append(sessionTime);
|
||||
lsaInterestName.appendNumber(nlsr.getSequencingManager().getCombinedSeqNo());
|
||||
shared_ptr<ndn::Interest> lsaInterest = make_shared<ndn::Interest>(lsaInterestName);
|
||||
|
||||
face.receive(*lsaInterest);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
}
|
||||
|
||||
bool
|
||||
wasRoutingUpdatePublished()
|
||||
{
|
||||
sendInterestForPublishedData();
|
||||
const ndn::Name& lsaPrefix = nlsr.getConfParameter().getLsaPrefix();
|
||||
|
||||
const auto& it = std::find_if(face.sentData.begin(), face.sentData.end(),
|
||||
@@ -83,6 +103,7 @@ public:
|
||||
Nlsr nlsr;
|
||||
NamePrefixList& namePrefixes;
|
||||
NfdRibCommandProcessor& processor;
|
||||
ndn::Name sessionTime;
|
||||
};
|
||||
|
||||
typedef boost::mpl::vector<NfdRibRegisterCommand, NfdRibUnregisterCommand> Commands;
|
||||
@@ -119,7 +140,7 @@ BOOST_AUTO_TEST_CASE(InsertPrefix)
|
||||
parameters.setName(prefixName);
|
||||
|
||||
processor.insertPrefix(parameters);
|
||||
this->advanceClocks(ndn::time::milliseconds(10), 1);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
BOOST_CHECK_EQUAL(namePrefixes.getNameList().size(), 1);
|
||||
auto itr = std::find(namePrefixes.getNameList().begin(), namePrefixes.getNameList().end(),
|
||||
@@ -140,7 +161,7 @@ BOOST_AUTO_TEST_CASE(RemovePrefix)
|
||||
|
||||
BOOST_CHECK_EQUAL(namePrefixes.getNameList().size(), 1);
|
||||
processor.removePrefix(parameters);
|
||||
this->advanceClocks(ndn::time::milliseconds(10), 1);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
BOOST_CHECK_EQUAL(namePrefixes.getNameList().size(), 0);
|
||||
auto itr = std::find(namePrefixes.getNameList().begin(), namePrefixes.getNameList().end(),
|
||||
@@ -161,7 +182,7 @@ BOOST_AUTO_TEST_CASE(onReceiveInterestRegisterCommand)
|
||||
.wireEncode()), 0);
|
||||
|
||||
face.receive(*command);
|
||||
this->advanceClocks(ndn::time::milliseconds(10), 1);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
BOOST_CHECK_EQUAL(namePrefixes.getNameList().size(), 1);
|
||||
auto itr = std::find(namePrefixes.getNameList().begin(), namePrefixes.getNameList().end(),
|
||||
@@ -185,7 +206,7 @@ BOOST_AUTO_TEST_CASE(onReceiveInterestUnregisterCommand)
|
||||
.wireEncode()), 0);
|
||||
|
||||
face.receive(ndn::Interest(name));
|
||||
this->advanceClocks(ndn::time::milliseconds(10), 1);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
BOOST_CHECK_EQUAL(namePrefixes.getNameList().size(), 0);
|
||||
BOOST_CHECK(wasRoutingUpdatePublished());
|
||||
@@ -201,7 +222,7 @@ BOOST_AUTO_TEST_CASE(onReceiveInterestInvalidPrefix)
|
||||
.wireEncode()), 0);
|
||||
|
||||
face.receive(ndn::Interest(name));
|
||||
this->advanceClocks(ndn::time::milliseconds(10), 1);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
BOOST_CHECK_EQUAL(namePrefixes.getNameList().size(), 0);
|
||||
BOOST_CHECK(!wasRoutingUpdatePublished());
|
||||
|
||||
@@ -39,14 +39,14 @@ namespace nlsr {
|
||||
namespace update {
|
||||
namespace test {
|
||||
|
||||
class PrefixUpdateFixture : public nlsr::test::BaseFixture
|
||||
class PrefixUpdateFixture : public nlsr::test::UnitTestTimeFixture
|
||||
{
|
||||
public:
|
||||
PrefixUpdateFixture()
|
||||
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
|
||||
: face(g_ioService, keyChain, {true, true})
|
||||
, siteIdentity(ndn::Name("/ndn/edu/test-site").appendVersion())
|
||||
, opIdentity(ndn::Name(siteIdentity).append(ndn::Name("%C1.Operator")).appendVersion())
|
||||
, nlsr(g_ioService, g_scheduler, *face, g_keyChain)
|
||||
, nlsr(g_ioService, g_scheduler, face, g_keyChain)
|
||||
, keyPrefix(("/ndn/broadcast"))
|
||||
, updateProcessor(nlsr.getPrefixUpdateProcessor())
|
||||
, SITE_CERT_PATH(boost::filesystem::current_path() / std::string("site.cert"))
|
||||
@@ -114,11 +114,12 @@ public:
|
||||
// Initialize NLSR so a sync socket is created
|
||||
nlsr.initialize();
|
||||
|
||||
// Listen on localhost prefix
|
||||
updateProcessor.startListening();
|
||||
// Saving clock::now before any advanceClocks so that it will
|
||||
// be the same value as what ChronoSync uses in setting the sessionName
|
||||
sessionTime.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
|
||||
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
face->sentInterests.clear();
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
face.sentInterests.clear();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -155,28 +156,44 @@ public:
|
||||
keyChain.addCertificateAsIdentityDefault(*opCert);
|
||||
}
|
||||
|
||||
void sendInterestForPublishedData() {
|
||||
// Need to send an interest now since ChronoSync
|
||||
// no longer does face->put(*data) in publishData.
|
||||
// Instead it does it in onInterest
|
||||
ndn::Name lsaInterestName("/localhop/ndn/NLSR/LSA");
|
||||
// The part after LSA is Chronosync getSession
|
||||
lsaInterestName.append(sessionTime);
|
||||
lsaInterestName.appendNumber(nlsr.getSequencingManager().getCombinedSeqNo());
|
||||
shared_ptr<Interest> lsaInterest = make_shared<Interest>(lsaInterestName);
|
||||
|
||||
face.receive(*lsaInterest);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
}
|
||||
|
||||
bool
|
||||
wasRoutingUpdatePublished()
|
||||
{
|
||||
sendInterestForPublishedData();
|
||||
|
||||
const ndn::Name& lsaPrefix = nlsr.getConfParameter().getLsaPrefix();
|
||||
|
||||
const auto& it = std::find_if(face->sentData.begin(), face->sentData.end(),
|
||||
const auto& it = std::find_if(face.sentData.begin(), face.sentData.end(),
|
||||
[lsaPrefix] (const ndn::Data& data) {
|
||||
return lsaPrefix.isPrefixOf(data.getName());
|
||||
});
|
||||
|
||||
return (it != face->sentData.end());
|
||||
return (it != face.sentData.end());
|
||||
}
|
||||
|
||||
void
|
||||
checkResponseCode(const Name& commandPrefix, uint64_t expectedCode)
|
||||
{
|
||||
std::vector<Data>::iterator it = std::find_if(face->sentData.begin(),
|
||||
face->sentData.end(),
|
||||
std::vector<Data>::iterator it = std::find_if(face.sentData.begin(),
|
||||
face.sentData.end(),
|
||||
[commandPrefix] (const Data& data) {
|
||||
return commandPrefix.isPrefixOf(data.getName());
|
||||
});
|
||||
BOOST_REQUIRE(it != face->sentData.end());
|
||||
BOOST_REQUIRE(it != face.sentData.end());
|
||||
|
||||
ndn::nfd::ControlResponse response(it->getContent().blockFromValue());
|
||||
BOOST_CHECK_EQUAL(response.getCode(), expectedCode);
|
||||
@@ -191,7 +208,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
std::shared_ptr<ndn::util::DummyClientFace> face;
|
||||
ndn::util::DummyClientFace face;
|
||||
ndn::KeyChain keyChain;
|
||||
|
||||
ndn::Name siteIdentity;
|
||||
@@ -207,6 +224,7 @@ public:
|
||||
PrefixUpdateProcessor& updateProcessor;
|
||||
|
||||
const boost::filesystem::path SITE_CERT_PATH;
|
||||
ndn::Name sessionTime;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(TestPrefixUpdateProcessor, PrefixUpdateFixture)
|
||||
@@ -225,8 +243,8 @@ BOOST_AUTO_TEST_CASE(Basic)
|
||||
std::shared_ptr<Interest> advertiseInterest = std::make_shared<Interest>(advertiseCommand);
|
||||
keyChain.signByIdentity(*advertiseInterest, opIdentity);
|
||||
|
||||
face->receive(*advertiseInterest);
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
face.receive(*advertiseInterest);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
NamePrefixList& namePrefixList = nlsr.getNamePrefixList();
|
||||
|
||||
@@ -234,7 +252,8 @@ BOOST_AUTO_TEST_CASE(Basic)
|
||||
BOOST_CHECK_EQUAL(namePrefixList.getNameList().front(), parameters.getName());
|
||||
|
||||
BOOST_CHECK(wasRoutingUpdatePublished());
|
||||
face->sentData.clear();
|
||||
|
||||
face.sentData.clear();
|
||||
|
||||
// Withdraw
|
||||
ndn::Name withdrawCommand("/localhost/nlsr/prefix-update/withdraw");
|
||||
@@ -243,8 +262,8 @@ BOOST_AUTO_TEST_CASE(Basic)
|
||||
std::shared_ptr<Interest> withdrawInterest = std::make_shared<Interest>(withdrawCommand);
|
||||
keyChain.signByIdentity(*withdrawInterest, opIdentity);
|
||||
|
||||
face->receive(*withdrawInterest);
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
face.receive(*withdrawInterest);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
BOOST_CHECK_EQUAL(namePrefixList.getSize(), 0);
|
||||
|
||||
@@ -263,22 +282,22 @@ BOOST_AUTO_TEST_CASE(DisabledAndEnabled)
|
||||
keyChain.signByIdentity(*advertiseInterest, opIdentity);
|
||||
|
||||
// Command should be rejected
|
||||
face->receive(*advertiseInterest);
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
face.receive(*advertiseInterest);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
BOOST_REQUIRE(!face->sentData.empty());
|
||||
BOOST_REQUIRE(!face.sentData.empty());
|
||||
|
||||
const ndn::MetaInfo& metaInfo = face->sentData.front().getMetaInfo();
|
||||
const ndn::MetaInfo& metaInfo = face.sentData.front().getMetaInfo();
|
||||
BOOST_CHECK_EQUAL(metaInfo.getType(), ndn::tlv::ContentType_Nack);
|
||||
|
||||
face->sentData.clear();
|
||||
face.sentData.clear();
|
||||
|
||||
// Enable PrefixUpdateProcessor so commands will be processed
|
||||
updateProcessor.enable();
|
||||
|
||||
// Command should be accepted
|
||||
face->receive(*advertiseInterest);
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
face.receive(*advertiseInterest);
|
||||
this->advanceClocks(ndn::time::milliseconds(10));
|
||||
|
||||
checkResponseCode(advertiseCommand, 200);
|
||||
}
|
||||
|
||||
@@ -32,15 +32,6 @@ def build(bld):
|
||||
use='nlsr-objects',
|
||||
)
|
||||
|
||||
# nsync tests
|
||||
unit_tests_nsync = bld.program(
|
||||
target='../unit-tests-nsync',
|
||||
features='cxx cxxprogram',
|
||||
source=bld.path.ant_glob(['nsync/**/*.cc']),
|
||||
use='nsync-objects unit-tests-main',
|
||||
includes='.',
|
||||
install_path=None,
|
||||
)
|
||||
|
||||
# nlsr tests
|
||||
unit_tests_nlsr = bld.program(
|
||||
|
||||
@@ -33,8 +33,7 @@ import os
|
||||
def options(opt):
|
||||
opt.load(['compiler_cxx', 'gnu_dirs'])
|
||||
opt.load(['default-compiler-flags', 'coverage',
|
||||
'boost', 'protoc', 'openssl',
|
||||
'doxygen', 'sphinx_build'],
|
||||
'boost', 'doxygen', 'sphinx_build'],
|
||||
tooldir=['.waf-tools'])
|
||||
|
||||
nlsropt = opt.add_option_group('NLSR Options')
|
||||
@@ -45,8 +44,7 @@ def options(opt):
|
||||
|
||||
def configure(conf):
|
||||
conf.load(['compiler_cxx', 'gnu_dirs',
|
||||
'boost', 'openssl',
|
||||
'default-compiler-flags',
|
||||
'boost', 'default-compiler-flags',
|
||||
'doxygen', 'sphinx_build'])
|
||||
|
||||
if 'PKG_CONFIG_PATH' not in os.environ:
|
||||
@@ -58,8 +56,6 @@ def configure(conf):
|
||||
conf.check_cfg(package='liblog4cxx', args=['--cflags', '--libs'],
|
||||
uselib_store='LOG4CXX', mandatory=True)
|
||||
|
||||
conf.check_openssl(mandatory=True)
|
||||
|
||||
boost_libs = 'system chrono program_options iostreams thread regex filesystem'
|
||||
if conf.options.with_tests:
|
||||
conf.env['WITH_TESTS'] = 1
|
||||
@@ -73,7 +69,8 @@ def configure(conf):
|
||||
Logs.error("Please upgrade your distribution or install custom boost libraries")
|
||||
return
|
||||
|
||||
conf.load('protoc')
|
||||
conf.check_cfg(package='ChronoSync', args=['ChronoSync >= 0.1', '--cflags', '--libs'],
|
||||
uselib_store='SYNC', mandatory=True)
|
||||
|
||||
conf.load('coverage')
|
||||
|
||||
@@ -100,23 +97,13 @@ def build(bld):
|
||||
VERSION_PATCH=VERSION_SPLIT[2],
|
||||
)
|
||||
|
||||
nsync_objects = bld(
|
||||
target='nsync-objects',
|
||||
name='nsync-objects',
|
||||
features='cxx',
|
||||
source=bld.path.ant_glob(['nsync/**/*.cc', 'nsync/**/*.proto']),
|
||||
use='BOOST NDN_CXX OPENSSL LOG4CXX',
|
||||
includes='nsync',
|
||||
export_includes='nsync',
|
||||
)
|
||||
|
||||
nlsr_objects = bld(
|
||||
target='nlsr-objects',
|
||||
name='nlsr-objects',
|
||||
features='cxx',
|
||||
source=bld.path.ant_glob(['src/**/*.cpp'],
|
||||
excl=['src/main.cpp']),
|
||||
use='nsync-objects NDN_CXX BOOST LOG4CXX',
|
||||
use='NDN_CXX BOOST LOG4CXX SYNC',
|
||||
includes='. src',
|
||||
export_includes='. src',
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user