make chronosync a dependency

refs: #2400

Change-Id: I8b488f165a4f9a2c9a7731931be3b6d2e3c43c89
This commit is contained in:
Ashlesh Gawande committed 2017-05-02 14:26:16 -05:00
1 parent c780a6986b
commit 415676b6cc
59 files changed
+165 -5533

No files matched your search

+3 -3
View File
@@ -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
+2 -2
View File
@@ -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
+58
View File
@@ -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
-47
View File
@@ -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''')
-47
View File
@@ -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
View File
@@ -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
-----
-3
View File
@@ -1,3 +0,0 @@
nsync is a copy of ChronoSync (https://github.com/bruinfish/ChronoSync/tree/master).
ChonoSync's license is GPL2.
-15
View File
@@ -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>
-21
View File
@@ -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
-49
View File
@@ -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
-74
View File
@@ -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;
}
}
-91
View File
@@ -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
-72
View File
@@ -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
-98
View File
@@ -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
-102
View File
@@ -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
-262
View File
@@ -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
-199
View File
@@ -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
-35
View File
@@ -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
-49
View File
@@ -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
-71
View File
@@ -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
-118
View File
@@ -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
-79
View File
@@ -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
-99
View File
@@ -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
-126
View File
@@ -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));
}
}
-96
View File
@@ -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
-43
View File
@@ -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
-84
View File
@@ -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
-61
View File
@@ -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
-74
View File
@@ -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
-84
View File
@@ -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
-752
View File
@@ -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;
}
}
-223
View File
@@ -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
-32
View File
@@ -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
-102
View File
@@ -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
-36
View File
@@ -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
-198
View File
@@ -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
-184
View File
@@ -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
-134
View File
@@ -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
-101
View File
@@ -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
-169
View File
@@ -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;
}
}
-116
View File
@@ -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
-24
View File
@@ -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;
}
-89
View File
@@ -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
-74
View File
@@ -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
+7 -9
View File
@@ -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
+3 -4
View File
@@ -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:
+1 -4
View File
@@ -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
View File
@@ -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;
-399
View File
@@ -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();
}
-104
View File
@@ -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()
-108
View File
@@ -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()
-294
View File
@@ -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()
+1
View File
@@ -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();
+3 -3
View File
@@ -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());
+44 -25
View File
@@ -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);
}
-9
View File
@@ -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(
+5 -18
View File
@@ -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',
)