Compare commits
96
Commits
NLSR-0.3.2
...
NLSR-0.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39cf81a110 | ||
|
|
b0bf8df1bd | ||
|
|
a073e2e23e | ||
|
|
9da6aa7fce | ||
|
|
304bebf64f | ||
|
|
982a58fae5 | ||
|
|
7afe22f410 | ||
|
|
f7da9c542c | ||
|
|
c3ea26f000 | ||
|
|
0d2c38299e | ||
|
|
563611eb20 | ||
|
|
af87575012 | ||
|
|
4964870e9d | ||
|
|
b2ef6adbd3 | ||
|
|
cf8d0eda75 | ||
|
|
437adfeed6 | ||
|
|
357318540d | ||
|
|
14ab329746 | ||
|
|
ed473c6c47 | ||
|
|
ac4b65664f | ||
|
|
d88c1dfdc2 | ||
|
|
9e955bcec7 | ||
|
|
f04f98943d | ||
|
|
2f62338d12 | ||
|
|
ae0a047c41 | ||
|
|
5bcb39e255 | ||
|
|
0fa4c77987 | ||
|
|
22cc1a8d17 | ||
|
|
96861ca49c | ||
|
|
faf49f4c32 | ||
|
|
9212bd43bb | ||
|
|
727d4830d7 | ||
|
|
ff9a62713b | ||
|
|
e18296c270 | ||
|
|
2a1ac616b3 | ||
|
|
a47255c2c5 | ||
|
|
ffb62fa3fb | ||
|
|
114537f6e0 | ||
|
|
922714a0d9 | ||
|
|
5867b5233f | ||
|
|
d40a588e25 | ||
|
|
8f23b5d58e | ||
|
|
9eac4d9830 | ||
|
|
6ebfd7c182 | ||
|
|
b7b5839197 | ||
|
|
813df80e20 | ||
|
|
0bd37314fe | ||
|
|
6a81b77260 | ||
|
|
c0c6bcf7e2 | ||
|
|
098aae410a | ||
|
|
e40377d570 | ||
|
|
7afcab4652 | ||
|
|
e98480b5d1 | ||
|
|
d0a7df337f | ||
|
|
e0d2048d5f | ||
|
|
f14ec357d5 | ||
|
|
c58cc7f596 | ||
|
|
22b5c957c0 | ||
|
|
90173ad966 | ||
|
|
608061b95d | ||
|
|
793e8707a1 | ||
|
|
54a43f06e1 | ||
|
|
820bb66350 | ||
|
|
9b71bbc970 | ||
|
|
3909aa160a | ||
|
|
d5c1a378d1 | ||
|
|
f6bfb14def | ||
|
|
d22da51783 | ||
|
|
a75fdb27c5 | ||
|
|
cd7ca05378 | ||
|
|
b00dc2acea | ||
|
|
0f1bf1dfcd | ||
|
|
8bfd124212 | ||
|
|
7600c90882 | ||
|
|
e9733ed876 | ||
|
|
b9e2c650e6 | ||
|
|
494de4033d | ||
|
|
56d1fae10a | ||
|
|
adad2490e5 | ||
|
|
b23f279353 | ||
|
|
3e105a0493 | ||
|
|
b9c5cecfb2 | ||
|
|
f8852c2d27 | ||
|
|
9461afb721 | ||
|
|
2108808ae3 | ||
|
|
6fa00d923c | ||
|
|
b4567f40fb | ||
|
|
415676b6cc | ||
|
|
c780a6986b | ||
|
|
9eaf3f4417 | ||
|
|
c2c3ae0fd2 | ||
|
|
812af97447 | ||
|
|
e689dd6d8b | ||
|
|
4d2c6c07ae | ||
|
|
30096b8f37 | ||
|
|
3be6466a85 |
No files matched your search
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
FORMULAE=(boost pkg-config openssl)
|
||||
brew update
|
||||
if [[ -n $TRAVIS ]]; then
|
||||
# travis images come with a large number of brew packages
|
||||
# pre-installed, don't waste time upgrading all of them
|
||||
for FORMULA in "${FORMULAE[@]}"; do
|
||||
brew outdated $FORMULA || brew upgrade $FORMULA
|
||||
done
|
||||
else
|
||||
brew upgrade
|
||||
fi
|
||||
brew install "${FORMULAE[@]}"
|
||||
brew cleanup
|
||||
fi
|
||||
|
||||
if has Ubuntu $NODE_LABELS; then
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qy install build-essential pkg-config libboost-all-dev \
|
||||
libsqlite3-dev libssl-dev
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
sudo apt-get -qy install lcov libgd-perl python-setuptools
|
||||
sudo easy_install --upgrade gcovr
|
||||
fi
|
||||
fi
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
if has OSX $NODE_LABELS && ! has OSX-10.8-c++11-64bit $NODE_LABELS; then
|
||||
# OSX 10.8 requires special handling of dependencies
|
||||
set -x
|
||||
brew update
|
||||
brew upgrade
|
||||
brew install boost pkg-config sqlite cryptopp log4cxx protobuf openssl
|
||||
brew link --force openssl log4cxx protobuf
|
||||
brew cleanup
|
||||
fi
|
||||
|
||||
if has Ubuntu $NODE_LABELS; then
|
||||
BOOST_PKG=libboost-all-dev
|
||||
if has Ubuntu-12.04 $NODE_LABELS; then
|
||||
BOOST_PKG=libboost1.48-all-dev
|
||||
fi
|
||||
|
||||
set -x
|
||||
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
|
||||
fi
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
|
||||
pushd "${CACHE_DIR:-/tmp}" >/dev/null
|
||||
|
||||
INSTALLED_VERSION=
|
||||
if has OSX $NODE_LABELS; then
|
||||
BOOST=$(brew ls --versions boost)
|
||||
OLD_BOOST=$(cat boost.txt || :)
|
||||
if [[ $OLD_BOOST != $BOOST ]]; then
|
||||
echo "$BOOST" > boost.txt
|
||||
INSTALLED_VERSION=NONE
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z $INSTALLED_VERSION ]]; then
|
||||
INSTALLED_VERSION=$(git -C ndn-cxx rev-parse HEAD 2>/dev/null || echo NONE)
|
||||
fi
|
||||
|
||||
sudo rm -Rf ndn-cxx-latest
|
||||
|
||||
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
|
||||
|
||||
LATEST_VERSION=$(git -C ndn-cxx-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
|
||||
|
||||
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
|
||||
sudo rm -Rf ndn-cxx
|
||||
mv ndn-cxx-latest ndn-cxx
|
||||
else
|
||||
sudo rm -Rf ndn-cxx-latest
|
||||
fi
|
||||
|
||||
sudo rm -f /usr/local/bin/ndnsec*
|
||||
sudo rm -fr /usr/local/include/ndn-cxx
|
||||
sudo rm -f /usr/local/lib/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx.pc
|
||||
|
||||
pushd ndn-cxx >/dev/null
|
||||
|
||||
./waf configure --color=yes --enable-shared --disable-static --without-osx-keychain
|
||||
./waf build --color=yes -j${WAF_JOBS:-1}
|
||||
sudo env "PATH=$PATH" ./waf install --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
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
|
||||
pushd "${CACHE_DIR:-/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=$(git -C ChronoSync 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=$(git -C ChronoSync-latest 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 -fr /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 configure --color=yes
|
||||
./waf build --color=yes -j${WAF_JOBS:-1}
|
||||
sudo env "PATH=$PATH" ./waf install --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
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
|
||||
git submodule init
|
||||
git submodule sync
|
||||
git submodule update
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
elif [[ -z $DISABLE_ASAN ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
|
||||
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
|
||||
# Configure/build in optimized mode with tests
|
||||
./waf --color=yes configure --with-tests
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
|
||||
# Configure/build in optimized mode without tests
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
fi
|
||||
|
||||
# Configure/build in debug mode with tests
|
||||
./waf --color=yes configure --debug --with-tests $ASAN $COVERAGE
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
|
||||
# (tests will be run against debug version)
|
||||
|
||||
# Install
|
||||
sudo env "PATH=$PATH" ./waf --color=yes install
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/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=$((cd ndn-cxx && git rev-parse HEAD) 2>/dev/null || echo NONE)
|
||||
|
||||
sudo rm -Rf ndn-cxx-latest
|
||||
|
||||
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
|
||||
|
||||
LATEST_VERSION=$((cd ndn-cxx-latest && git rev-parse HEAD) 2>/dev/null || echo UNKNOWN)
|
||||
|
||||
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
|
||||
sudo rm -Rf ndn-cxx
|
||||
mv ndn-cxx-latest ndn-cxx
|
||||
else
|
||||
sudo rm -Rf ndn-cxx-latest
|
||||
fi
|
||||
|
||||
sudo rm -Rf /usr/local/include/ndn-cxx
|
||||
sudo rm -f /usr/local/lib/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx*
|
||||
|
||||
pushd ndn-cxx >/dev/null
|
||||
|
||||
./waf configure -j1 --color=yes --enable-shared --disable-static --without-osx-keychain
|
||||
./waf -j1 --color=yes
|
||||
sudo ./waf install -j1 --color=yes
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
sudo ldconfig
|
||||
elif has FreeBSD $NODE_LABELS; then
|
||||
sudo ldconfig -a
|
||||
fi
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
set -e
|
||||
|
||||
git submodule init
|
||||
git submodule sync
|
||||
git submodule update
|
||||
|
||||
COVERAGE=$( python -c "print '--with-coverage' if 'code-coverage' in '$JOB_NAME' else ''" )
|
||||
|
||||
# Cleanup
|
||||
sudo ./waf -j1 --color=yes distclean
|
||||
|
||||
# Configure/build in debug mode
|
||||
./waf -j1 --color=yes configure --with-tests --debug
|
||||
./waf -j1 --color=yes build
|
||||
|
||||
# Cleanup
|
||||
sudo ./waf -j1 --color=yes distclean
|
||||
|
||||
# Configure/build in optimized mode without tests
|
||||
./waf -j1 --color=yes configure
|
||||
./waf -j1 --color=yes build
|
||||
|
||||
# Cleanup
|
||||
sudo ./waf -j1 --color=yes distclean
|
||||
|
||||
# Configure/build in optimized mode with tests
|
||||
./waf -j1 --color=yes configure --with-tests $COVERAGE
|
||||
./waf -j1 --color=yes build
|
||||
|
||||
# (tests will be run against optimized version)
|
||||
|
||||
./waf configure --color=yes --with-tests $COVERAGE
|
||||
|
||||
./waf -j1 --color=yes
|
||||
sudo ./waf install --color=yes
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Prepare environment
|
||||
rm -Rf ~/.ndn
|
||||
|
||||
ut_log_args() {
|
||||
echo --log_level=test_suite
|
||||
}
|
||||
|
||||
ASAN_OPTIONS="color=always"
|
||||
ASAN_OPTIONS+=":detect_stack_use_after_return=true"
|
||||
ASAN_OPTIONS+=":check_initialization_order=true"
|
||||
ASAN_OPTIONS+=":strict_init_order=true"
|
||||
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=1"
|
||||
ASAN_OPTIONS+=":detect_container_overflow=false"
|
||||
ASAN_OPTIONS+=":strict_string_checks=true"
|
||||
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
|
||||
export ASAN_OPTIONS
|
||||
|
||||
# Run unit tests
|
||||
./build/unit-tests-nlsr $(ut_log_args)
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
lcov --quiet \
|
||||
--capture \
|
||||
--directory . \
|
||||
--no-external \
|
||||
--rc lcov_branch_coverage=1 \
|
||||
--output-file build/coverage-with-tests.info
|
||||
|
||||
lcov --quiet \
|
||||
--remove build/coverage-with-tests.info "$PWD/tests/*" \
|
||||
--rc lcov_branch_coverage=1 \
|
||||
--output-file build/coverage.info
|
||||
|
||||
genhtml --branch-coverage \
|
||||
--demangle-cpp \
|
||||
--frames \
|
||||
--legend \
|
||||
--output-directory build/coverage \
|
||||
--title "NLSR unit tests" \
|
||||
build/coverage.info
|
||||
fi
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
set -e
|
||||
|
||||
rm -Rf ~/.ndn
|
||||
|
||||
./build/unit-tests-nlsr -l test_suite
|
||||
@@ -0,0 +1,36 @@
|
||||
CONTINUOUS INTEGRATION SCRIPTS
|
||||
==============================
|
||||
|
||||
Environment Variables Used in Build Scripts
|
||||
-------------------------------------------
|
||||
|
||||
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
|
||||
build scripts to select proper behavior for different OS.
|
||||
|
||||
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
|
||||
|
||||
Possible values for Linux:
|
||||
|
||||
* `[OS_TYPE]`: `Linux`
|
||||
* `[DISTRO_TYPE]`: `Ubuntu`
|
||||
* `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04`
|
||||
|
||||
Possible values for OS X / macOS:
|
||||
|
||||
* `[OS_TYPE]`: `OSX`
|
||||
* `[DISTRO_TYPE]`: `OSX` (can be absent)
|
||||
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12`
|
||||
|
||||
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
|
||||
the build scripts can perform different tasks.
|
||||
|
||||
Possible values:
|
||||
|
||||
* empty: default build process
|
||||
* `code-coverage` (Linux OS is assumed): debug build with tests and code coverage analysis
|
||||
* `limited-build`: only a single debug build with tests
|
||||
|
||||
- `CACHE_DIR`: the variable defines a path to folder containing cached files from previous builds,
|
||||
e.g., a compiled version of ndn-cxx library. If not set, `/tmp` is used.
|
||||
|
||||
- `WAF_JOBS`: number of parallel build jobs used by waf, defaults to 1.
|
||||
Executable → Regular
+13
-4
@@ -1,9 +1,18 @@
|
||||
has() {
|
||||
local saved_xtrace
|
||||
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
|
||||
set +x
|
||||
|
||||
local p=$1
|
||||
shift
|
||||
local x
|
||||
for x in "$@"; do
|
||||
[[ "${x}" == "${p}" ]] && return 0
|
||||
local i ret=1
|
||||
for i in "$@"; do
|
||||
if [[ "${i}" == "${p}" ]]; then
|
||||
ret=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
|
||||
set ${saved_xtrace}
|
||||
return ${ret}
|
||||
}
|
||||
+95
-17
@@ -1,25 +1,103 @@
|
||||
language: cpp
|
||||
dist: trusty
|
||||
sudo: required
|
||||
language: generic
|
||||
env:
|
||||
global:
|
||||
- JOB_NAME=limited-build
|
||||
- WAF_JOBS=2
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Linux/gcc
|
||||
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
|
||||
- os: linux
|
||||
dist: trusty
|
||||
env:
|
||||
- CXX=g++
|
||||
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
|
||||
env: COMPILER=g++-4.8
|
||||
- os: linux
|
||||
dist: trusty
|
||||
env:
|
||||
- CXX=clang++
|
||||
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
|
||||
env: COMPILER=g++-4.9
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-4.9
|
||||
- os: linux
|
||||
env: COMPILER=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-5
|
||||
- os: linux
|
||||
env: COMPILER=g++-6
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-6
|
||||
- os: linux
|
||||
env: COMPILER=g++-7
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-7
|
||||
|
||||
# Linux/clang
|
||||
# https://apt.llvm.org/
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.5
|
||||
addons:
|
||||
apt:
|
||||
packages: clang-3.5
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.6
|
||||
addons:
|
||||
apt:
|
||||
packages: clang-3.6
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-precise-3.7", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.7
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.8
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-precise-3.8", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.8
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.9 DISABLE_ASAN=yes
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-3.9", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.9
|
||||
- os: linux
|
||||
env: COMPILER=clang++-4.0
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-4.0", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-4.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-5.0
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-5.0", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-5.0
|
||||
|
||||
# macOS/clang
|
||||
# https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
|
||||
- os: osx
|
||||
osx_image: xcode8.2
|
||||
env:
|
||||
- CXX=clang++
|
||||
- NODE_LABELS="OSX OSX-10.12"
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
||||
on_failure: always
|
||||
osx_image: xcode7.3
|
||||
env: OSX_VERSION=10.11
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
env: OSX_VERSION=10.12
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
env: OSX_VERSION=10.12
|
||||
|
||||
before_script:
|
||||
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-14.04"; fi
|
||||
- if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi
|
||||
- if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi
|
||||
- ${CXX:-c++} --version
|
||||
- python --version
|
||||
|
||||
script:
|
||||
- ./.jenkins
|
||||
+216
-76
@@ -30,15 +30,15 @@ When using this tool, the wscript will look like:
|
||||
|
||||
Options are generated, in order to specify the location of boost includes/libraries.
|
||||
The `check_boost` configuration function allows to specify the used boost libraries.
|
||||
It can also provide default arguments to the --boost-static and --boost-mt command-line arguments.
|
||||
It can also provide default arguments to the --boost-mt command-line arguments.
|
||||
Everything will be packaged together in a BOOST component that you can use.
|
||||
|
||||
When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
|
||||
- you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
|
||||
Errors: C4530
|
||||
- boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
|
||||
So before calling `conf.check_boost` you might want to disabling by adding:
|
||||
conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
|
||||
So before calling `conf.check_boost` you might want to disabling by adding
|
||||
conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
|
||||
Errors:
|
||||
- boost might also be compiled with /MT, which links the runtime statically.
|
||||
If you have problems with redefined symbols,
|
||||
@@ -52,24 +52,55 @@ import sys
|
||||
import re
|
||||
from waflib import Utils, Logs, Errors
|
||||
from waflib.Configure import conf
|
||||
from waflib.TaskGen import feature, after_method
|
||||
|
||||
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib', '/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu', '/usr/local/ndn/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include', '/usr/local/ndn/include']
|
||||
BOOST_LIBS = ['/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu',
|
||||
'/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
|
||||
BOOST_VERSION_FILE = 'boost/version.hpp'
|
||||
BOOST_VERSION_CODE = '''
|
||||
#include <iostream>
|
||||
#include <boost/version.hpp>
|
||||
int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
|
||||
'''
|
||||
BOOST_SYSTEM_CODE = '''
|
||||
|
||||
BOOST_ERROR_CODE = '''
|
||||
#include <boost/system/error_code.hpp>
|
||||
int main() { boost::system::error_code c; }
|
||||
'''
|
||||
|
||||
PTHREAD_CODE = '''
|
||||
#include <pthread.h>
|
||||
static void* f(void*) { return 0; }
|
||||
int main() {
|
||||
pthread_t th;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_create(&th, &attr, &f, 0);
|
||||
pthread_join(th, 0);
|
||||
pthread_cleanup_push(0, 0);
|
||||
pthread_cleanup_pop(0);
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
'''
|
||||
|
||||
BOOST_THREAD_CODE = '''
|
||||
#include <boost/thread.hpp>
|
||||
int main() { boost::thread t; }
|
||||
'''
|
||||
|
||||
BOOST_LOG_CODE = '''
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup/console.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
int main() {
|
||||
using namespace boost::log;
|
||||
add_common_attributes();
|
||||
add_console_log(std::clog, keywords::format = "%Message%");
|
||||
BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
|
||||
}
|
||||
'''
|
||||
|
||||
# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
|
||||
PLATFORM = Utils.unversioned_sys_platform()
|
||||
detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
|
||||
@@ -101,34 +132,37 @@ BOOST_TOOLSETS = {
|
||||
|
||||
def options(opt):
|
||||
opt = opt.add_option_group('Boost Options')
|
||||
|
||||
opt.add_option('--boost-includes', type='string',
|
||||
default='', dest='boost_includes',
|
||||
help='''path to the directory where the boost includes are, e.g., /path/to/boost_1_55_0/stage/include''')
|
||||
help='''path to the directory where the boost includes are,
|
||||
e.g., /path/to/boost_1_55_0/stage/include''')
|
||||
opt.add_option('--boost-libs', type='string',
|
||||
default='', dest='boost_libs',
|
||||
help='''path to the directory where the boost libs are, e.g., /path/to/boost_1_55_0/stage/lib''')
|
||||
opt.add_option('--boost-static', action='store_true',
|
||||
default=False, dest='boost_static',
|
||||
help='link with static boost libraries (.lib/.a)')
|
||||
help='''path to the directory where the boost libs are,
|
||||
e.g., path/to/boost_1_55_0/stage/lib''')
|
||||
opt.add_option('--boost-mt', action='store_true',
|
||||
default=False, dest='boost_mt',
|
||||
help='select multi-threaded libraries')
|
||||
opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
|
||||
help='''select libraries with tags (dgsyp, d for debug), see doc Boost, Getting Started, chapter 6.1''')
|
||||
help='''select libraries with tags (gd for debug, static is automatically added),
|
||||
see doc Boost, Getting Started, chapter 6.1''')
|
||||
opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
|
||||
help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
|
||||
opt.add_option('--boost-toolset', type='string',
|
||||
default='', dest='boost_toolset',
|
||||
help='force a toolset e.g. msvc, vc90, gcc, mingw, mgw45 (default: auto)')
|
||||
help='force a toolset e.g. msvc, vc90, \
|
||||
gcc, mingw, mgw45 (default: auto)')
|
||||
py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
|
||||
opt.add_option('--boost-python', type='string',
|
||||
default=py_version, dest='boost_python',
|
||||
help='select the lib python with this version (default: %s)' % py_version)
|
||||
help='select the lib python with this version \
|
||||
(default: %s)' % py_version)
|
||||
|
||||
|
||||
@conf
|
||||
def __boost_get_version_file(self, d):
|
||||
if not d:
|
||||
return None
|
||||
dnode = self.root.find_dir(d)
|
||||
if dnode:
|
||||
return dnode.find_node(BOOST_VERSION_FILE)
|
||||
@@ -141,18 +175,15 @@ def boost_get_version(self, d):
|
||||
if node:
|
||||
try:
|
||||
txt = node.read()
|
||||
except (OSError, IOError):
|
||||
except EnvironmentError:
|
||||
Logs.error("Could not read the file %r" % node.abspath())
|
||||
else:
|
||||
re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
|
||||
m1 = re_but1.search(txt)
|
||||
|
||||
re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
|
||||
m2 = re_but2.search(txt)
|
||||
|
||||
if m1 and m2:
|
||||
return (m1.group(1), m2.group(1))
|
||||
|
||||
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
|
||||
|
||||
@conf
|
||||
@@ -160,7 +191,7 @@ def boost_get_includes(self, *k, **kw):
|
||||
includes = k and k[0] or kw.get('includes', None)
|
||||
if includes and self.__boost_get_version_file(includes):
|
||||
return includes
|
||||
for d in Utils.to_list(self.environ.get('INCLUDE', '')) + BOOST_INCLUDES:
|
||||
for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES:
|
||||
if self.__boost_get_version_file(d):
|
||||
return d
|
||||
if includes:
|
||||
@@ -195,7 +226,9 @@ def __boost_get_libs_path(self, *k, **kw):
|
||||
path = self.root.find_dir(libs)
|
||||
files = path.ant_glob('*boost_*')
|
||||
if not libs or not files:
|
||||
for d in Utils.to_list(self.environ.get('LIB', [])) + BOOST_LIBS:
|
||||
for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS:
|
||||
if not d:
|
||||
continue
|
||||
path = self.root.find_dir(d)
|
||||
if path:
|
||||
files = path.ant_glob('*boost_*')
|
||||
@@ -226,15 +259,10 @@ def boost_get_libs(self, *k, **kw):
|
||||
according to the parameters
|
||||
'''
|
||||
path, files = self.__boost_get_libs_path(**kw)
|
||||
t = []
|
||||
if kw.get('mt', False):
|
||||
t.append('mt')
|
||||
if kw.get('abi', None):
|
||||
t.append(kw['abi'])
|
||||
tags = t and '(-%s)+' % '-'.join(t) or ''
|
||||
files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True)
|
||||
toolset = self.boost_get_toolset(kw.get('toolset', ''))
|
||||
toolset_pat = '(-%s[0-9]{0,3})+' % toolset
|
||||
version = '(-%s)+' % self.env.BOOST_VERSION
|
||||
toolset_pat = '(-%s[0-9]{0,3})' % toolset
|
||||
version = '-%s' % self.env.BOOST_VERSION
|
||||
|
||||
def find_lib(re_lib, files):
|
||||
for file in files:
|
||||
@@ -248,28 +276,110 @@ def boost_get_libs(self, *k, **kw):
|
||||
name = name[3:]
|
||||
return name[:name.rfind('.')]
|
||||
|
||||
libs = []
|
||||
for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
|
||||
py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
|
||||
# Trying libraries, from most strict match to least one
|
||||
for pattern in ['boost_%s%s%s%s%s' % (lib, toolset_pat, tags, py, version),
|
||||
'boost_%s%s%s%s' % (lib, tags, py, version),
|
||||
'boost_%s%s%s' % (lib, tags, version),
|
||||
# Give up trying to find the right version
|
||||
'boost_%s%s%s%s' % (lib, toolset_pat, tags, py),
|
||||
'boost_%s%s%s' % (lib, tags, py),
|
||||
'boost_%s%s' % (lib, tags)]:
|
||||
self.to_log('Trying pattern %s' % pattern)
|
||||
file = find_lib(re.compile(pattern), files)
|
||||
if file:
|
||||
libs.append(format_lib_name(file.name))
|
||||
break
|
||||
else:
|
||||
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
|
||||
self.fatal('The configuration failed')
|
||||
def match_libs(lib_names, is_static):
|
||||
libs = []
|
||||
lib_names = Utils.to_list(lib_names)
|
||||
if not lib_names:
|
||||
return libs
|
||||
t = []
|
||||
if kw.get('mt', False):
|
||||
t.append('-mt')
|
||||
if kw.get('abi', None):
|
||||
t.append('%s%s' % (is_static and '-s' or '-', kw['abi']))
|
||||
elif is_static:
|
||||
t.append('-s')
|
||||
tags_pat = t and ''.join(t) or ''
|
||||
ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN
|
||||
ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN
|
||||
|
||||
return path.abspath(), libs
|
||||
for lib in lib_names:
|
||||
if lib == 'python':
|
||||
# for instance, with python='27',
|
||||
# accepts '-py27', '-py2', '27' and '2'
|
||||
# but will reject '-py3', '-py26', '26' and '3'
|
||||
tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'])
|
||||
else:
|
||||
tags = tags_pat
|
||||
# Trying libraries, from most strict match to least one
|
||||
for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext),
|
||||
'boost_%s%s%s%s$' % (lib, tags, version, ext),
|
||||
# Give up trying to find the right version
|
||||
'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext),
|
||||
'boost_%s%s%s$' % (lib, tags, ext),
|
||||
'boost_%s%s$' % (lib, ext),
|
||||
'boost_%s' % lib]:
|
||||
self.to_log('Trying pattern %s' % pattern)
|
||||
file = find_lib(re.compile(pattern), files)
|
||||
if file:
|
||||
libs.append(format_lib_name(file.name))
|
||||
break
|
||||
else:
|
||||
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
|
||||
self.fatal('The configuration failed')
|
||||
return libs
|
||||
|
||||
return path.abspath(), match_libs(kw.get('lib', None), False), match_libs(kw.get('stlib', None), True)
|
||||
|
||||
@conf
|
||||
def _check_pthread_flag(self, *k, **kw):
|
||||
'''
|
||||
Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode
|
||||
|
||||
Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
|
||||
boost/thread.hpp will trigger a #error if -pthread isn't used:
|
||||
boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
|
||||
is not turned on. Please set the correct command line options for
|
||||
threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
|
||||
|
||||
Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
|
||||
'''
|
||||
|
||||
var = kw.get('uselib_store', 'BOOST')
|
||||
|
||||
self.start_msg('Checking the flags needed to use pthreads')
|
||||
|
||||
# The ordering *is* (sometimes) important. Some notes on the
|
||||
# individual items follow:
|
||||
# (none): in case threads are in libc; should be tried before -Kthread and
|
||||
# other compiler flags to prevent continual compiler warnings
|
||||
# -lpthreads: AIX (must check this before -lpthread)
|
||||
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
|
||||
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
|
||||
# -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
|
||||
# -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
|
||||
# -pthreads: Solaris/GCC
|
||||
# -mthreads: MinGW32/GCC, Lynx/GCC
|
||||
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
|
||||
# doesn't hurt to check since this sometimes defines pthreads too;
|
||||
# also defines -D_REENTRANT)
|
||||
# ... -mt is also the pthreads flag for HP/aCC
|
||||
# -lpthread: GNU Linux, etc.
|
||||
# --thread-safe: KAI C++
|
||||
if Utils.unversioned_sys_platform() == "sunos":
|
||||
# On Solaris (at least, for some versions), libc contains stubbed
|
||||
# (non-functional) versions of the pthreads routines, so link-based
|
||||
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
|
||||
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
|
||||
# a function called by this macro, so we could check for that, but
|
||||
# who knows whether they'll stub that too in a future libc.) So,
|
||||
# we'll just look for -pthreads and -lpthread first:
|
||||
boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
|
||||
else:
|
||||
boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
|
||||
"-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
|
||||
|
||||
for boost_pthread_flag in boost_pthread_flags:
|
||||
try:
|
||||
self.env.stash()
|
||||
self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
|
||||
self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
|
||||
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
|
||||
|
||||
self.end_msg(boost_pthread_flag)
|
||||
return
|
||||
except self.errors.ConfigurationError:
|
||||
self.env.revert()
|
||||
self.end_msg('None')
|
||||
|
||||
@conf
|
||||
def check_boost(self, *k, **kw):
|
||||
@@ -282,7 +392,10 @@ def check_boost(self, *k, **kw):
|
||||
if not self.env['CXX']:
|
||||
self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
|
||||
|
||||
params = {'lib': k and k[0] or kw.get('lib', None)}
|
||||
params = {
|
||||
'lib': k and k[0] or kw.get('lib', None),
|
||||
'stlib': kw.get('stlib', None)
|
||||
}
|
||||
for key, value in self.options.__dict__.items():
|
||||
if not key.startswith('boost_'):
|
||||
continue
|
||||
@@ -297,42 +410,53 @@ def check_boost(self, *k, **kw):
|
||||
self.env.BOOST_VERSION = versions[0]
|
||||
self.env.BOOST_VERSION_NUMBER = int(versions[1])
|
||||
self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
|
||||
int(versions[1]) / 100 % 1000,
|
||||
int(versions[1]) % 100))
|
||||
int(versions[1]) / 100 % 1000,
|
||||
int(versions[1]) % 100))
|
||||
if Logs.verbose:
|
||||
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
|
||||
|
||||
if not params['lib']:
|
||||
if not params['lib'] and not params['stlib']:
|
||||
return
|
||||
if 'static' in kw or 'static' in params:
|
||||
Logs.warn('boost: static parameter is deprecated, use stlib instead.')
|
||||
self.start_msg('Checking boost libs')
|
||||
suffix = params.get('static', None) and 'ST' or ''
|
||||
path, libs = self.boost_get_libs(**params)
|
||||
self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
|
||||
self.env['%sLIB_%s' % (suffix, var)] = libs
|
||||
path, libs, stlibs = self.boost_get_libs(**params)
|
||||
self.env['LIBPATH_%s' % var] = [path]
|
||||
self.env['STLIBPATH_%s' % var] = [path]
|
||||
self.env['LIB_%s' % var] = libs
|
||||
self.env['STLIB_%s' % var] = stlibs
|
||||
self.end_msg('ok')
|
||||
if Logs.verbose:
|
||||
Logs.pprint('CYAN', ' path : %s' % path)
|
||||
Logs.pprint('CYAN', ' libs : %s' % libs)
|
||||
Logs.pprint('CYAN', ' shared libs : %s' % libs)
|
||||
Logs.pprint('CYAN', ' static libs : %s' % stlibs)
|
||||
|
||||
def has_shlib(lib):
|
||||
return params['lib'] and lib in params['lib']
|
||||
def has_stlib(lib):
|
||||
return params['stlib'] and lib in params['stlib']
|
||||
def has_lib(lib):
|
||||
return has_shlib(lib) or has_stlib(lib)
|
||||
if has_lib('thread'):
|
||||
# not inside try_link to make check visible in the output
|
||||
self._check_pthread_flag(k, kw)
|
||||
|
||||
def try_link():
|
||||
if 'system' in params['lib']:
|
||||
self.check_cxx(
|
||||
fragment=BOOST_SYSTEM_CODE,
|
||||
use=var,
|
||||
execute=False,
|
||||
)
|
||||
if 'thread' in params['lib']:
|
||||
self.check_cxx(
|
||||
fragment=BOOST_THREAD_CODE,
|
||||
use=var,
|
||||
execute=False,
|
||||
)
|
||||
if has_lib('system'):
|
||||
self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
|
||||
if has_lib('thread'):
|
||||
self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
|
||||
if has_lib('log'):
|
||||
if not has_lib('thread'):
|
||||
self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
|
||||
if has_shlib('log'):
|
||||
self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
|
||||
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
|
||||
|
||||
if params.get('linkage_autodetect', False):
|
||||
self.start_msg("Attempting to detect boost linkage flags")
|
||||
toolset = self.boost_get_toolset(kw.get('toolset', ''))
|
||||
if toolset in ['vc']:
|
||||
if toolset in ('vc',):
|
||||
# disable auto-linking feature, causing error LNK1181
|
||||
# because the code wants to be linked against
|
||||
self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
|
||||
@@ -356,14 +480,14 @@ def check_boost(self, *k, **kw):
|
||||
try:
|
||||
try_link()
|
||||
self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
|
||||
e = None
|
||||
exc = None
|
||||
break
|
||||
except Errors.ConfigurationError as exc:
|
||||
except Errors.ConfigurationError as e:
|
||||
self.env.revert()
|
||||
e = exc
|
||||
exc = e
|
||||
|
||||
if e is not None:
|
||||
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=e)
|
||||
if exc is not None:
|
||||
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
|
||||
self.fatal('The configuration failed')
|
||||
else:
|
||||
self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
|
||||
@@ -376,3 +500,19 @@ def check_boost(self, *k, **kw):
|
||||
self.end_msg("Could not link against boost libraries using supplied options")
|
||||
self.fatal('The configuration failed')
|
||||
self.end_msg('ok')
|
||||
|
||||
|
||||
@feature('cxx')
|
||||
@after_method('apply_link')
|
||||
def install_boost(self):
|
||||
if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'):
|
||||
return
|
||||
install_boost.done = True
|
||||
inst_to = getattr(self, 'install_path', '${BINDIR}')
|
||||
for lib in self.env.LIB_BOOST:
|
||||
try:
|
||||
file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST)
|
||||
self.bld.install_files(inst_to, self.bld.root.find_node(file))
|
||||
except:
|
||||
continue
|
||||
install_boost.done = False
|
||||
@@ -1,10 +1,6 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
#
|
||||
# Copyright (c) 2014, Regents of the University of California
|
||||
#
|
||||
# GPL 3.0 license, see the COPYING.md file for more information
|
||||
|
||||
from waflib import TaskGen
|
||||
from waflib import TaskGen, Logs
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage',
|
||||
@@ -12,6 +8,8 @@ def options(opt):
|
||||
|
||||
def configure(conf):
|
||||
if conf.options.with_coverage:
|
||||
if not conf.options.debug:
|
||||
conf.fatal("Code coverage flags require debug mode compilation (add --debug)")
|
||||
conf.check_cxx(cxxflags=['-fprofile-arcs', '-ftest-coverage', '-fPIC'],
|
||||
linkflags=['-fprofile-arcs'], uselib_store='GCOV', mandatory=True)
|
||||
|
||||
|
||||
@@ -4,17 +4,37 @@ from waflib import Logs, Configure, Utils
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug',
|
||||
help='''Compile in debugging mode without optimizations (-O0 or -Og)''')
|
||||
help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''')
|
||||
|
||||
def configure(conf):
|
||||
cxx = conf.env['CXX_NAME'] # CXX_NAME represents generic name of the compiler
|
||||
conf.start_msg('Checking C++ compiler version')
|
||||
|
||||
cxx = conf.env['CXX_NAME'] # CXX_NAME is the generic name of the compiler
|
||||
ccver = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
errmsg = ''
|
||||
warnmsg = ''
|
||||
if cxx == 'gcc':
|
||||
if ccver < (4, 8, 2):
|
||||
errmsg = ('The version of gcc you are using is too old.\n'
|
||||
'The minimum supported gcc version is 4.8.2.')
|
||||
flags = GccFlags()
|
||||
elif cxx == 'clang':
|
||||
if ccver < (3, 4, 0):
|
||||
errmsg = ('The version of clang you are using is too old.\n'
|
||||
'The minimum supported clang version is 3.4.0.')
|
||||
flags = ClangFlags()
|
||||
else:
|
||||
warnmsg = 'Note: %s compiler is unsupported' % cxx
|
||||
flags = CompilerFlags()
|
||||
Logs.warn('The code has not yet been tested with %s compiler' % cxx)
|
||||
|
||||
if errmsg:
|
||||
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED')
|
||||
conf.fatal(errmsg)
|
||||
elif warnmsg:
|
||||
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW')
|
||||
Logs.warn(warnmsg)
|
||||
else:
|
||||
conf.end_msg('.'.join(conf.env['CC_VERSION']))
|
||||
|
||||
areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
|
||||
|
||||
@@ -60,7 +80,7 @@ def add_supported_cxxflags(self, cxxflags):
|
||||
supportedFlags += [flag]
|
||||
|
||||
self.end_msg(' '.join(supportedFlags))
|
||||
self.env.CXXFLAGS = supportedFlags + self.env.CXXFLAGS
|
||||
self.env.prepend_value('CXXFLAGS', supportedFlags)
|
||||
|
||||
@Configure.conf
|
||||
def add_supported_linkflags(self, linkflags):
|
||||
@@ -78,7 +98,7 @@ def add_supported_linkflags(self, linkflags):
|
||||
supportedFlags += [flag]
|
||||
|
||||
self.end_msg(' '.join(supportedFlags))
|
||||
self.env.LINKFLAGS = supportedFlags + self.env.LINKFLAGS
|
||||
self.env.prepend_value('LINKFLAGS', supportedFlags)
|
||||
|
||||
|
||||
class CompilerFlags(object):
|
||||
@@ -98,18 +118,25 @@ class GccBasicFlags(CompilerFlags):
|
||||
"""
|
||||
This class defines basic flags that work for both gcc and clang compilers
|
||||
"""
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++11']
|
||||
return flags
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O0',
|
||||
'-Og', # gcc >= 4.8, clang >= 4.0
|
||||
'-g3',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Werror',
|
||||
'-Wno-unused-parameter',
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
@@ -121,32 +148,16 @@ class GccBasicFlags(CompilerFlags):
|
||||
'-Wextra',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
|
||||
return flags
|
||||
|
||||
class GccFlags(GccBasicFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(GccFlags, self).getGeneralFlags(conf)
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
if version < (4, 6, 0):
|
||||
conf.fatal('The version of gcc you are using (%s) is too old.\n' %
|
||||
'.'.join(conf.env['CC_VERSION']) +
|
||||
'The minimum supported gcc version is 4.6.0.')
|
||||
elif version < (4, 7, 0):
|
||||
flags['CXXFLAGS'] += ['-std=c++0x']
|
||||
else:
|
||||
flags['CXXFLAGS'] += ['-std=c++11']
|
||||
if version < (4, 8, 0):
|
||||
flags['DEFINES'] += ['_GLIBCXX_USE_NANOSLEEP'] # Bug #2499
|
||||
return flags
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccFlags, self).getDebugFlags(conf)
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
if version < (5, 1, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
|
||||
flags['CXXFLAGS'] += ['-Og', # gcc >= 4.8
|
||||
'-fdiagnostics-color', # gcc >= 4.9
|
||||
]
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
@@ -160,7 +171,6 @@ class GccFlags(GccBasicFlags):
|
||||
class ClangFlags(GccBasicFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++11']
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
flags['CXXFLAGS'] += ['-stdlib=libc++']
|
||||
flags['LINKFLAGS'] += ['-stdlib=libc++']
|
||||
@@ -169,24 +179,24 @@ class ClangFlags(GccBasicFlags):
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
'-Wno-error=unneeded-internal-declaration', # Bug #1588
|
||||
'-Wno-error=deprecated-register',
|
||||
'-Wno-error=ignored-qualifiers',
|
||||
'-Wno-error=infinite-recursion', # Bug #3358
|
||||
'-Wno-error=keyword-macro', # Bug #3235
|
||||
'-Wno-error=unneeded-internal-declaration', # Bug #1588
|
||||
'-Wno-keyword-macro',
|
||||
'-Wno-nested-anon-types',
|
||||
'-Wno-sign-compare',
|
||||
'-Wno-keyword-macro',
|
||||
'-Wno-error=ignored-qualifiers',
|
||||
'-Wno-error=infinite-recursion',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
'-Wno-keyword-macro',
|
||||
'-Wno-nested-anon-types',
|
||||
'-Wno-sign-compare',
|
||||
'-Wno-keyword-macro',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
return flags
|
||||
@@ -85,7 +85,7 @@ class doxygen(Task.Task):
|
||||
|
||||
# Override with any parameters passed to the task generator
|
||||
if getattr(self.generator, 'pars', None):
|
||||
for k, v in self.generator.pars.iteritems():
|
||||
for k, v in self.generator.pars.items():
|
||||
self.pars[k] = v
|
||||
|
||||
self.doxy_inputs = getattr(self, 'doxy_inputs', [])
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
'''
|
||||
|
||||
When using this tool, the wscript will look like:
|
||||
|
||||
def options(opt):
|
||||
opt.tool_options('openssl')
|
||||
|
||||
def configure(conf):
|
||||
conf.load('compiler_cxx openssl')
|
||||
conf.check_openssl()
|
||||
|
||||
def build(bld):
|
||||
bld(source='main.cpp', target='app', use='OPENSSL')
|
||||
|
||||
'''
|
||||
|
||||
from waflib import Options
|
||||
from waflib.Configure import conf
|
||||
|
||||
@conf
|
||||
def check_openssl(self,*k,**kw):
|
||||
root = k and k[0] or kw.get('path', None) or Options.options.with_openssl
|
||||
mandatory = kw.get('mandatory', True)
|
||||
var = kw.get('uselib_store', 'OPENSSL')
|
||||
|
||||
if root:
|
||||
libcrypto = self.check_cxx(lib=['ssl', 'crypto'],
|
||||
msg='Checking for OpenSSL library',
|
||||
define_name='HAVE_%s' % var,
|
||||
global_define=True,
|
||||
uselib_store=var,
|
||||
mandatory=mandatory,
|
||||
includes="%s/include" % root,
|
||||
libpath="%s/lib" % root)
|
||||
else:
|
||||
libcrypto = self.check_cxx(lib=['ssl', 'crypto'],
|
||||
msg='Checking for OpenSSL library',
|
||||
define_name='HAVE_%s' % var,
|
||||
uselib_store=var,
|
||||
mandatory=mandatory)
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--with-openssl', type='string', default=None,
|
||||
dest='with_openssl', help='''Path to OpenSSL''')
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# Philipp Bender, 2012
|
||||
# Matt Clarkson, 2012
|
||||
|
||||
from waflib.Task import Task
|
||||
from waflib.TaskGen import extension
|
||||
|
||||
"""
|
||||
A simple tool to integrate protocol buffers into your build system.
|
||||
|
||||
def configure(conf):
|
||||
conf.load('compiler_cxx cxx protoc')
|
||||
|
||||
def build(bld):
|
||||
bld(
|
||||
features = 'cxx cxxprogram'
|
||||
source = 'main.cpp file1.proto proto/file2.proto',
|
||||
include = '. proto',
|
||||
target = 'executable')
|
||||
|
||||
"""
|
||||
|
||||
class protoc(Task):
|
||||
run_str = '${PROTOC} ${PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${SRC[0].abspath()}'
|
||||
color = 'BLUE'
|
||||
ext_out = ['.h', 'pb.cc']
|
||||
|
||||
@extension('.proto')
|
||||
def process_protoc(self, node):
|
||||
cpp_node = node.change_ext('.pb.cc')
|
||||
hpp_node = node.change_ext('.pb.h')
|
||||
self.create_task('protoc', node, [cpp_node, hpp_node])
|
||||
self.source.append(cpp_node)
|
||||
|
||||
if 'cxx' in self.features and not self.env.PROTOC_FLAGS:
|
||||
self.env.PROTOC_FLAGS = '--cpp_out=%s' % node.parent.get_bld().abspath()
|
||||
|
||||
use = getattr(self, 'use', '')
|
||||
if not 'PROTOBUF' in use:
|
||||
self.use = self.to_list(use) + ['PROTOBUF']
|
||||
|
||||
def configure(conf):
|
||||
conf.check_cfg(package="protobuf", uselib_store="PROTOBUF", args=['--cflags', '--libs'])
|
||||
conf.find_program('protoc', var='PROTOC')
|
||||
conf.env.PROTOC_ST = '-I%s'
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--with-sanitizer', action='store', default='', dest='sanitizers',
|
||||
help='Comma-separated list of compiler sanitizers to enable [default=none]')
|
||||
|
||||
def configure(conf):
|
||||
for san in conf.options.sanitizers.split(','):
|
||||
if not san:
|
||||
continue
|
||||
|
||||
sanflag = '-fsanitize=%s' % san
|
||||
conf.start_msg('Checking if compiler supports %s' % sanflag)
|
||||
|
||||
if conf.check_cxx(cxxflags=['-Werror', sanflag, '-fno-omit-frame-pointer'],
|
||||
linkflags=[sanflag], mandatory=False):
|
||||
conf.end_msg('yes')
|
||||
conf.env.append_unique('CXXFLAGS', [sanflag, '-fno-omit-frame-pointer'])
|
||||
conf.env.append_unique('LINKFLAGS', [sanflag])
|
||||
else:
|
||||
conf.end_msg('no', color='RED')
|
||||
conf.fatal('%s sanitizer is not supported by the current compiler' % san)
|
||||
+14
-7
@@ -1,16 +1,18 @@
|
||||
NLSR Authors
|
||||
===========
|
||||
============
|
||||
|
||||
NLSR is an open source project includes contributions from the members of the
|
||||
[NDN project team](http://named-data.net/project/participants/).
|
||||
|
||||
## Project lead:
|
||||
## Project co-leads:
|
||||
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
|
||||
* Nicholas Gordon <nmgordon@memphis.edu>
|
||||
|
||||
## Past project leads:
|
||||
|
||||
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
|
||||
## Technical advisors:
|
||||
|
||||
@@ -24,25 +26,30 @@ NLSR is an open source project includes contributions from the members of the
|
||||
* The University of Memphis
|
||||
|
||||
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
|
||||
* Ashlesh Gawande <agawande@memphis.edu>
|
||||
* Minsheng Zhang <mzhang4@memphis.edu>
|
||||
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
|
||||
* Minsheng Zhang <https://www.linkedin.com/in/minsheng-zhang-032023a1>
|
||||
* Syed Obaid Amin <http://obaidamin.weebly.com/>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
* Muktadir R Chowdhury <mrchwdhr@memphis.edu>
|
||||
* Nicholas Gordon <nmgordon@memphis.edu>
|
||||
* Laqin Fan <lfan1@memphis.edu>
|
||||
* Damian Coomes <dmcoomes@memphis.edu>
|
||||
* Saurab Dulal <sdulal@memphis.edu>
|
||||
|
||||
* University of California, Los Angeles
|
||||
|
||||
* Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
|
||||
* Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
* Spyridon Mastorakis <http://cs.ucla.edu/~mastorakis/>
|
||||
* Jiewen Tan <alanwake@ucla.edu>
|
||||
* Jiewen Tan <https://www.linkedin.com/in/jiewentan>
|
||||
|
||||
* University of Arizona
|
||||
|
||||
* Junxiao Shi <https://www.cs.arizona.edu/people/shijunxiao/>
|
||||
* Junxiao Shi <https://www.linkedin.com/in/shijunxiao>
|
||||
|
||||
* University Pierre & Marie Curie, Sorbonne University
|
||||
|
||||
* Davide Pesavento <https://www.linkedin.com/in/davidepesavento>
|
||||
|
||||
## Queries about NLSR
|
||||
|
||||
|
||||
+4
-24
@@ -1,8 +1,7 @@
|
||||
NLSR LICENSE
|
||||
============
|
||||
|
||||
NLSR is released under the GPL with the additional exemption that
|
||||
compiling, linking, and/or using OpenSSL is allowed.
|
||||
NLSR is released under the GPL.
|
||||
|
||||
NLSR relies on third-party software and libraries, licensed under the following
|
||||
licenses:
|
||||
@@ -10,33 +9,14 @@ licenses:
|
||||
- Boost libraries are licensed under the conditions of
|
||||
[Boost Software License 1.0](http://www.boost.org/users/license.html)
|
||||
|
||||
- CryptoPP library is licensed under the conditions of
|
||||
[Boost Software License 1.0](http://www.boost.org/users/license.html)
|
||||
|
||||
- log4cxx is licensed under the conditions of
|
||||
[Apache License, Version 2.0](https://logging.apache.org/log4cxx/license.html)
|
||||
|
||||
- ndn-cxx is licensed under the conditions of
|
||||
[LGPL 3.0](https://github.com/named-data/ndn-cxx/blob/master/COPYING.md)
|
||||
|
||||
- protobuf is licensed under the conditions of
|
||||
[BSD license](https://github.com/google/protobuf/blob/master/LICENSE)
|
||||
|
||||
- SQLite is in [public domain](http://www.sqlite.org/copyright.html)
|
||||
- ChronoSync is licensed under the conditions of
|
||||
[GPL 3.0](https://github.com/named-data/ChronoSync/blob/master/COPYING.md)
|
||||
|
||||
- waf build system is licensed under the conditions of
|
||||
[BSD license](https://github.com/named-data/ndn-cxx/blob/master/waf)
|
||||
|
||||
NLSR also relies on third-party libraries with non-GPL compatible licenses.
|
||||
These libraries fall into the category of "System Libraries" under GPL
|
||||
license definitions and are used in accordance with the GPL license exception
|
||||
for "System Libraries":
|
||||
|
||||
- OpenSSL is licensed under an
|
||||
[Apache-style licence](http://www.openssl.org/source/license.html)
|
||||
|
||||
- (OS X platform only) OS X Security Framework is licensed under
|
||||
[Apple Public Source License](http://www.opensource.apple.com/license/apsl/)
|
||||
[BSD license](https://github.com/named-data/NLSR/blob/master/waf)
|
||||
|
||||
The GPL license is provided below in this file.
|
||||
For more information, see http://www.gnu.org/licenses/
|
||||
|
||||
+6
-3
@@ -28,10 +28,13 @@ Include the following header in all `.hpp` and `.cpp` files:
|
||||
|
||||
If you are affiliated with an NSF-supported NDN project institution,
|
||||
please use the [NDN Team License Boilerplate]
|
||||
(http://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
|
||||
(https://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
|
||||
|
||||
Recommendations
|
||||
---------------
|
||||
|
||||
NSLR code is subject to the code style, defined here:
|
||||
http://redmine.named-data.net/projects/nfd/wiki/CodeStyle
|
||||
NLSR code is subject to the code style, defined here:
|
||||
https://redmine.named-data.net/projects/nfd/wiki/CodeStyle
|
||||
|
||||
NLSR Developer's guide can be found here:
|
||||
https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf
|
||||
@@ -4,6 +4,9 @@ NLSR - Named Data Link State Routing Protocol
|
||||
For complete documentation and more extensive information,
|
||||
please visit the [NLSR homepage](http://named-data.net/doc/NLSR/current/).
|
||||
|
||||
If you are new to the NDN community of software generally, read the
|
||||
[Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md).
|
||||
|
||||
## Overview
|
||||
|
||||
NLSR is a routing protocol in NDN that populates NDN's Routing Information Base. NLSR
|
||||
@@ -13,10 +16,10 @@ NLSR is an open and free software package licensed under the GPL 3.0 license and
|
||||
Internet users and developers. For more information about the licensing details and
|
||||
limitations, refer to [COPYING.md](https://github.com/named-data/NLSR/blob/master/COPYING.md).
|
||||
|
||||
NLSR is developed by the members of the [NSF-sponsored NDN project team](http://named-data.net/project/participants/).
|
||||
NLSR is developed by the members of the [NSF-sponsored NDN project team](https://named-data.net/project/participants/).
|
||||
For more details, please refer to [AUTHORS.md](https://github.com/named-data/NLSR/blob/master/AUTHORS.md).
|
||||
Bug reports and feedback are highly appreciated and can be made through the
|
||||
[Redmine site](http://redmine.named-data.net/projects/nlsr).
|
||||
[Redmine site](https://redmine.named-data.net/projects/nlsr).
|
||||
|
||||
The main design goal of NLSR is to provide a routing protocol to populate NDN's FIB.
|
||||
NLSR calculates the routing table using link-state or hyperbolic routing and produces
|
||||
@@ -31,13 +34,18 @@ Source releases
|
||||
The source code and source-code installation instructions are always available at
|
||||
the following links:
|
||||
|
||||
- [Installation](http://named-data.net/doc/NLSR/current/INSTALL.html)
|
||||
- [Getting Started with NLSR](http://named-data.net/doc/NLSR/current/GETTING-STARTED.html)
|
||||
- [Installation](https://named-data.net/doc/NLSR/current/INSTALL.html)
|
||||
- [Getting Started with NLSR](https://named-data.net/doc/NLSR/current/GETTING-STARTED.html)
|
||||
- [GitHub NLSR repository](https://github.com/named-data/NLSR)
|
||||
|
||||
Additional information
|
||||
----------------------
|
||||
|
||||
- [NLSR Wiki](http://redmine.named-data.net/projects/nlsr/wiki/)
|
||||
- [Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md)
|
||||
- [NLSR Wiki](https://redmine.named-data.net/projects/nlsr/wiki/)
|
||||
- Feature requests and bug reports are welcome on our
|
||||
[NLSR on NDN Redmine](http://redmine.named-data.net/projects/nlsr)
|
||||
[NLSR on NDN Redmine](https://redmine.named-data.net/projects/nlsr)
|
||||
- [NLSR Mailing List Sign Up](https://listserv.memphis.edu/scripts/wa.exe?GETPW1)
|
||||
- [NLSR Mailing List](https://listserv.memphis.edu/scripts/wa.exe?SUBED1=NLSR-HELP-L&A=1)
|
||||
- [NLSR Mailing List Archives](https://listserv.memphis.edu/scripts/wa.exe?A0=NLSR-HELP-L)
|
||||
- [NLSR Developer's guide](https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf)
|
||||
@@ -14,6 +14,20 @@ Installation
|
||||
|
||||
:doc:`INSTALL`
|
||||
|
||||
|
||||
Important Notes About Configuration
|
||||
-----------------------------------
|
||||
|
||||
Since v0.4.0, NLSR no longer creates Faces for the neighbors that are
|
||||
specified in ``nlsr.conf``. Instead, it relies on the pre-existence of
|
||||
the Faces in NFD. NLSR will obtain this information from NFD, and
|
||||
configure its neighbors using this information.
|
||||
|
||||
For people who were relying on NLSR to automagically configure their
|
||||
networks, this must now be done with ``nfdc``. Its documentation can
|
||||
be found `here
|
||||
<https://named-data.net/doc/NFD/current/manpages/nfdc.html>`_
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
@@ -39,8 +53,26 @@ You can also run ``nlsr -f`` with the absolute path of the configuration file:
|
||||
|
||||
nlsr -f /usr/local/etc/ndn/nlsr.conf
|
||||
|
||||
To run NLSR as daemon, use the ``-d`` flag:
|
||||
Logging
|
||||
-------
|
||||
|
||||
NLSR uses the ndn-cxx logging facility. All levels listed below the selected log-level
|
||||
value are enabled.
|
||||
|
||||
::
|
||||
|
||||
nlsr -d
|
||||
Valid values:
|
||||
|
||||
TRACE trace messages (most verbose)
|
||||
DEBUG debugging messages
|
||||
INFO informational messages
|
||||
WARN warning messages
|
||||
ERROR error messages
|
||||
FATAL fatal (will be logged unconditionally)
|
||||
|
||||
To obtain logs for NLSR, set the NDN_LOG environment variable with the correct prefix and
|
||||
log-level settings. For example, running the command `export NDN_LOG=nlsr.*=TRACE && nlsr`
|
||||
will display all log messages in NLSR with a DEBUG level or below. If the user is presented
|
||||
with an error message `User does not have read and write permission on the directory` it can
|
||||
be circumvented by running the application with sudo: `sudo env NDN_LOG=nlsr.*=DEBUG nlsr`.
|
||||
Use `man ndn-log` for more detailed instructions.
|
||||
+2
-38
@@ -12,47 +12,11 @@ Prerequisites
|
||||
Refer to `Getting started with NFD <http://named-data.net/doc/NFD/current/INSTALL.html>`_
|
||||
for detailed installation and running instruction.
|
||||
|
||||
- log4cxx library
|
||||
|
||||
On Ubuntu Linux:
|
||||
- ChronoSync library
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install liblog4cxx10-dev
|
||||
|
||||
On OS X with MacPorts:
|
||||
|
||||
::
|
||||
|
||||
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
|
||||
https://github.com/named-data/ChronoSync#build
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
+3
-241
@@ -1,242 +1,4 @@
|
||||
Release Notes
|
||||
=============
|
||||
NLSR Release Notes
|
||||
==================
|
||||
|
||||
NLSR version 0.3.2 (changes since version 0.3.1)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: March 15, 2017
|
||||
|
||||
**Changes**
|
||||
|
||||
- NLSR constructor now accept a KeyChain argument. (:issue:`3742`)
|
||||
|
||||
- Fix security rule for /localhop LSA prefix (:issue:`3899`)
|
||||
|
||||
- Use ndn::nfd::ROUTE_ORIGIN_NLSR instead of a magic number. (:issue:`3903`)
|
||||
|
||||
- Handle "Face Already Exists" error (error code 409) in NFD. (:issue:`3976`)
|
||||
|
||||
- Enable NLSR to register localhost prefix with dispatcher before top-level prefix. (:issue:`3938`)
|
||||
|
||||
- Don't use ndn aliases provided by ndn-cxx/common.hpp. (:issue:`3983`)
|
||||
|
||||
- Remove use of deprecated code. (:issue:`3988`)
|
||||
|
||||
NLSR version 0.3.1 (changes since version 0.3.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: January 22, 2017
|
||||
|
||||
**Changes**
|
||||
|
||||
- **breaking change** Sync uses /localhop component in prefix to reduce duplicate NACKs (:issue:`3627`)
|
||||
|
||||
- **breaking change** LSA uses /localhop component in prefix to reduce duplicate NACKs (:issue:`3899`)
|
||||
|
||||
**Code Changes**:
|
||||
|
||||
- Fib and FaceMap use std::map instead of std::list (:issue:`2781`)
|
||||
|
||||
- NamePrefixTableEntries store RoutingTableEntries using a pointer (:issue:`2863`)
|
||||
|
||||
- Namespace closing comments are now consistent with ndn-cxx guidelines (:issue:`3735`)
|
||||
|
||||
- Update copyright date across all files (:issue:`3736`, `3909`, `3923`)
|
||||
|
||||
- Improve formatting of FaceMap and FaceMapEntry (:issue:`3737`)
|
||||
|
||||
- Sort NextHops on NexthopList insertion (:issue:`2721`)
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- HR now recalculates paths after status change of a neighbor (:issue:`3874`)
|
||||
|
||||
- NLSR no longer sets strategies multiple times (:issue:`3743`)
|
||||
|
||||
- NLSR should enable use of ndn-cxx dispatcher (:issue:`3930`)
|
||||
|
||||
- Fix typos in the sample configuration file (:issue:`3113`)
|
||||
|
||||
NLSR version 0.3.0 (changes since version 0.2.2)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: August 1, 2016
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Updated validation checker for LSA rule in the configuration file (:issue:`2965`)
|
||||
|
||||
- Do not advertise Adjacency LSAs when hyperbolic routing is enabled (:issue:`2402`)
|
||||
|
||||
- Do not distribute coordinate LSAs when using link-state routing. (:issue:`3661`)
|
||||
|
||||
- LSAs should be segmented before they are published (:issue:`2965`)
|
||||
|
||||
- Don't use DummyClientFace::sentDatas (:issue:`3383`)
|
||||
|
||||
- Remove disabled security files (:issue:`2960`)
|
||||
|
||||
- Lsa type should be argument for base class LSA constructor (:issue:`2788`)
|
||||
|
||||
- Use ndn-cxx/DummyClientFace (:issue:`2637`)
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- Unit tests cases are installed with `./waf install` (:issue:`3359`)
|
||||
|
||||
|
||||
NLSR version 0.2.2 (changes since version 0.2.1)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: January 5, 2016
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Adapt code to changes in NFD/ndn-cxx version 0.4.0 release
|
||||
|
||||
NLSR version 0.2.1 (changes since version 0.2.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: June 30, 2015
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Using a configuration file without ``prefix-update-validator`` disables runtime advertise/withdraw instead of exiting (:issue:`2814`)
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- Prevent incomplete removal of NPT entry (:issue:`2785`)
|
||||
|
||||
- Correct bidirectional links with differing costs (:issue:`2801`)
|
||||
|
||||
- Fix non-incrementing Adjacency number in AdjLsa::writeLog (:issue:`2594`)
|
||||
|
||||
- Remove FaceDestroyEvent test's reliance on nlsrSeqNo.txt (:issue:`2881`)
|
||||
|
||||
- Test ACTIVE/INACTIVE Adjacencies in LSA construction (:issue:`2735`)
|
||||
|
||||
NLSR version 0.2.0 (changes since version 0.1.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: April 30, 2015
|
||||
|
||||
**Build**:
|
||||
|
||||
- The code now requires C++11. The minimum supported gcc version is 4.6, as earlier versions do not have proper support for C++11 features. (:issue:`1930`)
|
||||
|
||||
- Require OpenSSL (:issue:`2375`)
|
||||
|
||||
**New features**:
|
||||
|
||||
- Add nlsrc command-line tool (:issue:`1834`)
|
||||
|
||||
- Advertise/Withdraw name prefixes at runtime (:issue:`1834`)
|
||||
|
||||
- Assign zero cost to hyperbolic direct neighbors (:issue:`1975`)
|
||||
|
||||
- Only hyperbolic costs are adjusted before registering (:issue:`1974`)
|
||||
|
||||
- Add ability to specify different logging levels (:issue:`1935`)
|
||||
|
||||
- Add LSDB dataset publishers (:issue:`2280`)
|
||||
|
||||
- Add LSDB dataset tlv abstractions (:issue:`2280`)
|
||||
|
||||
- Allow zero cost neighbors for hyperbolic routing table calculation (:issue:`1982`)
|
||||
|
||||
- Faces are now created with canonical Face URI (:issue:`1911`)
|
||||
|
||||
- Add configurable router event intervals (:issue:`2071`)
|
||||
|
||||
- Add router-dead-interval configuration setting (:issue:`1878`)
|
||||
|
||||
- Add log formatting specified by log4cxx configuration file (:issue:`1950`)
|
||||
|
||||
- Face URIs in configuration file are checked for validity on load (:issue:`2070`)
|
||||
|
||||
- Configuration variables with default values are now optional (:issue:`1949`)
|
||||
|
||||
- Recalculate routing table after face destroy event (:issue:`2635`)
|
||||
|
||||
- Add Travis-CI build script
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Change adjacency status from uint32_t to enum (:issue:`1946`)
|
||||
|
||||
- Remove scheduler from NLSR class (:issue:`1981`)
|
||||
|
||||
- Change hyperbolic cost adjustment factor from 100 to 1000 (:issue:`1974`)
|
||||
|
||||
- Remove use of outdated namespace ``ndn::Tlv`` (:issue:`2079`)
|
||||
|
||||
- Remove use of deprecated ``ndn::nfd::Controller(Face&)`` constructor (:issue:`2133`)
|
||||
|
||||
- Routing update publishing is abstracted to SyncLogicHandler (:issue:`2289`)
|
||||
|
||||
- Make ConfParameter variable types consistent with min and max values (:issue:`2084`)
|
||||
|
||||
- Replace LSA string literals with constants (:issue:`2310`)
|
||||
|
||||
- Subscribe to FaceMonitor notifications using connect (:issue:`2350`)
|
||||
|
||||
- Log exceptions thrown in event loop
|
||||
|
||||
- Change ``ndn::ptr_lib::shared_ptr`` to ``std::shared_ptr`` (:issue:`2110`)
|
||||
|
||||
- Avoid deprecated ``ndn::Name::set`` method (:issue:`2505`)
|
||||
|
||||
- Update waf to version 1.8.8-dev
|
||||
|
||||
- Add sorting tiebreaker to NexthopList (:issue:`2715`)
|
||||
|
||||
- Update Jenkins-CI build scripts
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- Fix python3 build error (:issue:`1956`)
|
||||
|
||||
- Fix typos in nlsr.conf security section (:issue:`1985`)
|
||||
|
||||
- Stop SyncLogicHandler from fetching a router’s own LSAs (:issue:`2005`)
|
||||
|
||||
- Fix Name LSA comparison which could cause incorrect advertised names to be removed (:issue:`2029`)
|
||||
|
||||
- Fix issue where more faces than max-faces-per-prefix could be applied to a prefix (:issue:`2018`)
|
||||
|
||||
- Stop LSDB from retrieving and out of date LSA when a new one is detected (:issue:`1987`)
|
||||
|
||||
- Correct mistakes in documentation
|
||||
|
||||
- Correct bitmask used to copy Name LSA sequence number (:issue:`2323`)
|
||||
|
||||
NLSR version 0.1.0 (initial release)
|
||||
++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: August 25, 2014
|
||||
|
||||
The main design goal of NLSR is to provide a routing protocol to populate `NFD's
|
||||
<http://named-data.net/doc/NFD/current/>`_ RIB. NLSR calculates the routing table using
|
||||
link-state or hyperbolic routing and produces multiple faces for each reachable name
|
||||
prefix in a single authoritative domain.
|
||||
|
||||
**Included features**:
|
||||
|
||||
- Advertise availability of content through the configured router
|
||||
|
||||
- Use `ChronoSync <https://github.com/named-data/ChronoSync>`_ to synchronize routers' LSA sequence numbers and Interest/Data to retrieve LSAs
|
||||
|
||||
- Produce a list of ranked forwarding options for each name prefix to facilitate NDN's adaptive forwarding strategies
|
||||
|
||||
- Configure maximum number of faces per prefix in NFD’s RIB
|
||||
|
||||
- Set up NFD tunnels to neighbors automatically and maintain the tunnels to neighbors
|
||||
|
||||
- Provide two routing protocols:
|
||||
|
||||
+ Link State routing: calculate route cost based on link costs
|
||||
+ Hyperbolic routing: calculate route cost based on hyperbolic coordinates
|
||||
|
||||
- Use a hierarchical trust model for routing within a single administrative domain
|
||||
|
||||
- Keep NFD’s RIB updated on failure and recovery
|
||||
.. include:: release-notes-latest.rst
|
||||
+89
-24
@@ -42,9 +42,9 @@ Type the following in the terminal:
|
||||
|
||||
::
|
||||
|
||||
nfd-status -f
|
||||
nfd-status
|
||||
|
||||
If you see ``ERROR: error while connecting to the forwarder (No such file or directory)``,
|
||||
If you see ``error while connecting to the forwarder (No such file or directory)``,
|
||||
``nfd`` is not running. Follow the instructions in `Getting started with NFD
|
||||
<http://named-data.net/doc/NFD/current/INSTALL.html>`_ to run nfd.
|
||||
|
||||
@@ -83,11 +83,7 @@ configuration commands follows:
|
||||
; InterestLifetime (in seconds) for LSA fetching
|
||||
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
|
||||
|
||||
; log-level is to set the levels of log for NLSR
|
||||
log-level INFO ; default value INFO, valid value DEBUG, INFO
|
||||
log-dir /var/log/nlsr/
|
||||
seq-dir /var/lib/nlsr/
|
||||
; log4cxx-conf /path/to/log4cxx-conf
|
||||
}
|
||||
|
||||
; the neighbors section contains the configuration for router's neighbors and hello's behavior
|
||||
@@ -106,11 +102,12 @@ configuration commands follows:
|
||||
hello-interval 60 ; interest sending interval in seconds. Default value 60
|
||||
; valid values 30-90
|
||||
|
||||
; adj-lsa-build-interval is the time to wait in seconds after an Adjacency LSA build is scheduled
|
||||
; before actually building the Adjacency LSA
|
||||
; adj-lsa-build-interval is the time to wait in seconds after an Adjacency LSA
|
||||
; build is scheduled before actually building the Adjacency LSA
|
||||
|
||||
adj-lsa-build-interval 5 ; default value 5. Valid values 0-5. It is recommended that
|
||||
; adj-lsa-build-interval have a lower value than routing-calc-interval
|
||||
; adj-lsa-build-interval have a lower value than
|
||||
; routing-calc-interval
|
||||
|
||||
; first-hello-interval is the time to wait in seconds before sending the first Hello Interest
|
||||
|
||||
@@ -121,8 +118,8 @@ configuration commands follows:
|
||||
|
||||
neighbor
|
||||
{
|
||||
name /ndn/edu/arizona/%C1.Router/router3 ; name prefix of the neighbor router consists
|
||||
; of network, site-name and router-name
|
||||
name /ndn/edu/arizona/%C1.Router/router3 ; name prefix of the neighbor router consists
|
||||
; of network, site-name and router-name
|
||||
|
||||
face-uri udp4://router3.arizona.edu ; face uri of the face connected to the neighbor
|
||||
link-cost 25 ; cost of the connecting link to neighbor
|
||||
@@ -130,7 +127,7 @@ configuration commands follows:
|
||||
|
||||
neighbor
|
||||
{
|
||||
name /ndn/edu/colostate/%C1.Router/router2 ; name prefix of the neighbor router consists
|
||||
name /ndn/edu/colostate/%C1.Router/router2 ; name prefix of the neighbor router consists
|
||||
; of network, site-name and router-name
|
||||
|
||||
face-uri udp4://79.123.10.145 ; face uri of the face connected to the neighbor
|
||||
@@ -147,9 +144,9 @@ configuration commands follows:
|
||||
; commands in this section follows a strict order
|
||||
; the switch is used to set hyperbolic routing calculation in NLSR
|
||||
|
||||
state off ; default value 'off', set value 'on' to enable hyperbolic routing table
|
||||
; calculation which turns link state routing 'off'. set value to 'dry-run'
|
||||
; to test hyperbolic routing and compare with link state routing.
|
||||
state off ; default value 'off', set value 'on' to enable hyperbolic routing table
|
||||
; calculation which turns link state routing 'off'. set value to 'dry-run'
|
||||
; to test hyperbolic routing and compare with link state routing.
|
||||
|
||||
|
||||
radius 123.456 ; radius of the router in hyperbolic coordinate system
|
||||
@@ -164,8 +161,8 @@ configuration commands follows:
|
||||
; the max-faces-per-prefix is used to limit the number of faces for each name prefixes
|
||||
; by NLSR in ndn FIB
|
||||
|
||||
max-faces-per-prefix 3 ; default value 0. Valid value 0-60. By default (value 0) NLSR adds
|
||||
; all available faces for each reachable name prefixes in NDN FIB
|
||||
max-faces-per-prefix 3 ; default value 0. Valid value 0-60. By default (value 0) NLSR adds
|
||||
; all available faces for each reachable name prefixes in NDN FIB
|
||||
|
||||
}
|
||||
|
||||
@@ -182,10 +179,78 @@ configuration commands follows:
|
||||
prefix /ndn/news/memphis/politics/lutherking
|
||||
}
|
||||
|
||||
.. note::
|
||||
By default NLSR's sequence file directory is set to ``/var/lib/nlsr/``. User must create this
|
||||
directory before starting NLSR. Since this is a system directory, NLSR must either be executed
|
||||
as root, or NLSR can be run as user "nlsr" after configuring the filesystem to grant "nlsr"
|
||||
read and write permissions. If user lacks permissions, the following error will occur:
|
||||
|
||||
Security configuration is discussed in :doc:`SECURITY-CONFIG`, which will be also part
|
||||
of this configuration file
|
||||
::
|
||||
|
||||
User does not have read and write permission on the directory
|
||||
Error in configuration file processing! Exiting from NLSR
|
||||
|
||||
To avoid this, the directory can be set in a user-owned directory. For example:
|
||||
|
||||
::
|
||||
|
||||
general
|
||||
{
|
||||
...
|
||||
|
||||
seq-dir /home/username/nlsr/log ; path for sequence directory (Absolute path)
|
||||
|
||||
}
|
||||
...
|
||||
|
||||
The user will encounter errors such as the following if security is not configured:
|
||||
|
||||
::
|
||||
|
||||
Cannot read certificate from file: /home/username/NLSR/root.cert
|
||||
|
||||
To get rid of this and similar errors relating to security one has to configure security
|
||||
as described in :doc:`SECURITY-CONFIG`. Security can be disabled for testing purposes as follows:
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
trust-anchor
|
||||
{
|
||||
type any
|
||||
;file-name "root.cert"
|
||||
}
|
||||
...
|
||||
trust-anchor
|
||||
{
|
||||
type any
|
||||
;file-name "site.cert"
|
||||
}
|
||||
; cert-to-publish "root.cert"
|
||||
; cert-to-publish "router.cert"
|
||||
; cert-to-publish "site.cert"
|
||||
; cert-to-publish "router.cert"
|
||||
|
||||
Or by simply replacing the whole security section with:
|
||||
|
||||
::
|
||||
|
||||
security
|
||||
{
|
||||
validator
|
||||
{
|
||||
trust-anchor
|
||||
{
|
||||
type any
|
||||
}
|
||||
}
|
||||
prefix-update-validator
|
||||
{
|
||||
trust-anchor
|
||||
{
|
||||
type any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Step 4: Running NLSR on /ndn/memphis.edu/router1
|
||||
-------------------------------------------------
|
||||
@@ -207,9 +272,9 @@ The same process needs to be followed for ``/ndn/arizona.edu/router3`` and
|
||||
Expected Output
|
||||
----------------
|
||||
|
||||
Assuming that all three routers are configured correctly and routing has converged, ``nfd-status`` in
|
||||
``/ndn/edu/colostate/%C1.Router/router2`` will have the following entries for the name
|
||||
advertised by ``/ndn/edu/memphis/%C1.Router/router1``:
|
||||
Assuming that all three routers are configured correctly and routing has converged,
|
||||
``nfd-status`` in ``/ndn/edu/colostate/%C1.Router/router2`` will have the following (or similar)
|
||||
entries for the name advertised by ``/ndn/edu/memphis/%C1.Router/router1``:
|
||||
|
||||
RIB:
|
||||
|
||||
@@ -219,7 +284,7 @@ RIB:
|
||||
/ndn/memphis/sports/basketball/grizzlies route={faceid=17 (origin=128 cost=25 ChildInherit), faceid=7 (origin=128 cost=58 ChildInherit)}
|
||||
/ndn/news/memphis/politics/lutherking route={faceid=17 (origin=128 cost=25 ChildInherit, faceid=7 (origin=128 cost=58 ChildInherit)}
|
||||
|
||||
This output can be seen by typing ``nfd-status -r`` in the terminal. Please refer to the
|
||||
This output can be seen by typing ``nfdc route list`` in the terminal. Please refer to the
|
||||
network figure for face IDs.
|
||||
|
||||
.. _hyperbolic routing table calculation: http://arxiv.org/abs/0805.1266
|
||||
@@ -20,7 +20,7 @@ The trust model of NLSR is semi-hierarchical. An example certificate signing hie
|
||||
router1 router2 router3 router4 router5 router6 router7
|
||||
| | | | | | |
|
||||
+ + + + + + +
|
||||
NLSR NSLR NSLR NSLR NSLR NSLR NSLR
|
||||
NLSR NLSR NLSR NLSR NLSR NLSR NLSR
|
||||
|
||||
Each entity's name and corresponding certificate name follow the
|
||||
convention below:
|
||||
@@ -28,15 +28,20 @@ convention below:
|
||||
======== ===================================================== ================================= ===============================================
|
||||
Entity Identity Name Example Certificate Name Example
|
||||
-------- ----------------------------------------------------- --------------------------------- -----------------------------------------------
|
||||
root /\<network\> /ndn /ndn/KEY/ksk-1/ID-CERT/%01
|
||||
site /\<network\>/\<site\> /ndn/edu/ucla /ndn/edu/ucla/KEY/ksk-2/ID-CERT/%01
|
||||
operator /\<network\>/\<site\>/%C1.Operator/\<operator-name\> /ndn/edu/ucla/%C1.Operator/op1 /ndn/edu/ucla/%C1.Operator/op1/KEY/ksk-3/ID-CERT/%01
|
||||
router /\<network\>/\<site\>/%C1.Router/\<router-name\> /ndn/edu/ucla/%C1.Router/rt1 /ndn/edu/ucla/%C1.Router/rt1/KEY/ksk-4/ID-CERT/%01
|
||||
NLSR /\<network\>/\<site\>/%C1.Router/\<router-name\>/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR/KEY/ksk-5/ID-CERT/%01
|
||||
root /\<network\> /ndn /ndn/KEY/1/%00/%01
|
||||
site /\<network\>/\<site\> /ndn/edu/ucla /ndn/edu/ucla/KEY/2/%00/%01
|
||||
operator /\<network\>/\<site\>/%C1.Operator/\<operator-name\> /ndn/edu/ucla/%C1.Operator/op1 /ndn/edu/ucla/%C1.Operator/op1/KEY/3/%00/%01
|
||||
router /\<network\>/\<site\>/%C1.Router/\<router-name\> /ndn/edu/ucla/%C1.Router/rt1 /ndn/edu/ucla/%C1.Router/rt1/KEY/4/%00/%01
|
||||
NLSR /\<network\>/\<site\>/%C1.Router/\<router-name\>/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR/KEY/5/%00/%01
|
||||
======== ===================================================== ================================= ===============================================
|
||||
|
||||
Users should create keys according to the naming and signing hierarchies above.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Detailed information about key setup is given in NLSR Developer's Guide.
|
||||
|
||||
Certificate Publishing
|
||||
----------------------
|
||||
|
||||
|
||||
+4
-3
@@ -12,6 +12,7 @@
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
import os
|
||||
|
||||
@@ -30,7 +31,7 @@ sys.path.insert(0, os.path.abspath('.'))
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.todo',
|
||||
'redmine_issue',
|
||||
'redmine_issue'
|
||||
]
|
||||
|
||||
def addExtensionIfExists(extension):
|
||||
@@ -60,7 +61,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'NLSR - Named Data Link State Routing Protocol'
|
||||
copyright = u'2014-2015, Named Data Networking Project'
|
||||
copyright = u'2014-{}, Named Data Networking Project'.format(datetime.date.today().year)
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@@ -251,4 +252,4 @@ if os.getenv('GOOGLE_ANALYTICS', None):
|
||||
googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
|
||||
googleanalytics_enabled = True
|
||||
|
||||
redmine_project_url = "http://redmine.named-data.net/"
|
||||
redmine_project_url = "https://redmine.named-data.net/"
|
||||
+26
-5
@@ -3,7 +3,7 @@ NLSR - Named Data Link State Routing Protocol
|
||||
|
||||
NLSR is a routing protocol in NDN that populates NDN's Routing Information Base. NLSR will
|
||||
continue to evolve alongside the Named Data Networking `protocol
|
||||
<http://named-data.net/doc/ndn-tlv/>`_.
|
||||
<https://named-data.net/doc/ndn-tlv/>`_.
|
||||
|
||||
NLSR is an open and free software package licensed under the GPL 3.0 license and free to
|
||||
all Internet users and developers. For more information about the licensing details and
|
||||
@@ -11,7 +11,7 @@ limitations, refer to `COPYING.md
|
||||
<https://github.com/named-data/NLSR/blob/master/COPYING.md>`_.
|
||||
|
||||
NLSR is developed by the members of the `NSF-sponsored NDN project team
|
||||
<http://named-data.net/project/participants/>`_. For more details, please refer to
|
||||
<https://named-data.net/project/participants/>`_. For more details, please refer to
|
||||
`AUTHORS.md <https://github.com/named-data/NLSR/blob/master/AUTHORS.md>`_. Bug reports and
|
||||
feedback are highly appreciated and can be made through the `NLSR Wiki`_.
|
||||
|
||||
@@ -29,11 +29,12 @@ NLSR Documentation
|
||||
:hidden:
|
||||
:maxdepth: 3
|
||||
|
||||
RELEASE-NOTES
|
||||
GETTING-STARTED
|
||||
INSTALL
|
||||
ROUTER-CONFIG
|
||||
SECURITY-CONFIG
|
||||
RELEASE-NOTES
|
||||
releases
|
||||
manpages
|
||||
|
||||
- :doc:`GETTING-STARTED`
|
||||
@@ -41,6 +42,7 @@ NLSR Documentation
|
||||
- :doc:`ROUTER-CONFIG`
|
||||
- :doc:`SECURITY-CONFIG`
|
||||
- :doc:`RELEASE-NOTES`
|
||||
- :doc:`releases`
|
||||
- :doc:`manpages`
|
||||
|
||||
Downloading
|
||||
@@ -48,14 +50,33 @@ Downloading
|
||||
|
||||
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`_
|
||||
|
||||
NLSR mailing list
|
||||
-----------------
|
||||
|
||||
- `NLSR Mailing List`_
|
||||
|
||||
- `NLSR Mailing List Archives`_
|
||||
|
||||
`Sign up`_ is needed to post to the list or access the archives.
|
||||
|
||||
Additional information
|
||||
----------------------
|
||||
|
||||
- `NLSR Wiki`_
|
||||
|
||||
- `NLSR Redmine`_
|
||||
Feature requests and bug reports
|
||||
|
||||
- `NLSR Paper`_
|
||||
Detailed explanation of the NLSR design
|
||||
|
||||
- `NLSR Developer's Guide`_
|
||||
For NLSR Development
|
||||
|
||||
.. _NLSR Wiki: http://redmine.named-data.net/projects/nlsr
|
||||
.. _NLSR Paper: http://www.cs.memphis.edu/~lanwang/paper/nlsr-final.pdf
|
||||
.. _NLSR Wiki: https://redmine.named-data.net/projects/nlsr/wiki
|
||||
.. _NLSR Paper: https://named-data.net/wp-content/uploads/2016/01/ndn-0037-1-nlsr.pdf
|
||||
.. _NLSR Mailing List: https://listserv.memphis.edu/scripts/wa.exe?SUBED1=NLSR-HELP-L&A=1
|
||||
.. _NLSR Mailing List Archives: https://listserv.memphis.edu/scripts/wa.exe?A0=NLSR-HELP-L
|
||||
.. _NLSR Developer's Guide: https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf
|
||||
.. _Sign up: https://listserv.memphis.edu/scripts/wa.exe?GETPW1
|
||||
.. _NLSR Redmine: https://redmine.named-data.net/projects/nlsr
|
||||
+2
-12
@@ -12,16 +12,12 @@ Usage
|
||||
Description
|
||||
-----------
|
||||
|
||||
``nlsr`` is a daemon that implements routing protocol in NDN to populates NDN's Routing
|
||||
``nlsr`` is a process that implements routing protocol in NDN to populate NDN's Routing
|
||||
Information Base.
|
||||
|
||||
Options:
|
||||
--------
|
||||
|
||||
|
||||
``-d``
|
||||
Run in daemon mode
|
||||
|
||||
``-f <FILE>``
|
||||
Specify configuration file name (default: ``./nlsr.conf``)
|
||||
|
||||
@@ -34,14 +30,8 @@ Options:
|
||||
Examples
|
||||
--------
|
||||
|
||||
To run NLSR daemon and use a configuration file from the ``/path/to`` directory.
|
||||
To run NLSR and use a configuration file from the ``/path/to`` directory.
|
||||
|
||||
::
|
||||
|
||||
nlsr -f /path/to/nlsr.conf
|
||||
|
||||
To run NLSR as daemon, use the ``-d`` flag:
|
||||
|
||||
::
|
||||
|
||||
nlsr -d
|
||||
+20
-1
@@ -26,9 +26,15 @@ Options
|
||||
|
||||
``COMMAND``
|
||||
|
||||
``status``
|
||||
``lsdb``
|
||||
Retrieve LSDB status information
|
||||
|
||||
``routing``
|
||||
Retrieve routing table status information
|
||||
|
||||
``status``
|
||||
Retrieve LSDB status and routing table status information
|
||||
|
||||
``advertise``
|
||||
Add a Name prefix to be advertised by NLSR
|
||||
|
||||
@@ -45,6 +51,19 @@ Options
|
||||
``name``
|
||||
The Name prefix to be withdrawn
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
When security is enabled, NLSR will not be allowed to successfully
|
||||
advertise/withdraw names without first setting a default identity of operator.
|
||||
If default identity is not set as operator, the user will be presented with the
|
||||
error message: “Name prefix update error (code: 403)”. To remedy this
|
||||
issue, use command 'ndn-sec-default'.
|
||||
|
||||
Example:
|
||||
|
||||
ndnsec-set-default /ndn/a-site/%C1.Operator/op
|
||||
|
||||
Exit Status
|
||||
-----------
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ $mathjax
|
||||
|
||||
<!--top menu-->
|
||||
<div class="nine columns" id="menu_container" >
|
||||
<h1><a href="http://named-data.net/doc/NFD/$projectnumber/">$projectname $projectnumber documentation</a></h1>
|
||||
<h1><a href="http://named-data.net/doc/NLSR/$projectnumber/">$projectname $projectnumber documentation</a></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--header container end-->
|
||||
|
||||
@@ -50,8 +50,8 @@ def make_link_node(rawtext, app, type, slug, options):
|
||||
base = app.config.redmine_project_url
|
||||
if not base:
|
||||
raise AttributeError
|
||||
except AttributeError, err:
|
||||
raise ValueError('redmine_project_url configuration value is not set (%s)' % str(err))
|
||||
except AttributeError:
|
||||
raise ValueError('redmine_project_url configuration value is not set')
|
||||
#
|
||||
slash = '/' if base[-1] != '/' else ''
|
||||
ref = base + slash + type + '/' + slug + '/'
|
||||
@@ -67,4 +67,4 @@ def setup(app):
|
||||
"""
|
||||
app.add_role('issue', redmine_role)
|
||||
app.add_config_value('redmine_project_url', None, 'env')
|
||||
return
|
||||
return
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
release-notes/release-notes-0.4.0.rst
|
||||
@@ -0,0 +1,30 @@
|
||||
NLSR version 0.1.0 (initial release)
|
||||
++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: August 25, 2014
|
||||
|
||||
The main design goal of NLSR is to provide a routing protocol to populate `NFD's
|
||||
<http://named-data.net/doc/NFD/current/>`_ RIB. NLSR calculates the routing table using
|
||||
link-state or hyperbolic routing and produces multiple faces for each reachable name
|
||||
prefix in a single authoritative domain.
|
||||
|
||||
**Included features**:
|
||||
|
||||
- Advertise availability of content through the configured router
|
||||
|
||||
- Use `ChronoSync <https://github.com/named-data/ChronoSync>`_ to synchronize routers' LSA sequence numbers and Interest/Data to retrieve LSAs
|
||||
|
||||
- Produce a list of ranked forwarding options for each name prefix to facilitate NDN's adaptive forwarding strategies
|
||||
|
||||
- Configure maximum number of faces per prefix in NFD’s RIB
|
||||
|
||||
- Set up NFD tunnels to neighbors automatically and maintain the tunnels to neighbors
|
||||
|
||||
- Provide two routing protocols:
|
||||
|
||||
+ Link State routing: calculate route cost based on link costs
|
||||
+ Hyperbolic routing: calculate route cost based on hyperbolic coordinates
|
||||
|
||||
- Use a hierarchical trust model for routing within a single administrative domain
|
||||
|
||||
- Keep NFD’s RIB updated on failure and recovery
|
||||
@@ -0,0 +1,94 @@
|
||||
NLSR version 0.2.0 (changes since version 0.1.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: April 30, 2015
|
||||
|
||||
**Build**:
|
||||
|
||||
- The code now requires C++11. The minimum supported gcc version is 4.6, as earlier versions do not have proper support for C++11 features. (:issue:`1930`)
|
||||
|
||||
- Require OpenSSL (:issue:`2375`)
|
||||
|
||||
**New features**:
|
||||
|
||||
- Add nlsrc command-line tool (:issue:`1834`)
|
||||
|
||||
- Advertise/Withdraw name prefixes at runtime (:issue:`1834`)
|
||||
|
||||
- Assign zero cost to hyperbolic direct neighbors (:issue:`1975`)
|
||||
|
||||
- Only hyperbolic costs are adjusted before registering (:issue:`1974`)
|
||||
|
||||
- Add ability to specify different logging levels (:issue:`1935`)
|
||||
|
||||
- Add LSDB dataset publishers (:issue:`2280`)
|
||||
|
||||
- Add LSDB dataset tlv abstractions (:issue:`2280`)
|
||||
|
||||
- Allow zero cost neighbors for hyperbolic routing table calculation (:issue:`1982`)
|
||||
|
||||
- Faces are now created with canonical Face URI (:issue:`1911`)
|
||||
|
||||
- Add configurable router event intervals (:issue:`2071`)
|
||||
|
||||
- Add router-dead-interval configuration setting (:issue:`1878`)
|
||||
|
||||
- Add log formatting specified by log4cxx configuration file (:issue:`1950`)
|
||||
|
||||
- Face URIs in configuration file are checked for validity on load (:issue:`2070`)
|
||||
|
||||
- Configuration variables with default values are now optional (:issue:`1949`)
|
||||
|
||||
- Recalculate routing table after face destroy event (:issue:`2635`)
|
||||
|
||||
- Add Travis-CI build script
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Change adjacency status from uint32_t to enum (:issue:`1946`)
|
||||
|
||||
- Remove scheduler from NLSR class (:issue:`1981`)
|
||||
|
||||
- Change hyperbolic cost adjustment factor from 100 to 1000 (:issue:`1974`)
|
||||
|
||||
- Remove use of outdated namespace ``ndn::Tlv`` (:issue:`2079`)
|
||||
|
||||
- Remove use of deprecated ``ndn::nfd::Controller(Face&)`` constructor (:issue:`2133`)
|
||||
|
||||
- Routing update publishing is abstracted to SyncLogicHandler (:issue:`2289`)
|
||||
|
||||
- Make ConfParameter variable types consistent with min and max values (:issue:`2084`)
|
||||
|
||||
- Replace LSA string literals with constants (:issue:`2310`)
|
||||
|
||||
- Subscribe to FaceMonitor notifications using connect (:issue:`2350`)
|
||||
|
||||
- Log exceptions thrown in event loop
|
||||
|
||||
- Change ``ndn::ptr_lib::shared_ptr`` to ``std::shared_ptr`` (:issue:`2110`)
|
||||
|
||||
- Avoid deprecated ``ndn::Name::set`` method (:issue:`2505`)
|
||||
|
||||
- Update waf to version 1.8.8-dev
|
||||
|
||||
- Add sorting tiebreaker to NexthopList (:issue:`2715`)
|
||||
|
||||
- Update Jenkins-CI build scripts
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- Fix python3 build error (:issue:`1956`)
|
||||
|
||||
- Fix typos in nlsr.conf security section (:issue:`1985`)
|
||||
|
||||
- Stop SyncLogicHandler from fetching a router’s own LSAs (:issue:`2005`)
|
||||
|
||||
- Fix Name LSA comparison which could cause incorrect advertised names to be removed (:issue:`2029`)
|
||||
|
||||
- Fix issue where more faces than max-faces-per-prefix could be applied to a prefix (:issue:`2018`)
|
||||
|
||||
- Stop LSDB from retrieving and out of date LSA when a new one is detected (:issue:`1987`)
|
||||
|
||||
- Correct mistakes in documentation
|
||||
|
||||
- Correct bitmask used to copy Name LSA sequence number (:issue:`2323`)
|
||||
@@ -0,0 +1,20 @@
|
||||
NLSR version 0.2.1 (changes since version 0.2.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: June 30, 2015
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Using a configuration file without ``prefix-update-validator`` disables runtime advertise/withdraw instead of exiting (:issue:`2814`)
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- Prevent incomplete removal of NPT entry (:issue:`2785`)
|
||||
|
||||
- Correct bidirectional links with differing costs (:issue:`2801`)
|
||||
|
||||
- Fix non-incrementing Adjacency number in AdjLsa::writeLog (:issue:`2594`)
|
||||
|
||||
- Remove FaceDestroyEvent test's reliance on nlsrSeqNo.txt (:issue:`2881`)
|
||||
|
||||
- Test ACTIVE/INACTIVE Adjacencies in LSA construction (:issue:`2735`)
|
||||
@@ -0,0 +1,8 @@
|
||||
NLSR version 0.2.2 (changes since version 0.2.1)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: January 5, 2016
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Adapt code to changes in NFD/ndn-cxx version 0.4.0 release
|
||||
@@ -0,0 +1,26 @@
|
||||
NLSR version 0.3.0 (changes since version 0.2.2)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: August 1, 2016
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Updated validation checker for LSA rule in the configuration file (:issue:`2965`)
|
||||
|
||||
- Do not advertise Adjacency LSAs when hyperbolic routing is enabled (:issue:`2402`)
|
||||
|
||||
- Do not distribute coordinate LSAs when using link-state routing. (:issue:`3661`)
|
||||
|
||||
- LSAs should be segmented before they are published (:issue:`2965`)
|
||||
|
||||
- Don't use DummyClientFace::sentDatas (:issue:`3383`)
|
||||
|
||||
- Remove disabled security files (:issue:`2960`)
|
||||
|
||||
- Lsa type should be argument for base class LSA constructor (:issue:`2788`)
|
||||
|
||||
- Use ndn-cxx/DummyClientFace (:issue:`2637`)
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- Unit tests cases are installed with `./waf install` (:issue:`3359`)
|
||||
@@ -0,0 +1,34 @@
|
||||
NLSR version 0.3.1 (changes since version 0.3.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: January 22, 2017
|
||||
|
||||
**Changes**
|
||||
|
||||
- **breaking change** Sync uses /localhop component in prefix to reduce duplicate NACKs (:issue:`3627`)
|
||||
|
||||
- **breaking change** LSA uses /localhop component in prefix to reduce duplicate NACKs (:issue:`3899`)
|
||||
|
||||
**Code Changes**:
|
||||
|
||||
- Fib and FaceMap use std::map instead of std::list (:issue:`2781`)
|
||||
|
||||
- NamePrefixTableEntries store RoutingTableEntries using a pointer (:issue:`2863`)
|
||||
|
||||
- Namespace closing comments are now consistent with ndn-cxx guidelines (:issue:`3735`)
|
||||
|
||||
- Update copyright date across all files (:issue:`3736`, `3909`, `3923`)
|
||||
|
||||
- Improve formatting of FaceMap and FaceMapEntry (:issue:`3737`)
|
||||
|
||||
- Sort NextHops on NexthopList insertion (:issue:`2721`)
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- HR now recalculates paths after status change of a neighbor (:issue:`3874`)
|
||||
|
||||
- NLSR no longer sets strategies multiple times (:issue:`3743`)
|
||||
|
||||
- NLSR should enable use of ndn-cxx dispatcher (:issue:`3930`)
|
||||
|
||||
- Fix typos in the sample configuration file (:issue:`3113`)
|
||||
@@ -0,0 +1,20 @@
|
||||
NLSR version 0.3.2 (changes since version 0.3.1)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: March 15, 2017
|
||||
|
||||
**Changes**
|
||||
|
||||
- NLSR constructor now accept a KeyChain argument. (:issue:`3742`)
|
||||
|
||||
- Fix security rule for /localhop LSA prefix (:issue:`3899`)
|
||||
|
||||
- Use ndn::nfd::ROUTE_ORIGIN_NLSR instead of a magic number. (:issue:`3903`)
|
||||
|
||||
- Handle "Face Already Exists" error (error code 409) in NFD. (:issue:`3976`)
|
||||
|
||||
- Enable NLSR to register localhost prefix with dispatcher before top-level prefix. (:issue:`3938`)
|
||||
|
||||
- Don't use ndn aliases provided by ndn-cxx/common.hpp. (:issue:`3983`)
|
||||
|
||||
- Remove use of deprecated code. (:issue:`3988`)
|
||||
@@ -0,0 +1,79 @@
|
||||
NLSR version 0.4.0
|
||||
++++++++++++++++++
|
||||
|
||||
**New features**:
|
||||
|
||||
- **breaking change** Discover Faces from NFD (:issue:`2954`)
|
||||
|
||||
- **breaking change** Accommodate n-Dimensional HR coordinates (:issue:`3751`)
|
||||
|
||||
**Changes**:
|
||||
|
||||
- **breaking change** Make chronosync a dependency (:issue:`2400`)
|
||||
|
||||
- **breaking change** Use separate name prefix and sequence number
|
||||
for each LSA type (:issue:`3964`)
|
||||
|
||||
- **breaking change** Convert to ``v2::security`` and adapt to ndn-cxx changes (:issue:`3964`)
|
||||
|
||||
- Use unix timestamp as default (:issue:`4187`)
|
||||
|
||||
**Bug Fixes**:
|
||||
|
||||
- Add support for sources to NamePrefixList (:issue:`4177`)
|
||||
|
||||
- Fix incorrect error on face-dataset-fetch-interval valid values (:issue:`4211`)
|
||||
|
||||
- Fix prefix advertise runtime error (:issue:`4215`)
|
||||
|
||||
- Fix heap buffer overflow error (:issue:`4217`)
|
||||
|
||||
**Code Changes**:
|
||||
|
||||
- LSA getData() now uses ostream instead of manually building the string (:issue:`2346`)
|
||||
|
||||
- Refresh FIB entries independently of routing table calculation (:issue:`2778`)
|
||||
|
||||
- Change configuration parameter output level to info (:issue:`2850`)
|
||||
|
||||
- Updates to name prefixes are more efficient (:issue:`2864`)
|
||||
|
||||
- Implement statistics collector/recorder (:issue:`2956`)
|
||||
|
||||
- Implement ``NameLsa::isEqualContent`` (:issue:`2962`)
|
||||
|
||||
- Refactor ``Fib::removeOldNextHopsFromFibEntryAndNfd()`` for simplicity, readability. (:issue:`3820`)
|
||||
|
||||
- Improve logging throughout lsdb.cpp and others (:issue:`3934`)
|
||||
|
||||
- Enable dispatcher for LOCALHOST_PREFIX (:issue:`3938`)
|
||||
|
||||
- Don't use ndn aliases provided by ndn-cxx/common.hpp (:issue:`3983`)
|
||||
|
||||
- Canonize Adjacent FaceURIs on startup (:issue:`4063`)
|
||||
|
||||
- Refactor AdjacencyList to use iterators instead of bare ptrs (:issue:`4068`)
|
||||
|
||||
- Merge redundant functions (:issue:`4105`)
|
||||
|
||||
- Remove writeLog in NamePrefixList (:issue:`4131`)
|
||||
|
||||
- Check for self in ChronoSync updates (:issue:`4134`)
|
||||
|
||||
- Install nlsr.conf as sample in the system (:issue:`4197`)
|
||||
|
||||
- Enable AddressSanitizer and LeakSanitizer for unit tests (:issue:`4206`)
|
||||
|
||||
- Resolve all ASan errors in unit tests (:issue:`4230`)
|
||||
|
||||
- Simplified LSDB dataset interest handler. (:issue:`4235`)
|
||||
|
||||
- Made map more container-agnostic (:issue:`4239`)
|
||||
|
||||
- Improved routing map data structure. (:issue:`4240`)
|
||||
|
||||
- Increased independence of SyncLogicHandler (:issue:`4264`)
|
||||
|
||||
- Use unique_ptr for signal container (:issue:`4268`)
|
||||
|
||||
- Use network name in sync prefix to avoid sync leaks from other networks (:issue:`4101`)
|
||||
@@ -0,0 +1,24 @@
|
||||
NLSR version 0.4.1
|
||||
++++++++++++++++++
|
||||
|
||||
**New features**:
|
||||
|
||||
- The routing table dataset publisher (:issue:`3630`)
|
||||
|
||||
- Use ndn-cxx logging facility, remove log4cxx dependency (:issue:`3949`)
|
||||
|
||||
- Automatic serving of other routers' certificates (:issue:`4448`)
|
||||
|
||||
**Bug Fixes**:
|
||||
|
||||
- Hard-code a fixed session name for ChronoSync sockets (:issue:`4513`)
|
||||
|
||||
- Fix encoding bug in the routing table publisher (:issue:`4453`)
|
||||
|
||||
- Fix NLSR not converging without content store (:issue:`4430`)
|
||||
|
||||
**Miscellaneous Changes**:
|
||||
|
||||
- Make ChronoSync's sync interest lifetime configurable (:issue:`4490`)
|
||||
|
||||
- Print labels on adjacency matrix when logging (:issue:`2045`)
|
||||
@@ -0,0 +1,70 @@
|
||||
NLSR Versions
|
||||
+++++++++++++
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
|
||||
release-notes/release-notes-0.4.1
|
||||
release-notes/release-notes-0.4.0
|
||||
release-notes/release-notes-0.3.2
|
||||
release-notes/release-notes-0.3.1
|
||||
release-notes/release-notes-0.3.0
|
||||
release-notes/release-notes-0.2.2
|
||||
release-notes/release-notes-0.2.1
|
||||
release-notes/release-notes-0.2.0
|
||||
release-notes/release-notes-0.1.0
|
||||
|
||||
* **NLSR version 0.4.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`, `Documentation <https://named-data.net/doc/NLSR/0.4.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.4.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`, `Documentation <https://named-data.net/doc/NLSR/0.4.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.3.2**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.2>`, `Documentation <https://named-data.net/doc/NLSR/0.3.2/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.3.2>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.3.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.3.2.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.3.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.1>`, `Documentation <https://named-data.net/doc/NLSR/0.3.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.3.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.3.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.3.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.3.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.0>`, `Documentation <https://named-data.net/doc/NLSR/0.3.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.3.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.3.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.3.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.2.2**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.2.2>`, `Documentation <https://named-data.net/doc/NLSR/0.2.2/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.2.2>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.2.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.2.2.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.2.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.2.1>`, `Documentation <https://named-data.net/doc/NLSR/0.2.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.2.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.2.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.2.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.2.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.2.0>`, `Documentation <https://named-data.net/doc/NLSR/0.2.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.2.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.2.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.2.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.1.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.1.0>`, `Documentation <https://named-data.net/doc/NLSR/0.1.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.1.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.1.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.1.0.tar.bz2.sha256>`__)
|
||||
@@ -1,11 +0,0 @@
|
||||
log4j.rootLogger=DEBUG, Rolling
|
||||
|
||||
log4j.appender.Rolling=org.apache.log4j.rolling.RollingFileAppender
|
||||
log4j.appender.Rolling.File=/tmp/testnlsrproperties.log
|
||||
log4j.appender.Rolling.MaxSize=1MB
|
||||
log4j.appender.Rolling.MaxBackupIndex=10
|
||||
|
||||
log4j.appender.Rolling.layout=PatternLayout
|
||||
log4j.appender.Rolling.layout.ContextPrinting=enabled
|
||||
log4j.appender.Rolling.layout.DateFormat=ISO8601
|
||||
log4j.appender.Rolling.layout.ConversionPattern=%date{yyyyMMddHHmmssSSS} %p: [%c] %m%n
|
||||
@@ -11,7 +11,7 @@ general
|
||||
; lsa-refresh-time is the time in seconds, after which router will refresh its LSAs
|
||||
lsa-refresh-time 1800 ; default value 1800. Valid values 240-7200
|
||||
|
||||
; router-dead-interval is the time in seconds after which an inactive router's
|
||||
; router-dead-interval is the time in seconds after which an inactive routers
|
||||
; LSAs are removed
|
||||
;router-dead-interval 3600 ; default value: 2*lsa-refresh-time. Value must be larger
|
||||
; than lsa-refresh-time
|
||||
@@ -19,27 +19,13 @@ general
|
||||
; InterestLifetime (in seconds) for LSA fetching
|
||||
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
|
||||
|
||||
; log-level is used to set the logging level for NLSR.
|
||||
; All debugging levels listed above the selected value are enabled.
|
||||
;
|
||||
; Valid values:
|
||||
;
|
||||
; NONE ; no messages
|
||||
; ERROR ; error messages
|
||||
; WARN ; warning messages
|
||||
; INFO ; informational messages (default)
|
||||
; DEBUG ; debugging messages
|
||||
; TRACE ; trace messages (most verbose)
|
||||
; ALL ; all messages
|
||||
; sync interest lifetime of ChronoSync in milliseconds
|
||||
sync-interest-lifetime 60000 ; default value 60000. Valid values 1000-120,000
|
||||
|
||||
log-level INFO
|
||||
|
||||
log-dir /var/log/nlsr/ ; path for log directory (Absolute path)
|
||||
seq-dir /var/lib/nlsr/ ; path for sequence directory (Absolute path)
|
||||
;log4cxx-conf /path/to/log4cxx-conf ; path for log4cxx configuration file (Absolute path)
|
||||
seq-dir /var/lib/nlsr ; path for sequence directory (Absolute path)
|
||||
}
|
||||
|
||||
; the neighbors section contains the configuration for router's neighbors and hello's behavior
|
||||
; the neighbor's section contains the configuration for router's neighbors and hellos behavior
|
||||
|
||||
neighbors
|
||||
{
|
||||
@@ -65,6 +51,16 @@ neighbors
|
||||
|
||||
first-hello-interval 10 ; Default value 10. Valid values 0-10
|
||||
|
||||
face-dataset-fetch-tries 3 ; default is 3. Valid values 1-10. The FaceDataset is
|
||||
; gotten from NFD, and is needed to configure NLSR
|
||||
; correctly. It is recommended not to set this
|
||||
; variable too high, because it could cause
|
||||
; congestion for NFD.
|
||||
|
||||
face-dataset-fetch-interval 3600 ; default is 3600. Valid values 1800-5400.
|
||||
; This controls how often (in seconds) NLSR will attempt to
|
||||
; fetch a FaceStatus dataset from NFD.
|
||||
|
||||
; neighbor command is used to configure router's neighbor. Each neighbor will need
|
||||
; one block of neighbor command
|
||||
|
||||
@@ -101,11 +97,11 @@ hyperbolic
|
||||
|
||||
|
||||
radius 123.456 ; radius of the router in hyperbolic coordinate system
|
||||
angle 1.45 ; angle of the router in hyperbolic coordinate system
|
||||
angle 1.45,2.36 ; angle of the router in hyperbolic coordinate system
|
||||
}
|
||||
|
||||
|
||||
; the fib section is used to configure fib entry's type to ndn FIB updated by NLSR
|
||||
; the fib section is used to configure fib entrys type to ndn FIB updated by NLSR
|
||||
|
||||
fib
|
||||
{
|
||||
@@ -156,7 +152,7 @@ security
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
|
||||
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
|
||||
k-expand \\1
|
||||
h-relation equal
|
||||
p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$
|
||||
@@ -184,7 +180,7 @@ security
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
|
||||
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
|
||||
k-expand \\1
|
||||
h-relation equal
|
||||
; the last four components in the prefix should be <lsaType><seqNo><version><segmentNo>
|
||||
@@ -202,7 +198,7 @@ security
|
||||
filter
|
||||
{
|
||||
type name
|
||||
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><ksk-.*><ID-CERT><>$
|
||||
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><><><>$
|
||||
}
|
||||
checker
|
||||
{
|
||||
@@ -213,10 +209,10 @@ security
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
|
||||
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
|
||||
k-expand \\1
|
||||
h-relation equal
|
||||
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
|
||||
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><><><>$
|
||||
p-expand \\1
|
||||
}
|
||||
}
|
||||
@@ -230,7 +226,7 @@ security
|
||||
filter
|
||||
{
|
||||
type name
|
||||
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
|
||||
regex ^[^<KEY>]*<KEY><><><>$
|
||||
}
|
||||
checker
|
||||
{
|
||||
@@ -255,7 +251,9 @@ security
|
||||
filter
|
||||
{
|
||||
type name
|
||||
regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$
|
||||
; /<prefix>/<management-module>/<command-verb>/<control-parameters>
|
||||
; /<timestamp>/<random-value>/<signed-interests-components>
|
||||
regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<><><>$
|
||||
}
|
||||
checker
|
||||
{
|
||||
@@ -264,7 +262,7 @@ security
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
|
||||
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,7 +274,7 @@ security
|
||||
filter
|
||||
{
|
||||
type name
|
||||
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
|
||||
regex ^[^<KEY>]*<KEY><><><>$
|
||||
}
|
||||
checker
|
||||
{
|
||||
@@ -291,6 +289,7 @@ security
|
||||
file-name "site.cert"
|
||||
}
|
||||
}
|
||||
|
||||
; cert-to-publish "root.cert" ; optional, a file containing the root certificate
|
||||
; Only the router that is designated to publish the root cert
|
||||
; needs to specify this
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
nsync is a copy of ChronoSync (https://github.com/bruinfish/ChronoSync/tree/master).
|
||||
|
||||
ChonoSync's license is GPL2.
|
||||
@@ -1,15 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* See COPYING.md for copyright and distribution information.
|
||||
*/
|
||||
|
||||
// suppress Boost::archive warnings
|
||||
#pragma GCC system_header
|
||||
#pragma clang system_header
|
||||
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/archive/iterators/dataflow_exception.hpp>
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef NSYNC_OPENSSL_H
|
||||
#define 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 // NSYNC_OPENSSL_H
|
||||
@@ -1,74 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-diff-leaf.h"
|
||||
#include <boost/throw_exception.hpp>
|
||||
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;
|
||||
|
||||
using namespace Sync::Error;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
DiffLeaf::DiffLeaf (NameInfoConstPtr info, const SeqNo &seq)
|
||||
: Leaf (info, seq)
|
||||
, m_op (UPDATE)
|
||||
{
|
||||
}
|
||||
|
||||
DiffLeaf::DiffLeaf (NameInfoConstPtr info)
|
||||
: Leaf (info, SeqNo (0,0))
|
||||
, m_op (REMOVE)
|
||||
{
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, Operation op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case UPDATE:
|
||||
os << "update";
|
||||
break;
|
||||
case REMOVE:
|
||||
os << "remove";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Operation &op)
|
||||
{
|
||||
std::string operation;
|
||||
is >> operation;
|
||||
if (operation == "update")
|
||||
op = UPDATE;
|
||||
else if (operation == "remove")
|
||||
op = REMOVE;
|
||||
else
|
||||
BOOST_THROW_EXCEPTION (SyncDiffLeafOperationParseError () << errmsg_info (operation));
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_DIFF_LEAF_H
|
||||
#define 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 // SYNC_DIFF_LEAF_H
|
||||
@@ -1,72 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_DIFF_STATE_CONTAINER_H
|
||||
#define 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 // SYNC_DIFF_STATE_CONTAINER_H
|
||||
@@ -1,98 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-diff-state.h"
|
||||
#include "sync-diff-leaf.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
DiffState::DiffState ()
|
||||
{
|
||||
}
|
||||
|
||||
DiffState::~DiffState ()
|
||||
{
|
||||
}
|
||||
|
||||
DiffStatePtr
|
||||
DiffState::diff () const
|
||||
{
|
||||
DiffStatePtr ret = make_shared<DiffState> ();
|
||||
|
||||
DiffStatePtr state = m_next;
|
||||
while (state != 0)
|
||||
{
|
||||
*ret += *state;
|
||||
state = state->m_next;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DiffState &
|
||||
DiffState::operator += (const DiffState &state)
|
||||
{
|
||||
BOOST_FOREACH (LeafConstPtr _leaf, state.getLeaves ())
|
||||
{
|
||||
DiffLeafConstPtr leaf = dynamic_pointer_cast<const DiffLeaf> (_leaf);
|
||||
BOOST_ASSERT (leaf != 0);
|
||||
|
||||
if (leaf->getOperation () == UPDATE)
|
||||
update (leaf->getInfo (), leaf->getSeq ());
|
||||
else if (leaf->getOperation () == REMOVE)
|
||||
remove (leaf->getInfo ());
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT (false);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// from State
|
||||
tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
|
||||
DiffState::update (NameInfoConstPtr info, const SeqNo &seq)
|
||||
{
|
||||
m_leaves.erase (info);
|
||||
|
||||
DiffLeafPtr leaf = make_shared<DiffLeaf> (info, seq);
|
||||
m_leaves.insert (leaf);
|
||||
|
||||
return make_tuple (true, false, SeqNo ());
|
||||
}
|
||||
|
||||
bool
|
||||
DiffState::remove (NameInfoConstPtr info)
|
||||
{
|
||||
m_leaves.erase (info);
|
||||
|
||||
DiffLeafPtr leaf = make_shared<DiffLeaf> (info);
|
||||
m_leaves.insert (leaf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // ns3
|
||||
@@ -1,102 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_DIFF_STATE_H
|
||||
#define 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 // SYNC_DIFF_STATE_H
|
||||
@@ -1,262 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-digest.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
|
||||
typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
|
||||
|
||||
// for printing, may be disabled in optimized build
|
||||
|
||||
// #ifdef DIGEST_BASE64
|
||||
// #include <boost/archive/iterators/base64_from_binary.hpp>
|
||||
// #include <boost/archive/iterators/binary_from_base64.hpp>
|
||||
// #endif
|
||||
|
||||
#include "boost-archive.h"
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::archive::iterators;
|
||||
using namespace std;
|
||||
|
||||
// Other options: VP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha256, EVP_dss, EVP_dss1, EVP_mdc2, EVP_ripemd160
|
||||
#define HASH_FUNCTION EVP_sha256
|
||||
#define HASH_FUNCTION_LEN 32
|
||||
|
||||
|
||||
// #ifndef DIGEST_BASE64
|
||||
|
||||
template<class CharType>
|
||||
struct hex_from_4_bit
|
||||
{
|
||||
typedef CharType result_type;
|
||||
CharType operator () (CharType ch) const
|
||||
{
|
||||
const char *lookup_table = "0123456789abcdef";
|
||||
// cout << "New character: " << (int) ch << " (" << (char) ch << ")" << "\n";
|
||||
BOOST_ASSERT (ch < 16);
|
||||
return lookup_table[static_cast<size_t>(ch)];
|
||||
}
|
||||
};
|
||||
|
||||
typedef transform_iterator<hex_from_4_bit<std::vector<uint8_t>::const_iterator::value_type>,
|
||||
transform_width<std::vector<uint8_t>::const_iterator, 4, 8, std::vector<uint8_t>::const_iterator::value_type> > string_from_binary;
|
||||
|
||||
|
||||
template<class CharType>
|
||||
struct hex_to_4_bit
|
||||
{
|
||||
typedef CharType result_type;
|
||||
CharType operator () (CharType ch) const
|
||||
{
|
||||
const signed char lookup_table [] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
||||
};
|
||||
|
||||
// cout << "New character: " << hex << (int) ch << " (" << (char) ch << ")" << "\n";
|
||||
signed char value = -1;
|
||||
if ((unsigned)ch < 128)
|
||||
value = lookup_table [(unsigned)ch];
|
||||
if (value == -1)
|
||||
BOOST_THROW_EXCEPTION (Sync::Error::DigestCalculationError () << errmsg_info_int ((int)ch));
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
typedef transform_width<transform_iterator<hex_to_4_bit<string::const_iterator::value_type>, string::const_iterator>, 8, 4> string_to_binary;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
Digest::Digest ()
|
||||
{
|
||||
m_context = EVP_MD_CTX_create ();
|
||||
|
||||
reset ();
|
||||
}
|
||||
|
||||
Digest::~Digest ()
|
||||
{
|
||||
EVP_MD_CTX_destroy (m_context);
|
||||
}
|
||||
|
||||
bool
|
||||
Digest::empty () const
|
||||
{
|
||||
return m_buffer.empty ();
|
||||
}
|
||||
|
||||
bool
|
||||
Digest::isZero () const
|
||||
{
|
||||
if (m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has not been yet finalized"));
|
||||
|
||||
return (m_buffer.size () == 1 && m_buffer[0] == 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Digest::reset ()
|
||||
{
|
||||
m_buffer.clear ();
|
||||
|
||||
int ok = EVP_DigestInit_ex (m_context, HASH_FUNCTION (), 0);
|
||||
if (!ok)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("EVP_DigestInit_ex returned error")
|
||||
<< errmsg_info_int (ok));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Digest::finalize ()
|
||||
{
|
||||
if (!m_buffer.empty ()) return;
|
||||
|
||||
m_buffer.resize (HASH_FUNCTION_LEN);
|
||||
|
||||
unsigned int tmp;
|
||||
int ok = EVP_DigestFinal_ex (m_context,
|
||||
&m_buffer[0], &tmp);
|
||||
if (!ok)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("EVP_DigestFinal_ex returned error")
|
||||
<< errmsg_info_int (ok));
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Digest::getHash () const
|
||||
{
|
||||
if (isZero ()) return 0;
|
||||
|
||||
if (sizeof (std::size_t) > m_buffer.size ())
|
||||
{
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Hash is not zero and length is less than size_t")
|
||||
<< errmsg_info_int (m_buffer.size ()));
|
||||
}
|
||||
|
||||
// just getting first sizeof(std::size_t) bytes
|
||||
// not ideal, but should work pretty well
|
||||
return *(reinterpret_cast<const std::size_t*> (&m_buffer[0]));
|
||||
}
|
||||
|
||||
bool
|
||||
Digest::operator == (const Digest &digest) const
|
||||
{
|
||||
if (m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest1 is empty"));
|
||||
|
||||
if (digest.m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest2 is empty"));
|
||||
|
||||
return m_buffer == digest.m_buffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Digest::update (const uint8_t *buffer, size_t size)
|
||||
{
|
||||
// cout << "Update: " << (void*)buffer << " / size: " << size << "\n";
|
||||
|
||||
// cannot update Digest when it has been finalized
|
||||
if (!m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has been already finalized"));
|
||||
|
||||
bool ok = EVP_DigestUpdate (m_context, buffer, size);
|
||||
if (!ok)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("EVP_DigestUpdate returned error")
|
||||
<< errmsg_info_int (ok));
|
||||
}
|
||||
|
||||
|
||||
Digest &
|
||||
Digest::operator << (const Digest &src)
|
||||
{
|
||||
if (src.m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has not been yet finalized"));
|
||||
|
||||
update (&src.m_buffer[0], src.m_buffer.size ());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const Digest &digest)
|
||||
{
|
||||
BOOST_ASSERT (!digest.m_buffer.empty ());
|
||||
|
||||
ostreambuf_iterator<char> out_it (os); // ostream iterator
|
||||
// need to encode to base64
|
||||
copy (string_from_binary (digest.m_buffer.begin ()),
|
||||
string_from_binary (digest.m_buffer.end ()),
|
||||
out_it);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Digest &digest)
|
||||
{
|
||||
string str;
|
||||
is >> str; // read string first
|
||||
|
||||
if (str.size () == 0)
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Input is empty"));
|
||||
|
||||
// uint8_t padding = (3 - str.size () % 3) % 3;
|
||||
// for (uint8_t i = 0; i < padding; i++) str.push_back ('=');
|
||||
|
||||
// only empty digest object can be used for reading
|
||||
if (!digest.m_buffer.empty ())
|
||||
BOOST_THROW_EXCEPTION (Error::DigestCalculationError ()
|
||||
<< errmsg_info_str ("Digest has been already finalized"));
|
||||
|
||||
digest.m_buffer.clear ();
|
||||
|
||||
copy (string_to_binary (str.begin ()),
|
||||
string_to_binary (str.end ()),
|
||||
std::back_inserter (digest.m_buffer));
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
} // Sync
|
||||
@@ -1,199 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_DIGEST_H
|
||||
#define 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 // SYNC_DIGEST_H
|
||||
@@ -1,35 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_EVENT_H
|
||||
#define SYNC_EVENT_H
|
||||
|
||||
#include "sync-common.h"
|
||||
|
||||
namespace Sync
|
||||
{
|
||||
|
||||
typedef function< void ( ) > Event;
|
||||
|
||||
} // Sync
|
||||
|
||||
#endif // SYNC_EVENT_H
|
||||
@@ -1,49 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-full-leaf.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
FullLeaf::FullLeaf (NameInfoConstPtr info, const SeqNo &seq)
|
||||
: Leaf (info, seq)
|
||||
{
|
||||
updateDigest ();
|
||||
}
|
||||
|
||||
void
|
||||
FullLeaf::updateDigest ()
|
||||
{
|
||||
m_digest.reset ();
|
||||
m_digest << getInfo ()->getDigest () << *getSeq ().getDigest ();
|
||||
m_digest.finalize ();
|
||||
}
|
||||
|
||||
// from Leaf
|
||||
void
|
||||
FullLeaf::setSeq (const SeqNo &seq)
|
||||
{
|
||||
Leaf::setSeq (seq);
|
||||
updateDigest ();
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,71 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_FULL_LEAF_H
|
||||
#define 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 // SYNC_FULL_LEAF_H
|
||||
@@ -1,118 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-full-state.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include "sync-full-leaf.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
|
||||
FullState::FullState ()
|
||||
// m_lastUpdated is initialized to "not_a_date_time" in normal lib mode and to "0" time in NS-3 mode
|
||||
{
|
||||
}
|
||||
|
||||
FullState::~FullState ()
|
||||
{
|
||||
}
|
||||
|
||||
ndn::time::system_clock::Duration
|
||||
FullState::getTimeFromLastUpdate () const
|
||||
{
|
||||
return ndn::time::system_clock::now() - m_lastUpdated;
|
||||
}
|
||||
|
||||
DigestConstPtr
|
||||
FullState::getDigest ()
|
||||
{
|
||||
if (!m_digest)
|
||||
{
|
||||
m_digest = make_shared<Digest> ();
|
||||
if (m_leaves.get<ordered> ().size () > 0)
|
||||
{
|
||||
for (LeafConstPtr leaf : m_leaves.get<ordered> ())
|
||||
{
|
||||
FullLeafConstPtr fullLeaf = dynamic_pointer_cast<const FullLeaf> (leaf);
|
||||
BOOST_ASSERT (fullLeaf != 0);
|
||||
*m_digest << fullLeaf->getDigest ();
|
||||
}
|
||||
m_digest->finalize ();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::istringstream is ("00"); //zero state
|
||||
is >> *m_digest;
|
||||
}
|
||||
}
|
||||
|
||||
return m_digest;
|
||||
}
|
||||
|
||||
// from State
|
||||
tuple<bool/*inserted*/, bool/*updated*/, SeqNo/*oldSeqNo*/>
|
||||
FullState::update (NameInfoConstPtr info, const SeqNo &seq)
|
||||
{
|
||||
m_lastUpdated = ndn::time::system_clock::now();
|
||||
|
||||
|
||||
m_digest.reset ();
|
||||
|
||||
LeafContainer::iterator item = m_leaves.find (info);
|
||||
if (item == m_leaves.end ())
|
||||
{
|
||||
m_leaves.insert (make_shared<FullLeaf> (info, seq));
|
||||
return make_tuple (true, false, SeqNo ());
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*item)->getSeq () == seq || seq < (*item)->getSeq ())
|
||||
{
|
||||
return make_tuple (false, false, SeqNo ());
|
||||
}
|
||||
|
||||
SeqNo old = (*item)->getSeq ();
|
||||
m_leaves.modify (item, [&seq](LeafPtr data){ data->setSeq(seq); });
|
||||
return make_tuple (false, true, old);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FullState::remove (NameInfoConstPtr info)
|
||||
{
|
||||
m_lastUpdated = ndn::time::system_clock::now();
|
||||
|
||||
m_digest.reset ();
|
||||
|
||||
LeafContainer::iterator item = m_leaves.find (info);
|
||||
if (item != m_leaves.end ())
|
||||
{
|
||||
m_leaves.erase (item);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,79 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_FULL_STATE_H
|
||||
#define 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 // SYNC_STATE_H
|
||||
@@ -1,99 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_INTEREST_CONTAINER_H
|
||||
#define 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 // SYNC_INTEREST_CONTAINER_H
|
||||
@@ -1,126 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-interest-table.h"
|
||||
#include "sync-logging.h"
|
||||
using namespace std;
|
||||
|
||||
INIT_LOGGER("SyncInterestTable");
|
||||
|
||||
namespace Sync
|
||||
{
|
||||
|
||||
SyncInterestTable::SyncInterestTable(boost::asio::io_service& io, ndn::time::system_clock::Duration lifetime)
|
||||
: m_entryLifetime(lifetime)
|
||||
, m_scheduler(io)
|
||||
{
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(4),
|
||||
ndn::bind(&SyncInterestTable::expireInterests, this));
|
||||
}
|
||||
|
||||
SyncInterestTable::~SyncInterestTable()
|
||||
{
|
||||
}
|
||||
|
||||
Interest
|
||||
SyncInterestTable::pop()
|
||||
{
|
||||
if (m_table.size() == 0)
|
||||
BOOST_THROW_EXCEPTION(Error::InterestTableIsEmpty());
|
||||
|
||||
Interest ret = *m_table.begin();
|
||||
m_table.erase(m_table.begin());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
SyncInterestTable::insert(DigestConstPtr digest, const string &name, bool unknownState/*=false*/)
|
||||
{
|
||||
bool existent = false;
|
||||
|
||||
InterestContainer::index<named>::type::iterator it = m_table.get<named>().find(name);
|
||||
if (it != m_table.end())
|
||||
{
|
||||
existent = true;
|
||||
m_table.erase(it);
|
||||
}
|
||||
m_table.insert(Interest(digest, name, unknownState));
|
||||
|
||||
return existent;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SyncInterestTable::size() const
|
||||
{
|
||||
return m_table.size();
|
||||
}
|
||||
|
||||
bool
|
||||
SyncInterestTable::remove(const string &name)
|
||||
{
|
||||
InterestContainer::index<named>::type::iterator item = m_table.get<named>().find(name);
|
||||
if (item != m_table.get<named>().end())
|
||||
{
|
||||
m_table.get<named>().erase(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SyncInterestTable::remove(DigestConstPtr digest)
|
||||
{
|
||||
InterestContainer::index<hashed>::type::iterator item = m_table.get<hashed>().find(digest);
|
||||
if (item != m_table.get<hashed>().end())
|
||||
{
|
||||
m_table.get<hashed>().erase(digest); // erase all records associated with the digest
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SyncInterestTable::expireInterests()
|
||||
{
|
||||
uint32_t count = 0;
|
||||
ndn::time::system_clock::TimePoint expireTime = ndn::time::system_clock::now() - m_entryLifetime;
|
||||
|
||||
while (m_table.size() > 0)
|
||||
{
|
||||
InterestContainer::index<timed>::type::iterator item = m_table.get<timed>().begin();
|
||||
|
||||
if (item->m_time <= expireTime)
|
||||
{
|
||||
m_table.get<timed>().erase(item);
|
||||
count ++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(4),
|
||||
ndn::bind(&SyncInterestTable::expireInterests, this));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_INTEREST_TABLE_H
|
||||
#define 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 // SYNC_INTEREST_TABLE_H
|
||||
@@ -1,43 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-leaf.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
Leaf::Leaf (NameInfoConstPtr info, const SeqNo &seq)
|
||||
: m_info (info)
|
||||
, m_seq (seq)
|
||||
{
|
||||
}
|
||||
|
||||
Leaf::~Leaf ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Leaf::setSeq (const SeqNo &seq)
|
||||
{
|
||||
m_seq = std::max (m_seq, seq);
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,84 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_LEAF_H
|
||||
#define 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 // SYNC_LEAF_H
|
||||
@@ -1,61 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-logging.h"
|
||||
|
||||
#ifdef HAVE_LOG4CXX
|
||||
|
||||
#include <log4cxx/logger.h>
|
||||
#include <log4cxx/basicconfigurator.h>
|
||||
#include <log4cxx/consoleappender.h>
|
||||
#include <log4cxx/patternlayout.h>
|
||||
#include <log4cxx/level.h>
|
||||
#include <log4cxx/propertyconfigurator.h>
|
||||
#include <log4cxx/defaultconfigurator.h>
|
||||
#include <log4cxx/helpers/exception.h>
|
||||
using namespace log4cxx;
|
||||
using namespace log4cxx::helpers;
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
void
|
||||
INIT_LOGGERS ()
|
||||
{
|
||||
static bool configured = false;
|
||||
|
||||
if (configured) return;
|
||||
|
||||
if (access ("log4cxx.properties", R_OK)==0)
|
||||
PropertyConfigurator::configureAndWatch ("log4cxx.properties");
|
||||
else
|
||||
{
|
||||
PatternLayoutPtr layout (new PatternLayout ("%d{HH:mm:ss} %p %c{1} - %m%n"));
|
||||
ConsoleAppenderPtr appender (new ConsoleAppender (layout));
|
||||
|
||||
BasicConfigurator::configure( appender );
|
||||
Logger::getRootLogger()->setLevel (log4cxx::Level::getInfo ());
|
||||
}
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,74 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_LOG_H
|
||||
#define SYNC_LOG_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 // SYNC_LOG_H
|
||||
@@ -1,84 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_LOGIC_EVENT_CONTAINER_H
|
||||
#define 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 // SYNC_LOGIC_EVENT_CONTAINER_H
|
||||
@@ -1,752 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
* Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-logic.h"
|
||||
#include "sync-diff-leaf.h"
|
||||
#include "sync-full-leaf.h"
|
||||
#include "sync-logging.h"
|
||||
#include "sync-state.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using ndn::Data;
|
||||
using ndn::EventId;
|
||||
using ndn::KeyChain;
|
||||
using ndn::Face;
|
||||
using ndn::Name;
|
||||
using ndn::OnDataValidated;
|
||||
using ndn::OnDataValidationFailed;
|
||||
using ndn::Validator;
|
||||
|
||||
INIT_LOGGER ("SyncLogic");
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define _LOG_DEBUG_ID(v) _LOG_DEBUG(m_instanceId << " " << v)
|
||||
#else
|
||||
#define _LOG_DEBUG_ID(v) _LOG_DEBUG(v)
|
||||
#endif
|
||||
|
||||
#define GET_RANDOM(var) var ()
|
||||
|
||||
#define TIME_SECONDS_WITH_JITTER(sec) \
|
||||
(ndn::time::seconds(sec) + ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
|
||||
|
||||
#define TIME_MILLISECONDS_WITH_JITTER(ms) \
|
||||
(ndn::time::seconds(ms) + ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter)))
|
||||
|
||||
namespace Sync {
|
||||
|
||||
using ndn::shared_ptr;
|
||||
|
||||
int SyncLogic::m_instanceCounter = 0;
|
||||
|
||||
const int SyncLogic::m_syncResponseFreshness = 1000; // MUST BE dividable by 1000!!!
|
||||
const int SyncLogic::m_syncInterestReexpress = 4; // seconds
|
||||
|
||||
SyncLogic::SyncLogic (const Name& syncPrefix,
|
||||
shared_ptr<Validator> validator,
|
||||
shared_ptr<Face> face,
|
||||
LogicUpdateCallback onUpdate,
|
||||
LogicRemoveCallback onRemove)
|
||||
: m_state (new FullState)
|
||||
, m_syncInterestTable (face->getIoService(), ndn::time::seconds(m_syncInterestReexpress))
|
||||
, m_syncPrefix (syncPrefix)
|
||||
, m_onUpdate (onUpdate)
|
||||
, m_onRemove (onRemove)
|
||||
, m_perBranch (false)
|
||||
, m_validator(validator)
|
||||
, m_keyChain(new KeyChain())
|
||||
, m_face(face)
|
||||
, m_scheduler(face->getIoService())
|
||||
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
|
||||
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
|
||||
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
|
||||
, m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
|
||||
{
|
||||
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
|
||||
bind(&SyncLogic::onSyncInterest,
|
||||
this, _1, _2),
|
||||
bind(&SyncLogic::onSyncRegisterSucceed,
|
||||
this, _1),
|
||||
bind(&SyncLogic::onSyncRegisterFailed,
|
||||
this, _1, _2));
|
||||
|
||||
|
||||
m_reexpressingInterestId = m_scheduler.scheduleEvent (ndn::time::seconds (0),
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
|
||||
m_instanceId = string("Instance " + boost::lexical_cast<string>(m_instanceCounter++) + " ");
|
||||
}
|
||||
|
||||
SyncLogic::SyncLogic (const Name& syncPrefix,
|
||||
shared_ptr<Validator> validator,
|
||||
shared_ptr<Face> face,
|
||||
LogicPerBranchCallback onUpdateBranch)
|
||||
: m_state (new FullState)
|
||||
, m_syncInterestTable (face->getIoService(), ndn::time::seconds (m_syncInterestReexpress))
|
||||
, m_syncPrefix (syncPrefix)
|
||||
, m_onUpdateBranch (onUpdateBranch)
|
||||
, m_perBranch(true)
|
||||
, m_validator(validator)
|
||||
, m_keyChain(new KeyChain())
|
||||
, m_face(face)
|
||||
, m_scheduler(face->getIoService())
|
||||
, m_randomGenerator (static_cast<unsigned int> (std::time (0)))
|
||||
, m_rangeUniformRandom (m_randomGenerator, boost::uniform_int<> (200,1000))
|
||||
, m_reexpressionJitter (m_randomGenerator, boost::uniform_int<> (100,500))
|
||||
, m_recoveryRetransmissionInterval (m_defaultRecoveryRetransmitInterval)
|
||||
{
|
||||
m_syncRegisteredPrefixId = m_face->setInterestFilter (m_syncPrefix,
|
||||
bind(&SyncLogic::onSyncInterest,
|
||||
this, _1, _2),
|
||||
bind(&SyncLogic::onSyncRegisterSucceed,
|
||||
this, _1),
|
||||
bind(&SyncLogic::onSyncRegisterFailed,
|
||||
this, _1, _2));
|
||||
|
||||
m_reexpressingInterestId = m_scheduler.scheduleEvent (ndn::time::seconds (0),
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
}
|
||||
|
||||
SyncLogic::~SyncLogic ()
|
||||
{
|
||||
m_face->unsetInterestFilter(m_syncRegisteredPrefixId);
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Two types of intersts
|
||||
*
|
||||
* Normal name: .../<hash>
|
||||
* Recovery name: .../recovery/<hash>
|
||||
*/
|
||||
tuple<DigestConstPtr, std::string>
|
||||
SyncLogic::convertNameToDigestAndType (const Name &name)
|
||||
{
|
||||
BOOST_ASSERT (m_syncPrefix.isPrefixOf(name));
|
||||
|
||||
int nameLengthDiff = name.size() - m_syncPrefix.size();
|
||||
BOOST_ASSERT (nameLengthDiff > 0);
|
||||
BOOST_ASSERT (nameLengthDiff < 3);
|
||||
|
||||
string hash = name.get(-1).toUri();
|
||||
string interestType;
|
||||
|
||||
if(nameLengthDiff == 1)
|
||||
interestType = "normal";
|
||||
else
|
||||
interestType = name.get(-2).toUri();
|
||||
|
||||
_LOG_DEBUG_ID (hash << ", " << interestType);
|
||||
|
||||
DigestPtr digest = make_shared<Digest> ();
|
||||
istringstream is (hash);
|
||||
is >> *digest;
|
||||
|
||||
return make_tuple(digest, interestType);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncInterest (const Name& prefix, const ndn::Interest& interest)
|
||||
{
|
||||
Name name = interest.getName();
|
||||
|
||||
_LOG_DEBUG_ID("respondSyncInterest: " << name);
|
||||
|
||||
try
|
||||
{
|
||||
_LOG_DEBUG_ID ("<< I " << name);
|
||||
|
||||
DigestConstPtr digest;
|
||||
string type;
|
||||
tie (digest, type) = convertNameToDigestAndType (name);
|
||||
|
||||
if (type == "normal") // kind of ineffective...
|
||||
{
|
||||
processSyncInterest (name, digest);
|
||||
}
|
||||
else if (type == "recovery")
|
||||
{
|
||||
processSyncRecoveryInterest (name, digest);
|
||||
}
|
||||
}
|
||||
catch (Error::DigestCalculationError &e)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Something fishy happened...");
|
||||
// log error. ignoring it for now, later we should log it
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncRegisterSucceed(const Name& prefix)
|
||||
{
|
||||
_LOG_DEBUG_ID("Sync prefix registration succeeded! " << prefix);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncRegisterFailed(const Name& prefix, const string& msg)
|
||||
{
|
||||
_LOG_DEBUG_ID("Sync prefix registration failed! " << msg);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncData(const ndn::Interest& interest, const Data& data)
|
||||
{
|
||||
OnDataValidated onValidated = bind(&SyncLogic::onSyncDataValidated, this, _1);
|
||||
OnDataValidationFailed onValidationFailed = bind(&SyncLogic::onSyncDataValidationFailed, this, _1);
|
||||
m_validator->validate(data, onValidated, onValidationFailed);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncTimeout(const ndn::Interest& interest)
|
||||
{
|
||||
// It is OK. Others will handle the time out situation.
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncDataValidationFailed(const shared_ptr<const Data>& data)
|
||||
{
|
||||
_LOG_DEBUG_ID("Sync data cannot be verified!");
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::onSyncDataValidated(const shared_ptr<const Data>& data)
|
||||
{
|
||||
Name name = data->getName();
|
||||
const char* wireData = (const char*)data->getContent().value();
|
||||
size_t len = data->getContent().value_size();
|
||||
|
||||
try
|
||||
{
|
||||
_LOG_DEBUG_ID ("<< D " << name);
|
||||
|
||||
DigestConstPtr digest;
|
||||
string type;
|
||||
tie (digest, type) = convertNameToDigestAndType (name);
|
||||
|
||||
if (type == "normal")
|
||||
{
|
||||
processSyncData (name, digest, wireData, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// timer is always restarted when we schedule recovery
|
||||
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
|
||||
processSyncData (name, digest, wireData, len);
|
||||
}
|
||||
}
|
||||
catch (Error::DigestCalculationError &e)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Something fishy happened...");
|
||||
// log error. ignoring it for now, later we should log it
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::processSyncInterest (const Name &name, DigestConstPtr digest,
|
||||
bool timedProcessing/*=false*/)
|
||||
{
|
||||
_LOG_DEBUG_ID("processSyncInterest");
|
||||
DigestConstPtr rootDigest;
|
||||
{
|
||||
rootDigest = m_state->getDigest();
|
||||
}
|
||||
|
||||
// Special case when state is not empty and we have received request with zero-root digest
|
||||
if (digest->isZero () && !rootDigest->isZero ())
|
||||
{
|
||||
|
||||
SyncStateMsg ssm;
|
||||
{
|
||||
ssm << (*m_state);
|
||||
}
|
||||
sendSyncData (name, digest, ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*rootDigest == *digest)
|
||||
{
|
||||
_LOG_DEBUG_ID ("processSyncInterest (): Same state. Adding to PIT");
|
||||
m_syncInterestTable.insert (digest, name.toUri(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
|
||||
|
||||
if (stateInDiffLog != m_log.end ())
|
||||
{
|
||||
DiffStateConstPtr stateDiff = (*stateInDiffLog)->diff ();
|
||||
|
||||
sendSyncData (name, digest, stateDiff);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!timedProcessing)
|
||||
{
|
||||
bool exists = m_syncInterestTable.insert (digest, name.toUri(), true);
|
||||
if (exists) // somebody else replied, so restart random-game timer
|
||||
{
|
||||
_LOG_DEBUG_ID("Unknown digest, but somebody may have already replied, " <<
|
||||
"so restart our timer");
|
||||
m_scheduler.cancelEvent (m_delayedInterestProcessingId);
|
||||
}
|
||||
|
||||
uint32_t waitDelay = GET_RANDOM (m_rangeUniformRandom);
|
||||
_LOG_DEBUG_ID("Digest is not in the log. Schedule processing after small delay: " <<
|
||||
ndn::time::milliseconds (waitDelay));
|
||||
|
||||
m_delayedInterestProcessingId =
|
||||
m_scheduler.scheduleEvent(ndn::time::milliseconds (waitDelay),
|
||||
bind (&SyncLogic::processSyncInterest, this, name, digest, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
_LOG_DEBUG_ID(" (timed processing)");
|
||||
|
||||
m_recoveryRetransmissionInterval = m_defaultRecoveryRetransmitInterval;
|
||||
sendSyncRecoveryInterests (digest);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::processSyncData (const Name &name, DigestConstPtr digest,
|
||||
const char *wireData, size_t len)
|
||||
{
|
||||
DiffStatePtr diffLog = make_shared<DiffState> ();
|
||||
bool ownInterestSatisfied = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
m_syncInterestTable.remove (name.toUri()); // Remove satisfied interest from PIT
|
||||
|
||||
ownInterestSatisfied = (name == m_outstandingInterestName);
|
||||
|
||||
DiffState diff;
|
||||
SyncStateMsg msg;
|
||||
if (!msg.ParseFromArray(wireData, len) || !msg.IsInitialized())
|
||||
{
|
||||
//Throw
|
||||
BOOST_THROW_EXCEPTION (Error::SyncStateMsgDecodingFailure () );
|
||||
}
|
||||
msg >> diff;
|
||||
|
||||
vector<MissingDataInfo> v;
|
||||
BOOST_FOREACH (LeafConstPtr leaf, diff.getLeaves().get<ordered>())
|
||||
{
|
||||
DiffLeafConstPtr diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
|
||||
BOOST_ASSERT (diffLeaf != 0);
|
||||
|
||||
NameInfoConstPtr info = diffLeaf->getInfo();
|
||||
if (diffLeaf->getOperation() == UPDATE)
|
||||
{
|
||||
SeqNo seq = diffLeaf->getSeq();
|
||||
|
||||
bool inserted = false;
|
||||
bool updated = false;
|
||||
SeqNo oldSeq;
|
||||
{
|
||||
tie (inserted, updated, oldSeq) = m_state->update (info, seq);
|
||||
}
|
||||
|
||||
if (inserted || updated)
|
||||
{
|
||||
diffLog->update (info, seq);
|
||||
if (!oldSeq.isValid())
|
||||
{
|
||||
oldSeq = SeqNo(seq.getSession(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
++oldSeq;
|
||||
}
|
||||
// there is no need for application to process update on forwarder node
|
||||
if (info->toString() != forwarderPrefix)
|
||||
{
|
||||
MissingDataInfo mdi = {info->toString(), oldSeq, seq};
|
||||
{
|
||||
ostringstream interestName;
|
||||
interestName << mdi.prefix <<
|
||||
"/" << mdi.high.getSession() <<
|
||||
"/" << mdi.high.getSeq();
|
||||
_LOG_DEBUG_ID("+++++++++++++++ " + interestName.str());
|
||||
}
|
||||
if (m_perBranch)
|
||||
{
|
||||
ostringstream interestName;
|
||||
interestName << mdi.prefix <<
|
||||
"/" << mdi.high.getSession() <<
|
||||
"/" << mdi.high.getSeq();
|
||||
m_onUpdateBranch(interestName.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
v.push_back(mdi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (diffLeaf->getOperation() == REMOVE)
|
||||
{
|
||||
if (m_state->remove (info))
|
||||
{
|
||||
diffLog->remove (info);
|
||||
if (!m_perBranch)
|
||||
{
|
||||
m_onRemove (info->toString ());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (!v.empty())
|
||||
{
|
||||
if (!m_perBranch)
|
||||
{
|
||||
m_onUpdate(v);
|
||||
}
|
||||
}
|
||||
|
||||
insertToDiffLog (diffLog);
|
||||
}
|
||||
catch (Error::SyncStateMsgDecodingFailure &e)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Something really fishy happened during state decoding " <<
|
||||
diagnostic_information (e));
|
||||
diffLog.reset ();
|
||||
// don't do anything
|
||||
}
|
||||
|
||||
if ((diffLog != 0 && diffLog->getLeaves ().size () > 0) ||
|
||||
ownInterestSatisfied)
|
||||
{
|
||||
_LOG_DEBUG_ID(" +++++++++++++++ state changed!!!");
|
||||
// Do it only if everything went fine and state changed
|
||||
|
||||
// this is kind of wrong
|
||||
// satisfyPendingSyncInterests (diffLog); // if there are interests in PIT,
|
||||
// // there is a point to satisfy them using new state
|
||||
|
||||
// if state has changed, then it is safe to express a new interest
|
||||
ndn::time::system_clock::Duration after =
|
||||
ndn::time::milliseconds(GET_RANDOM (m_reexpressionJitter));
|
||||
// cout << "------------ reexpress interest after: " << after << endl;
|
||||
EventId eventId = m_scheduler.scheduleEvent (after,
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_reexpressingInterestId = eventId;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::processSyncRecoveryInterest (const Name &name, DigestConstPtr digest)
|
||||
{
|
||||
_LOG_DEBUG_ID("processSyncRecoveryInterest");
|
||||
DiffStateContainer::iterator stateInDiffLog = m_log.find (digest);
|
||||
|
||||
if (stateInDiffLog == m_log.end ())
|
||||
{
|
||||
_LOG_DEBUG_ID ("Could not find " << *digest << " in digest log");
|
||||
return;
|
||||
}
|
||||
|
||||
SyncStateMsg ssm;
|
||||
{
|
||||
ssm << (*m_state);
|
||||
}
|
||||
sendSyncData (name, digest, ssm);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::satisfyPendingSyncInterests (DiffStateConstPtr diffLog)
|
||||
{
|
||||
DiffStatePtr fullStateLog = make_shared<DiffState> ();
|
||||
{
|
||||
BOOST_FOREACH (LeafConstPtr leaf, m_state->getLeaves ()/*.get<timed> ()*/)
|
||||
{
|
||||
fullStateLog->update (leaf->getInfo (), leaf->getSeq ());
|
||||
/// @todo Impose limit on how many state info should be send out
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint32_t counter = 0;
|
||||
while (m_syncInterestTable.size () > 0)
|
||||
{
|
||||
Sync::Interest interest = m_syncInterestTable.pop ();
|
||||
|
||||
if (!interest.m_unknown)
|
||||
{
|
||||
_LOG_DEBUG_ID (">> D " << interest.m_name);
|
||||
sendSyncData (interest.m_name, interest.m_digest, diffLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
_LOG_DEBUG_ID (">> D (unknown)" << interest.m_name);
|
||||
sendSyncData (interest.m_name, interest.m_digest, fullStateLog);
|
||||
}
|
||||
counter ++;
|
||||
}
|
||||
_LOG_DEBUG_ID ("Satisfied " << counter << " pending interests");
|
||||
}
|
||||
catch (Error::InterestTableIsEmpty &e)
|
||||
{
|
||||
// ok. not really an error
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::insertToDiffLog (DiffStatePtr diffLog)
|
||||
{
|
||||
diffLog->setDigest (m_state->getDigest());
|
||||
if (m_log.size () > 0)
|
||||
{
|
||||
m_log.get<sequenced> ().front ()->setNext (diffLog);
|
||||
}
|
||||
m_log.erase (m_state->getDigest()); // remove diff state with the same digest.
|
||||
// next pointers are still valid
|
||||
/// @todo Optimization
|
||||
m_log.get<sequenced> ().push_front (diffLog);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::addLocalNames (const Name &prefix, uint64_t session, uint64_t seq)
|
||||
{
|
||||
DiffStatePtr diff;
|
||||
{
|
||||
//cout << "Add local names" <<endl;
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
|
||||
|
||||
_LOG_DEBUG_ID ("addLocalNames (): old state " << *m_state->getDigest ());
|
||||
|
||||
SeqNo seqN (session, seq);
|
||||
m_state->update(info, seqN);
|
||||
|
||||
_LOG_DEBUG_ID ("addLocalNames (): new state " << *m_state->getDigest ());
|
||||
|
||||
diff = make_shared<DiffState>();
|
||||
diff->update(info, seqN);
|
||||
insertToDiffLog (diff);
|
||||
}
|
||||
|
||||
// _LOG_DEBUG_ID ("PIT size: " << m_syncInterestTable.size ());
|
||||
satisfyPendingSyncInterests (diff);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::remove(const Name &prefix)
|
||||
{
|
||||
DiffStatePtr diff;
|
||||
{
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate(prefix.toUri());
|
||||
m_state->remove(info);
|
||||
|
||||
// increment the sequence number for the forwarder node
|
||||
NameInfoConstPtr forwarderInfo = StdNameInfo::FindOrCreate(forwarderPrefix);
|
||||
|
||||
LeafContainer::iterator item = m_state->getLeaves ().find (forwarderInfo);
|
||||
SeqNo seqNo (0);
|
||||
if (item != m_state->getLeaves ().end ())
|
||||
{
|
||||
seqNo = (*item)->getSeq ();
|
||||
++seqNo;
|
||||
}
|
||||
m_state->update (forwarderInfo, seqNo);
|
||||
|
||||
diff = make_shared<DiffState>();
|
||||
diff->remove(info);
|
||||
diff->update(forwarderInfo, seqNo);
|
||||
|
||||
insertToDiffLog (diff);
|
||||
}
|
||||
|
||||
satisfyPendingSyncInterests (diff);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::sendSyncInterest ()
|
||||
{
|
||||
_LOG_DEBUG_ID("sendSyncInterest");
|
||||
|
||||
{
|
||||
m_outstandingInterestName = m_syncPrefix;
|
||||
ostringstream os;
|
||||
os << *m_state->getDigest();
|
||||
m_outstandingInterestName.append(os.str());
|
||||
_LOG_DEBUG_ID (">> I " << m_outstandingInterestName);
|
||||
}
|
||||
|
||||
_LOG_DEBUG_ID("sendSyncInterest: " << m_outstandingInterestName);
|
||||
|
||||
EventId eventId =
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(m_syncInterestReexpress) +
|
||||
ndn::time::milliseconds(GET_RANDOM(m_reexpressionJitter)),
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_reexpressingInterestId = eventId;
|
||||
|
||||
ndn::Interest interest(m_outstandingInterestName);
|
||||
interest.setMustBeFresh(true);
|
||||
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncLogic::onSyncData, this, _1, _2),
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1), // Nack
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::sendSyncRecoveryInterests (DigestConstPtr digest)
|
||||
{
|
||||
ostringstream os;
|
||||
os << *digest;
|
||||
|
||||
Name interestName = m_syncPrefix;
|
||||
interestName.append("recovery").append(os.str());
|
||||
|
||||
ndn::time::system_clock::Duration nextRetransmission =
|
||||
ndn::time::milliseconds(m_recoveryRetransmissionInterval + GET_RANDOM (m_reexpressionJitter));
|
||||
|
||||
m_recoveryRetransmissionInterval <<= 1;
|
||||
|
||||
m_scheduler.cancelEvent (m_reexpressingRecoveryInterestId);
|
||||
if (m_recoveryRetransmissionInterval < 100*1000) // <100 seconds
|
||||
m_reexpressingRecoveryInterestId =
|
||||
m_scheduler.scheduleEvent (nextRetransmission,
|
||||
bind (&SyncLogic::sendSyncRecoveryInterests, this, digest));
|
||||
|
||||
ndn::Interest interest(interestName);
|
||||
interest.setMustBeFresh(true);
|
||||
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncLogic::onSyncData, this, _1, _2),
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1), // Nack
|
||||
bind(&SyncLogic::onSyncTimeout, this, _1));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, StateConstPtr state)
|
||||
{
|
||||
SyncStateMsg msg;
|
||||
msg << (*state);
|
||||
sendSyncData(name, digest, msg);
|
||||
}
|
||||
|
||||
// pass in state msg instead of state, so that there is no need to lock the state until
|
||||
// this function returns
|
||||
void
|
||||
SyncLogic::sendSyncData (const Name &name, DigestConstPtr digest, SyncStateMsg &ssm)
|
||||
{
|
||||
_LOG_DEBUG_ID (">> D " << name);
|
||||
int size = ssm.ByteSize();
|
||||
char *wireData = new char[size];
|
||||
ssm.SerializeToArray(wireData, size);
|
||||
|
||||
//Data syncData(name);
|
||||
ndn::shared_ptr<ndn::Data> syncData = ndn::make_shared<ndn::Data>();
|
||||
syncData->setName(name);
|
||||
syncData->setContent(reinterpret_cast<const uint8_t*>(wireData), size);
|
||||
syncData->setFreshnessPeriod(ndn::time::seconds(m_syncResponseFreshness));
|
||||
|
||||
m_keyChain->sign(*syncData);
|
||||
|
||||
m_face->put(*syncData);
|
||||
|
||||
delete []wireData;
|
||||
|
||||
// checking if our own interest got satisfied
|
||||
bool satisfiedOwnInterest = false;
|
||||
{
|
||||
satisfiedOwnInterest = (m_outstandingInterestName == name);
|
||||
}
|
||||
|
||||
if (satisfiedOwnInterest)
|
||||
{
|
||||
_LOG_DEBUG_ID ("Satisfied our own Interest. Re-expressing (hopefully with a new digest)");
|
||||
|
||||
ndn::time::system_clock::Duration after =
|
||||
ndn::time::milliseconds(GET_RANDOM(m_reexpressionJitter));
|
||||
// cout << "------------ reexpress interest after: " << after << endl;
|
||||
EventId eventId = m_scheduler.scheduleEvent (after,
|
||||
bind (&SyncLogic::sendSyncInterest, this));
|
||||
m_scheduler.cancelEvent (m_reexpressingInterestId);
|
||||
m_reexpressingInterestId = eventId;
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
SyncLogic::getRootDigest()
|
||||
{
|
||||
ostringstream os;
|
||||
os << *m_state->getDigest();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
size_t
|
||||
SyncLogic::getNumberOfBranches () const
|
||||
{
|
||||
return m_state->getLeaves ().size ();
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogic::printState () const
|
||||
{
|
||||
BOOST_FOREACH (const shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
|
||||
{
|
||||
std::cout << *leaf << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, bool>
|
||||
SyncLogic::getBranchPrefixes() const
|
||||
{
|
||||
std::map<std::string, bool> m;
|
||||
|
||||
BOOST_FOREACH (const shared_ptr<Sync::Leaf> leaf, m_state->getLeaves ())
|
||||
{
|
||||
std::string prefix = leaf->getInfo()->toString();
|
||||
// do not return forwarder prefix
|
||||
if (prefix != forwarderPrefix)
|
||||
{
|
||||
m.insert(pair<std::string, bool>(prefix, false));
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
* Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_LOGIC_H
|
||||
#define 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 // SYNC_APP_WRAPPER_H
|
||||
@@ -1,32 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-name-info.h"
|
||||
|
||||
// #include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace Sync {
|
||||
|
||||
NameInfo::NameMap NameInfo::m_names;
|
||||
size_t NameInfo::m_ids = 0;
|
||||
|
||||
} // Sync
|
||||
@@ -1,102 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_NAME_INFO_H
|
||||
#define 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 // SYNC_NAME_INFO_H
|
||||
@@ -1,36 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-seq-no.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
DigestConstPtr
|
||||
SeqNo::getDigest () const
|
||||
{
|
||||
DigestPtr digest = make_shared<Digest> ();
|
||||
*digest << m_session << m_seq;
|
||||
digest->finalize ();
|
||||
return digest;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,198 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
* Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_SEQ_NO_H
|
||||
#define 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 // SYNC_SEQ_NO_H
|
||||
@@ -1,184 +0,0 @@
|
||||
/* -*- Mode: C32++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-socket.h"
|
||||
#include "sync-logging.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using ndn::Data;
|
||||
using ndn::Face;
|
||||
using ndn::KeyChain;
|
||||
using ndn::Name;
|
||||
using ndn::OnDataValidated;
|
||||
using ndn::OnDataValidationFailed;
|
||||
using ndn::Validator;
|
||||
|
||||
INIT_LOGGER ("SyncSocket");
|
||||
|
||||
namespace Sync {
|
||||
|
||||
using ndn::shared_ptr;
|
||||
using ndn::make_shared;
|
||||
|
||||
SyncSocket::SyncSocket (const Name &syncPrefix,
|
||||
shared_ptr<Validator> validator,
|
||||
shared_ptr<Face> face,
|
||||
NewDataCallback dataCallback,
|
||||
RemoveCallback rmCallback )
|
||||
: m_newDataCallback(dataCallback)
|
||||
, m_validator(validator)
|
||||
, m_keyChain(new KeyChain())
|
||||
, m_face(face)
|
||||
, m_syncLogic (syncPrefix,
|
||||
validator,
|
||||
face,
|
||||
bind(&SyncSocket::passCallback, this, _1),
|
||||
rmCallback)
|
||||
{
|
||||
}
|
||||
|
||||
SyncSocket::~SyncSocket()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
SyncSocket::publishData(const Name &prefix, uint64_t session,
|
||||
const char *buf, size_t len,
|
||||
int freshness,uint64_t seq)
|
||||
{
|
||||
shared_ptr<Data> data = make_shared<Data>();
|
||||
data->setContent(reinterpret_cast<const uint8_t*>(buf), len);
|
||||
data->setFreshnessPeriod(ndn::time::seconds(freshness));
|
||||
|
||||
m_face->getIoService().post(bind(&SyncSocket::publishDataInternal, this,
|
||||
data, prefix, session,seq));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::publishDataInternal(shared_ptr<Data> data,
|
||||
const Name &prefix, uint64_t session, uint64_t seq)
|
||||
{
|
||||
uint64_t sequence = seq;
|
||||
Name dataName = prefix;
|
||||
dataName.append(boost::lexical_cast<string>(session))
|
||||
.append(boost::lexical_cast<string>(sequence));
|
||||
data->setName(dataName);
|
||||
|
||||
m_keyChain->sign(*data);
|
||||
m_face->put(*data);
|
||||
|
||||
SeqNo s(session, sequence + 1);
|
||||
|
||||
m_sequenceLog[prefix] = s;
|
||||
m_syncLogic.addLocalNames (prefix, session, sequence);
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::fetchData(const Name &prefix, const SeqNo &seq,
|
||||
const OnDataValidated& onValidated, int retry)
|
||||
{
|
||||
Name interestName = prefix;
|
||||
interestName.append(boost::lexical_cast<string>(seq.getSession()))
|
||||
.append(boost::lexical_cast<string>(seq.getSeq()));
|
||||
|
||||
const OnDataValidationFailed& onValidationFailed =
|
||||
bind(&SyncSocket::onDataValidationFailed, this, _1);
|
||||
|
||||
ndn::Interest interest(interestName);
|
||||
interest.setMustBeFresh(true);
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncSocket::onData, this, _1, _2,
|
||||
onValidated, onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout, this, _1, retry, // Nack
|
||||
onValidated, onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout, this, _1, retry,
|
||||
onValidated, onValidationFailed));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::onData(const ndn::Interest& interest, const Data& data,
|
||||
const OnDataValidated& onValidated,
|
||||
const OnDataValidationFailed& onValidationFailed)
|
||||
{
|
||||
m_validator->validate(data, onValidated, onValidationFailed);
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::onDataTimeout(const ndn::Interest& interest,
|
||||
int retry,
|
||||
const OnDataValidated& onValidated,
|
||||
const OnDataValidationFailed& onValidationFailed)
|
||||
{
|
||||
if(retry > 0)
|
||||
{
|
||||
m_face->expressInterest(interest,
|
||||
bind(&SyncSocket::onData,
|
||||
this,
|
||||
_1,
|
||||
_2,
|
||||
onValidated,
|
||||
onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout,
|
||||
this,
|
||||
_1,
|
||||
retry - 1,
|
||||
onValidated,
|
||||
onValidationFailed),
|
||||
bind(&SyncSocket::onDataTimeout,
|
||||
this,
|
||||
_1,
|
||||
retry - 1,
|
||||
onValidated,
|
||||
onValidationFailed));
|
||||
|
||||
}
|
||||
else
|
||||
_LOG_DEBUG("interest eventually time out!");
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::onDataValidationFailed(const shared_ptr<const Data>& data)
|
||||
{
|
||||
_LOG_DEBUG("data cannot be verified!");
|
||||
}
|
||||
|
||||
|
||||
uint64_t
|
||||
SyncSocket::getNextSeq (const Name &prefix, uint64_t session)
|
||||
{
|
||||
SequenceLog::iterator i = m_sequenceLog.find (prefix);
|
||||
|
||||
if (i != m_sequenceLog.end ())
|
||||
{
|
||||
SeqNo s = i->second;
|
||||
if (s.getSession() == session)
|
||||
return s.getSeq();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}//Sync
|
||||
@@ -1,134 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef _SYNC_SOCKET_H
|
||||
#define _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 // SYNC_SOCKET_H
|
||||
@@ -1,101 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_STATE_LEAF_CONTAINER
|
||||
#define SYNC_STATE_LEAF_CONTAINER
|
||||
|
||||
#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 // SYNC_STATE_LEAF_CONTAINER
|
||||
@@ -1,169 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-state.h"
|
||||
#include "sync-diff-leaf.h"
|
||||
#include "sync-std-name-info.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
typedef boost::error_info<struct tag_errmsg, std::string> info_str;
|
||||
|
||||
using namespace Sync::Error;
|
||||
using boost::lexical_cast;
|
||||
|
||||
namespace Sync {
|
||||
|
||||
/*
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const State &state)
|
||||
{
|
||||
os << "<state>"; DEBUG_ENDL;
|
||||
|
||||
BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
|
||||
{
|
||||
shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
|
||||
if (diffLeaf != 0)
|
||||
{
|
||||
os << "<item action=\"" << diffLeaf->getOperation () << "\">"; DEBUG_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "<item>"; DEBUG_ENDL;
|
||||
}
|
||||
os << "<name>" << *leaf->getInfo () << "</name>"; DEBUG_ENDL;
|
||||
if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
|
||||
{
|
||||
os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
|
||||
}
|
||||
os << "</item>"; DEBUG_ENDL;
|
||||
}
|
||||
os << "</state>";
|
||||
}
|
||||
*/
|
||||
|
||||
SyncStateMsg &
|
||||
operator << (SyncStateMsg &ossm, const State &state)
|
||||
{
|
||||
BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
|
||||
{
|
||||
SyncState *oss = ossm.add_ss();
|
||||
shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
|
||||
if (diffLeaf != 0 && diffLeaf->getOperation() != UPDATE)
|
||||
{
|
||||
oss->set_type(SyncState::DELETE);
|
||||
}
|
||||
else
|
||||
{
|
||||
oss->set_type(SyncState::UPDATE);
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os << *leaf->getInfo();
|
||||
oss->set_name(os.str());
|
||||
|
||||
if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
|
||||
{
|
||||
SyncState::SeqNo *seqNo = oss->mutable_seqno();
|
||||
seqNo->set_session(leaf->getSeq().getSession());
|
||||
seqNo->set_seq(leaf->getSeq().getSeq());
|
||||
}
|
||||
}
|
||||
return ossm;
|
||||
}
|
||||
|
||||
/*
|
||||
std::istream &
|
||||
operator >> (std::istream &in, State &state)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
in >> doc;
|
||||
|
||||
if (doc.RootElement() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("Empty XML"));
|
||||
|
||||
for (TiXmlElement *iterator = doc.RootElement()->FirstChildElement ("item");
|
||||
iterator != 0;
|
||||
iterator = iterator->NextSiblingElement("item"))
|
||||
{
|
||||
TiXmlElement *name = iterator->FirstChildElement ("name");
|
||||
if (name == 0 || name->GetText() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<name> element is missing"));
|
||||
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate (name->GetText());
|
||||
|
||||
if (iterator->Attribute("action") == 0 || strcmp(iterator->Attribute("action"), "update") == 0)
|
||||
{
|
||||
TiXmlElement *seq = iterator->FirstChildElement ("seq");
|
||||
if (seq == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seq> element is missing"));
|
||||
|
||||
TiXmlElement *session = seq->FirstChildElement ("session");
|
||||
TiXmlElement *seqno = seq->FirstChildElement ("seqno");
|
||||
|
||||
if (session == 0 || session->GetText() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<session> element is missing"));
|
||||
if (seqno == 0 || seqno->GetText() == 0)
|
||||
BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seqno> element is missing"));
|
||||
|
||||
state.update (info, SeqNo (
|
||||
lexical_cast<uint32_t> (session->GetText()),
|
||||
lexical_cast<uint32_t> (seqno->GetText())
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
state.remove (info);
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
*/
|
||||
|
||||
SyncStateMsg &
|
||||
operator >> (SyncStateMsg &issm, State &state)
|
||||
{
|
||||
int n = issm.ss_size();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
const SyncState &ss = issm.ss(i);
|
||||
NameInfoConstPtr info = StdNameInfo::FindOrCreate (ss.name());
|
||||
if (ss.type() == SyncState::UPDATE)
|
||||
{
|
||||
uint64_t session = lexical_cast<uint64_t>(ss.seqno().session());
|
||||
uint64_t seq = lexical_cast<uint64_t>(ss.seqno().seq());
|
||||
SeqNo seqNo(session, seq);
|
||||
state.update(info, seqNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.remove(info);
|
||||
}
|
||||
}
|
||||
return issm;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_STATE_H
|
||||
#define 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 // SYNC_STATE_H
|
||||
@@ -1,24 +0,0 @@
|
||||
package Sync;
|
||||
|
||||
message SyncState
|
||||
{
|
||||
required string name = 1;
|
||||
enum ActionType
|
||||
{
|
||||
UPDATE = 0;
|
||||
DELETE = 1;
|
||||
OTHER = 2;
|
||||
}
|
||||
required ActionType type = 2;
|
||||
message SeqNo
|
||||
{
|
||||
required uint64 seq = 1;
|
||||
required uint64 session = 2;
|
||||
}
|
||||
optional SeqNo seqno = 3;
|
||||
}
|
||||
|
||||
message SyncStateMsg
|
||||
{
|
||||
repeated SyncState ss = 1;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#include "sync-std-name-info.h"
|
||||
|
||||
namespace Sync {
|
||||
|
||||
|
||||
NameInfoConstPtr
|
||||
StdNameInfo::FindOrCreate (const std::string &key)
|
||||
{
|
||||
// std::cout << "FindOrCreate: " << m_names.size () << "\n";
|
||||
|
||||
NameInfoConstPtr ret;
|
||||
|
||||
NameMap::iterator item = m_names.find (key);
|
||||
if (item != m_names.end ())
|
||||
{
|
||||
ret = item->second.lock ();
|
||||
BOOST_ASSERT (ret != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NameInfoPtr (new StdNameInfo (key));
|
||||
weak_ptr<const NameInfo> value (ret);
|
||||
std::pair<NameMap::iterator,bool> inserted =
|
||||
m_names.insert (make_pair (key, value));
|
||||
|
||||
BOOST_ASSERT (inserted.second); // previous call has to insert value
|
||||
item = inserted.first;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
StdNameInfo::StdNameInfo (const std::string &name)
|
||||
: m_name (name)
|
||||
{
|
||||
m_id = m_ids ++; // set ID for a newly inserted element
|
||||
m_digest << name;
|
||||
m_digest.finalize ();
|
||||
|
||||
// std::cout << "StdNameInfo: " << name << " = " << m_id << "\n";
|
||||
}
|
||||
|
||||
StdNameInfo::~StdNameInfo ()
|
||||
{
|
||||
// cout << "Destructor for " << m_name << "\n";
|
||||
m_names.erase (toString ());
|
||||
}
|
||||
|
||||
std::string
|
||||
StdNameInfo::toString () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
bool
|
||||
StdNameInfo::operator == (const NameInfo &info) const
|
||||
{
|
||||
return m_name == dynamic_cast<const StdNameInfo&> (info).m_name;
|
||||
}
|
||||
|
||||
bool
|
||||
StdNameInfo::operator < (const NameInfo &info) const
|
||||
{
|
||||
return m_name < dynamic_cast<const StdNameInfo&> (info).m_name;
|
||||
}
|
||||
|
||||
} // Sync
|
||||
@@ -1,74 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012 University of California, Los Angeles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
|
||||
* Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef SYNC_STD_NAME_INFO_H
|
||||
#define 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 // SYNC_CCNX_NAME_INFO_H
|
||||
+54
-80
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -29,9 +29,7 @@
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("AdjacencyList");
|
||||
|
||||
using namespace std;
|
||||
INIT_LOGGER(AdjacencyList);
|
||||
|
||||
AdjacencyList::AdjacencyList()
|
||||
{
|
||||
@@ -61,20 +59,6 @@ AdjacencyList::addAdjacents(AdjacencyList& adl)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AdjacencyList::updateAdjacentStatus(const ndn::Name& adjName, Adjacent::Status s)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(adjName);
|
||||
|
||||
if (it == m_adjList.end()) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
it->setStatus(s);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Adjacent
|
||||
AdjacencyList::getAdjacent(const ndn::Name& adjName)
|
||||
{
|
||||
@@ -86,49 +70,23 @@ AdjacencyList::getAdjacent(const ndn::Name& adjName)
|
||||
return adj;
|
||||
}
|
||||
|
||||
static bool
|
||||
compareAdjacent(const Adjacent& adjacent1, const Adjacent& adjacent2)
|
||||
{
|
||||
return adjacent1.getName() < adjacent2.getName();
|
||||
}
|
||||
|
||||
bool
|
||||
AdjacencyList::operator==(AdjacencyList& adl)
|
||||
AdjacencyList::operator==(const AdjacencyList& adl) const
|
||||
{
|
||||
if (getSize() != adl.getSize()) {
|
||||
if (m_adjList.size() != adl.getAdjList().size()) {
|
||||
return false;
|
||||
}
|
||||
m_adjList.sort(compareAdjacent);
|
||||
adl.getAdjList().sort(compareAdjacent);
|
||||
uint32_t equalAdjCount = 0;
|
||||
std::list<Adjacent>& adjList2 = adl.getAdjList();
|
||||
std::list<Adjacent>::iterator it1;
|
||||
std::list<Adjacent>::iterator it2;
|
||||
for (it1 = m_adjList.begin(), it2 = adjList2.begin();
|
||||
it1 != m_adjList.end(); it1++, it2++) {
|
||||
if (!((*it1) == (*it2))) {
|
||||
break;
|
||||
}
|
||||
equalAdjCount++;
|
||||
}
|
||||
return equalAdjCount == getSize();
|
||||
}
|
||||
|
||||
int32_t
|
||||
AdjacencyList::updateAdjacentLinkCost(const ndn::Name& adjName, double lc)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(adjName);
|
||||
if (it == m_adjList.end()) {
|
||||
return -1;
|
||||
}
|
||||
(*it).setLinkCost(lc);
|
||||
return 0;
|
||||
std::set<Adjacent> ourList(m_adjList.cbegin(), m_adjList.cend());
|
||||
std::set<Adjacent> theirList(adl.getAdjList().cbegin(), adl.getAdjList().cend());
|
||||
|
||||
return ourList == theirList;
|
||||
}
|
||||
|
||||
bool
|
||||
AdjacencyList::isNeighbor(const ndn::Name& adjName)
|
||||
AdjacencyList::isNeighbor(const ndn::Name& adjName) const
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(adjName);
|
||||
std::list<Adjacent>::const_iterator it = find(adjName);
|
||||
if (it == m_adjList.end())
|
||||
{
|
||||
return false;
|
||||
@@ -157,9 +115,9 @@ AdjacencyList::setTimedOutInterestCount(const ndn::Name& neighbor,
|
||||
}
|
||||
|
||||
int32_t
|
||||
AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor)
|
||||
AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor) const
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(neighbor);
|
||||
std::list<Adjacent>::const_iterator it = find(neighbor);
|
||||
if (it == m_adjList.end()) {
|
||||
return -1;
|
||||
}
|
||||
@@ -167,9 +125,9 @@ AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor)
|
||||
}
|
||||
|
||||
Adjacent::Status
|
||||
AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor)
|
||||
AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor) const
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(neighbor);
|
||||
std::list<Adjacent>::const_iterator it = find(neighbor);
|
||||
|
||||
if (it == m_adjList.end()) {
|
||||
return Adjacent::STATUS_UNKNOWN;
|
||||
@@ -194,6 +152,12 @@ AdjacencyList::getAdjList()
|
||||
return m_adjList;
|
||||
}
|
||||
|
||||
const std::list<Adjacent>&
|
||||
AdjacencyList::getAdjList() const
|
||||
{
|
||||
return m_adjList;
|
||||
}
|
||||
|
||||
bool
|
||||
AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
|
||||
{
|
||||
@@ -218,10 +182,10 @@ AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
|
||||
}
|
||||
|
||||
int32_t
|
||||
AdjacencyList::getNumOfActiveNeighbor()
|
||||
AdjacencyList::getNumOfActiveNeighbor() const
|
||||
{
|
||||
int32_t actNbrCount = 0;
|
||||
for (std::list<Adjacent>::iterator it = m_adjList.begin(); it != m_adjList.end(); it++) {
|
||||
for (std::list<Adjacent>::const_iterator it = m_adjList.begin(); it != m_adjList.end(); it++) {
|
||||
|
||||
if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
actNbrCount++;
|
||||
@@ -240,36 +204,46 @@ AdjacencyList::find(const ndn::Name& adjName)
|
||||
return it;
|
||||
}
|
||||
|
||||
Adjacent *
|
||||
AdjacencyList::findAdjacent(const ndn::Name& adjName)
|
||||
std::list<Adjacent>::const_iterator
|
||||
AdjacencyList::find(const ndn::Name& adjName) const
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
if (it != m_adjList.end()) {
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
return 0;
|
||||
std::list<Adjacent>::const_iterator it = std::find_if(m_adjList.cbegin(),
|
||||
m_adjList.cend(),
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
return it;
|
||||
}
|
||||
|
||||
Adjacent *
|
||||
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(const ndn::Name& adjName)
|
||||
{
|
||||
return std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
}
|
||||
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(uint64_t faceId)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceId,
|
||||
_1, faceId));
|
||||
if (it != m_adjList.end()) {
|
||||
return &(*it);
|
||||
}
|
||||
return std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceId,
|
||||
_1, faceId));
|
||||
}
|
||||
|
||||
return 0;
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(const ndn::FaceUri& faceUri)
|
||||
{
|
||||
return std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceUri,
|
||||
_1, faceUri));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
AdjacencyList::getFaceId(const std::string& faceUri)
|
||||
AdjacencyList::getFaceId(const ndn::FaceUri& faceUri)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
@@ -285,7 +259,7 @@ AdjacencyList::getFaceId(const std::string& faceUri)
|
||||
void
|
||||
AdjacencyList::writeLog()
|
||||
{
|
||||
_LOG_DEBUG("-------Adjacency List--------");
|
||||
NLSR_LOG_DEBUG("-------Adjacency List--------");
|
||||
for (std::list<Adjacent>::iterator it = m_adjList.begin();
|
||||
it != m_adjList.end(); it++) {
|
||||
(*it).writeLog();
|
||||
|
||||
+37
-30
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -22,11 +22,11 @@
|
||||
#ifndef NLSR_ADJACENCY_LIST_HPP
|
||||
#define NLSR_ADJACENCY_LIST_HPP
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <ndn-cxx/common.hpp>
|
||||
|
||||
#include "adjacent.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
@@ -52,35 +52,23 @@ public:
|
||||
int32_t
|
||||
insert(Adjacent& adjacent);
|
||||
|
||||
/*! \brief Sets the status of an adjacency.
|
||||
|
||||
\param adjName The adjacency in this list you want to change the status of.
|
||||
|
||||
\param s The status to change to.
|
||||
|
||||
\return A boolean indicating whether an adjacency was
|
||||
updated. This is false if s is not in the list.
|
||||
*/
|
||||
bool
|
||||
updateAdjacentStatus(const ndn::Name& adjName, Adjacent::Status s);
|
||||
|
||||
int32_t
|
||||
updateAdjacentLinkCost(const ndn::Name& adjName, double lc);
|
||||
|
||||
std::list<Adjacent>&
|
||||
getAdjList();
|
||||
|
||||
const std::list<Adjacent>&
|
||||
getAdjList() const;
|
||||
|
||||
bool
|
||||
isNeighbor(const ndn::Name& adjName);
|
||||
isNeighbor(const ndn::Name& adjName) const;
|
||||
|
||||
void
|
||||
incrementTimedOutInterestCount(const ndn::Name& neighbor);
|
||||
|
||||
int32_t
|
||||
getTimedOutInterestCount(const ndn::Name& neighbor);
|
||||
getTimedOutInterestCount(const ndn::Name& neighbor) const;
|
||||
|
||||
Adjacent::Status
|
||||
getStatusOfNeighbor(const ndn::Name& neighbor);
|
||||
getStatusOfNeighbor(const ndn::Name& neighbor) const;
|
||||
|
||||
void
|
||||
setStatusOfNeighbor(const ndn::Name& neighbor, Adjacent::Status status);
|
||||
@@ -117,16 +105,16 @@ public:
|
||||
isAdjLsaBuildable(const uint32_t interestRetryNo) const;
|
||||
|
||||
int32_t
|
||||
getNumOfActiveNeighbor();
|
||||
getNumOfActiveNeighbor() const;
|
||||
|
||||
Adjacent
|
||||
getAdjacent(const ndn::Name& adjName);
|
||||
|
||||
bool
|
||||
operator==(AdjacencyList& adl);
|
||||
operator==(const AdjacencyList& adl) const;
|
||||
|
||||
size_t
|
||||
getSize()
|
||||
size() const
|
||||
{
|
||||
return m_adjList.size();
|
||||
}
|
||||
@@ -139,14 +127,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Adjacent*
|
||||
AdjacencyList::iterator
|
||||
findAdjacent(const ndn::Name& adjName);
|
||||
|
||||
Adjacent*
|
||||
AdjacencyList::iterator
|
||||
findAdjacent(uint64_t faceId);
|
||||
|
||||
AdjacencyList::iterator
|
||||
findAdjacent(const ndn::FaceUri& faceUri);
|
||||
|
||||
/*! \brief Hack to stop developers from using this function
|
||||
|
||||
It is here so that faceUri cannot be passed in as string,
|
||||
converted to Name and findAdjacent(Name) be used.
|
||||
So when faceUri is passed as string this will cause a compile error
|
||||
*/
|
||||
template <typename T = float> void
|
||||
findAdjacent(const std::string& faceUri)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(std::is_integral<T>::value,
|
||||
"Don't use std::string with findAdjacent!");
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getFaceId(const std::string& faceUri);
|
||||
getFaceId(const ndn::FaceUri& faceUri);
|
||||
|
||||
void
|
||||
writeLog();
|
||||
@@ -168,9 +172,12 @@ private:
|
||||
iterator
|
||||
find(const ndn::Name& adjName);
|
||||
|
||||
const_iterator
|
||||
find(const ndn::Name& adjName) const;
|
||||
|
||||
private:
|
||||
std::list<Adjacent> m_adjList;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
#endif //NLSR_ADJACENCY_LIST_HPP
|
||||
#endif // NLSR_ADJACENCY_LIST_HPP
|
||||
+29
-23
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,30 +16,25 @@
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
**/
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("Adjacent");
|
||||
|
||||
using namespace std;
|
||||
INIT_LOGGER(Adjacent);
|
||||
|
||||
const float Adjacent::DEFAULT_LINK_COST = 10.0;
|
||||
|
||||
Adjacent::Adjacent()
|
||||
: m_name()
|
||||
, m_connectingFaceUri()
|
||||
, m_faceUri()
|
||||
, m_linkCost(DEFAULT_LINK_COST)
|
||||
, m_status(STATUS_INACTIVE)
|
||||
, m_interestTimedOutNo(0)
|
||||
@@ -49,7 +44,7 @@ Adjacent::Adjacent()
|
||||
|
||||
Adjacent::Adjacent(const ndn::Name& an)
|
||||
: m_name(an)
|
||||
, m_connectingFaceUri()
|
||||
, m_faceUri()
|
||||
, m_linkCost(DEFAULT_LINK_COST)
|
||||
, m_status(STATUS_INACTIVE)
|
||||
, m_interestTimedOutNo(0)
|
||||
@@ -57,35 +52,46 @@ Adjacent::Adjacent(const ndn::Name& an)
|
||||
{
|
||||
}
|
||||
|
||||
Adjacent::Adjacent(const ndn::Name& an, const std::string& cfu, double lc,
|
||||
Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
|
||||
Status s, uint32_t iton, uint64_t faceId)
|
||||
: m_name(an)
|
||||
, m_connectingFaceUri(cfu)
|
||||
, m_faceUri(faceUri)
|
||||
, m_linkCost(lc)
|
||||
, m_status(s)
|
||||
, m_interestTimedOutNo(iton)
|
||||
, m_faceId(faceId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
Adjacent::operator==(const Adjacent& adjacent) const
|
||||
{
|
||||
return (m_name == adjacent.getName()) &&
|
||||
(m_connectingFaceUri == adjacent.getConnectingFaceUri()) &&
|
||||
(m_faceUri == adjacent.getFaceUri()) &&
|
||||
(std::abs(m_linkCost - adjacent.getLinkCost()) <
|
||||
std::numeric_limits<double>::epsilon()) ;
|
||||
std::numeric_limits<double>::epsilon());
|
||||
}
|
||||
|
||||
bool
|
||||
Adjacent::operator<(const Adjacent& adjacent) const
|
||||
{
|
||||
return (m_name < adjacent.getName()) ||
|
||||
(m_linkCost < adjacent.getLinkCost());
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Adjacent& adjacent)
|
||||
{
|
||||
os << "Adjacent: " << adjacent.m_name << "\n Connecting FaceUri: " << adjacent.m_faceUri
|
||||
<< "\n Link cost: " << adjacent.m_linkCost << "\n Status: " << adjacent.m_status
|
||||
<< "\n Interest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
void
|
||||
Adjacent::writeLog()
|
||||
{
|
||||
_LOG_DEBUG("Adjacent : " << m_name);
|
||||
_LOG_DEBUG("Connecting FaceUri: " << m_connectingFaceUri);
|
||||
_LOG_DEBUG("Link Cost: " << m_linkCost);
|
||||
_LOG_DEBUG("Status: " << m_status);
|
||||
_LOG_DEBUG("Interest Timed out: " << m_interestTimedOutNo);
|
||||
NLSR_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+45
-17
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,20 +16,25 @@
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
**/
|
||||
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/net/face-uri.hpp>
|
||||
|
||||
#ifndef NLSR_ADJACENT_HPP
|
||||
#define NLSR_ADJACENT_HPP
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*! \brief A neighbor reachable over a Face.
|
||||
*
|
||||
* Represents another node that we expect to be running NLSR that we
|
||||
* should be able to reach over a direct Face connection.
|
||||
*/
|
||||
class Adjacent
|
||||
{
|
||||
|
||||
@@ -45,7 +50,7 @@ public:
|
||||
|
||||
Adjacent(const ndn::Name& an);
|
||||
|
||||
Adjacent(const ndn::Name& an, const std::string& cfu, double lc,
|
||||
Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
|
||||
Status s, uint32_t iton, uint64_t faceId);
|
||||
|
||||
const ndn::Name&
|
||||
@@ -60,16 +65,16 @@ public:
|
||||
m_name = an;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getConnectingFaceUri() const
|
||||
const ndn::FaceUri&
|
||||
getFaceUri() const
|
||||
{
|
||||
return m_connectingFaceUri;
|
||||
return m_faceUri;
|
||||
}
|
||||
|
||||
void
|
||||
setConnectingFaceUri(const std::string& cfu)
|
||||
setFaceUri(const ndn::FaceUri& faceUri)
|
||||
{
|
||||
m_connectingFaceUri = cfu;
|
||||
m_faceUri = faceUri;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
@@ -116,30 +121,40 @@ public:
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getFaceId()
|
||||
getFaceId() const
|
||||
{
|
||||
return m_faceId;
|
||||
}
|
||||
|
||||
/*! \brief Equality is when name, Face URI, and link cost are all equal. */
|
||||
bool
|
||||
operator==(const Adjacent& adjacent) const;
|
||||
|
||||
bool
|
||||
operator!=(const Adjacent& adjacent) const
|
||||
{
|
||||
return !(*this == adjacent);
|
||||
}
|
||||
|
||||
bool
|
||||
operator<(const Adjacent& adjacent) const;
|
||||
|
||||
inline bool
|
||||
compare(const ndn::Name& adjacencyName)
|
||||
compare(const ndn::Name& adjacencyName) const
|
||||
{
|
||||
return m_name == adjacencyName;
|
||||
}
|
||||
|
||||
inline bool
|
||||
compareFaceId(uint64_t faceId)
|
||||
compareFaceId(const uint64_t faceId) const
|
||||
{
|
||||
return m_faceId == faceId;
|
||||
}
|
||||
|
||||
inline bool
|
||||
compareFaceUri(std::string& faceUri)
|
||||
compareFaceUri(const ndn::FaceUri& faceUri) const
|
||||
{
|
||||
return m_connectingFaceUri == faceUri;
|
||||
return m_faceUri == faceUri;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -149,14 +164,27 @@ public:
|
||||
static const float DEFAULT_LINK_COST;
|
||||
|
||||
private:
|
||||
/*! m_name The NLSR-configured router name of the neighbor */
|
||||
ndn::Name m_name;
|
||||
std::string m_connectingFaceUri;
|
||||
/*! m_faceUri The NFD-level specification of the Face*/
|
||||
ndn::FaceUri m_faceUri;
|
||||
/*! m_linkCost The semi-arbitrary cost to traverse the link. */
|
||||
double m_linkCost;
|
||||
/*! m_status Whether the neighbor is active or not */
|
||||
Status m_status;
|
||||
/*! m_interestTimedOutNo How many failed Hello interests we have sent since the last reply */
|
||||
uint32_t m_interestTimedOutNo;
|
||||
/*! m_faceId The NFD-assigned ID for the neighbor, used to
|
||||
* determine whether a Face is available */
|
||||
uint64_t m_faceId;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Adjacent& adjacent);
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Adjacent& adjacent);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif //NLSR_ADJACENT_HPP
|
||||
#endif // NLSR_ADJACENT_HPP
|
||||
+26
-1
@@ -19,10 +19,17 @@
|
||||
*
|
||||
**/
|
||||
|
||||
/*! \file
|
||||
* Shared include file to provide a single point-of-entry, and
|
||||
* hopefully improve compile times.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_COMMON_HPP
|
||||
#define NLSR_COMMON_HPP
|
||||
|
||||
#include <ndn-cxx/common.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
#include <ndn-cxx/name.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
@@ -31,6 +38,24 @@ using std::make_shared;
|
||||
using std::shared_ptr;
|
||||
using std::function;
|
||||
|
||||
}
|
||||
const ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION = ndn::time::seconds(4);
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_iterator
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
/*! Use C++11 iterator_traits to check if some type is an iterator
|
||||
*/
|
||||
template<typename T>
|
||||
struct is_iterator<T, typename std::enable_if<!std::is_same<
|
||||
typename std::iterator_traits<T>::value_type,
|
||||
void>::value>::type>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_COMMON_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -20,101 +20,18 @@
|
||||
**/
|
||||
|
||||
#include "sync-logic-handler.hpp"
|
||||
|
||||
#include "common.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "sequencing-manager.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("SyncLogicHandler");
|
||||
INIT_LOGGER(SyncLogicHandler);
|
||||
|
||||
using namespace ndn;
|
||||
using namespace std;
|
||||
|
||||
class SyncUpdate
|
||||
{
|
||||
public:
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
SyncUpdate(const ndn::Name& name, uint64_t seqNo)
|
||||
: m_name(name)
|
||||
, m_seqManager(seqNo)
|
||||
{
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const ndn::Name
|
||||
getOriginRouter() const
|
||||
{
|
||||
int32_t nlsrPosition = util::getNameComponentPosition(m_name, NLSR_COMPONENT);
|
||||
int32_t lsaPosition = util::getNameComponentPosition(m_name, LSA_COMPONENT);
|
||||
|
||||
if (nlsrPosition < 0 || lsaPosition < 0) {
|
||||
BOOST_THROW_EXCEPTION(Error("Cannot parse update name because expected components are missing"));
|
||||
}
|
||||
|
||||
ndn::Name networkName = m_name.getSubName(1, nlsrPosition-1);
|
||||
ndn::Name routerName = m_name.getSubName(lsaPosition + 1);
|
||||
|
||||
ndn::Name originRouter = networkName;
|
||||
originRouter.append(routerName);
|
||||
|
||||
return originRouter;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getNameLsaSeqNo() const
|
||||
{
|
||||
return m_seqManager.getNameLsaSeq();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getAdjLsaSeqNo() const
|
||||
{
|
||||
return m_seqManager.getAdjLsaSeq();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getCorLsaSeqNo() const
|
||||
{
|
||||
return m_seqManager.getCorLsaSeq();
|
||||
}
|
||||
|
||||
const SequencingManager&
|
||||
getSequencingManager() const
|
||||
{
|
||||
return m_seqManager;
|
||||
}
|
||||
|
||||
private:
|
||||
const ndn::Name m_name;
|
||||
SequencingManager m_seqManager;
|
||||
|
||||
static const std::string NLSR_COMPONENT;
|
||||
static const std::string LSA_COMPONENT;
|
||||
};
|
||||
|
||||
const std::string SyncUpdate::NLSR_COMPONENT = "NLSR";
|
||||
const std::string SyncUpdate::LSA_COMPONENT = "LSA";
|
||||
const std::string NLSR_COMPONENT = "NLSR";
|
||||
const std::string LSA_COMPONENT = "LSA";
|
||||
|
||||
template<class T>
|
||||
class NullDeleter
|
||||
@@ -126,22 +43,20 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
SyncLogicHandler::SyncLogicHandler(ndn::Face& face,
|
||||
Lsdb& lsdb, ConfParameter& conf,
|
||||
SequencingManager& seqManager)
|
||||
: m_validator(new ndn::ValidatorNull())
|
||||
SyncLogicHandler::SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew,
|
||||
const ConfParameter& conf)
|
||||
: onNewLsa(ndn::make_unique<OnNewLsa>())
|
||||
, m_syncFace(face)
|
||||
, m_lsdb(lsdb)
|
||||
, m_isLsaNew(isLsaNew)
|
||||
, m_confParam(conf)
|
||||
, m_sequencingManager(seqManager)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix)
|
||||
SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix, const ndn::time::milliseconds& syncInterestLifetime)
|
||||
{
|
||||
if (m_syncSocket != nullptr) {
|
||||
_LOG_WARN("Trying to create Sync socket, but Sync socket already exists");
|
||||
NLSR_LOG_WARN("Trying to create Sync socket, but Sync socket already exists");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -150,156 +65,143 @@ SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix)
|
||||
// Build LSA sync update prefix
|
||||
buildUpdatePrefix();
|
||||
|
||||
_LOG_DEBUG("Creating Sync socket. Sync Prefix: " << m_syncPrefix);
|
||||
NLSR_LOG_DEBUG("Creating Sync socket. Sync Prefix: " << m_syncPrefix);
|
||||
|
||||
// The face's lifetime is managed in main.cpp; SyncSocket should not manage the memory
|
||||
// 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));
|
||||
const auto fixedSession = ndn::name::Component::fromNumber(0);
|
||||
m_syncSocket = std::make_shared<chronosync::Socket>(m_syncPrefix, m_nameLsaUserPrefix, *facePtr,
|
||||
std::bind(&SyncLogicHandler::onChronoSyncUpdate, this, _1),
|
||||
chronosync::Socket::DEFAULT_NAME, chronosync::Socket::DEFAULT_VALIDATOR,
|
||||
syncInterestLifetime, fixedSession);
|
||||
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
|
||||
m_syncSocket->addSyncNode(m_adjLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
}
|
||||
else if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_syncSocket->addSyncNode(m_coorLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
}
|
||||
else {
|
||||
m_syncSocket->addSyncNode(m_adjLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
m_syncSocket->addSyncNode(m_coorLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::onNsyncUpdate(const vector<Sync::MissingDataInfo>& v, Sync::SyncSocket* socket)
|
||||
SyncLogicHandler::onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v)
|
||||
{
|
||||
_LOG_DEBUG("Received Nsync update event");
|
||||
NLSR_LOG_DEBUG("Received ChronoSync update event");
|
||||
|
||||
for (size_t i = 0; i < v.size(); i++){
|
||||
_LOG_DEBUG("Update Name: " << v[i].prefix << " Seq no: " << v[i].high.getSeq());
|
||||
ndn::Name updateName = v[i].session.getPrefix(-1);
|
||||
|
||||
SyncUpdate update(v[i].prefix, v[i].high.getSeq());
|
||||
NLSR_LOG_DEBUG("Update Name: " << updateName << " Seq no: " << v[i].high);
|
||||
|
||||
processUpdateFromSync(update);
|
||||
int32_t nlsrPosition = util::getNameComponentPosition(updateName, nlsr::NLSR_COMPONENT);
|
||||
int32_t lsaPosition = util::getNameComponentPosition(updateName, nlsr::LSA_COMPONENT);
|
||||
|
||||
if (nlsrPosition < 0 || lsaPosition < 0) {
|
||||
NLSR_LOG_WARN("Received malformed sync update");
|
||||
return;
|
||||
}
|
||||
|
||||
ndn::Name networkName = updateName.getSubName(1, nlsrPosition-1);
|
||||
ndn::Name routerName = updateName.getSubName(lsaPosition + 1).getPrefix(-1);
|
||||
|
||||
ndn::Name originRouter = networkName;
|
||||
originRouter.append(routerName);
|
||||
|
||||
processUpdateFromSync(originRouter, updateName, v[i].high);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::onNsyncRemoval(const string& prefix)
|
||||
SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
const ndn::Name& updateName, const uint64_t& seqNo)
|
||||
{
|
||||
_LOG_DEBUG("Received Nsync removal event");
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::processUpdateFromSync(const SyncUpdate& update)
|
||||
{
|
||||
ndn::Name originRouter;
|
||||
|
||||
try {
|
||||
originRouter = update.getOriginRouter();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
_LOG_WARN("Received malformed sync update");
|
||||
return;
|
||||
}
|
||||
NLSR_LOG_DEBUG("Origin Router of update: " << originRouter);
|
||||
|
||||
// A router should not try to fetch its own LSA
|
||||
if (originRouter != m_confParam.getRouterPrefix()) {
|
||||
|
||||
update.getSequencingManager().writeLog();
|
||||
Lsa::Type lsaType;
|
||||
std::istringstream(updateName.get(updateName.size()-1).toUri()) >> lsaType;
|
||||
|
||||
if (isLsaNew(originRouter, NameLsa::TYPE_STRING, update.getNameLsaSeqNo())) {
|
||||
_LOG_DEBUG("Received sync update with higher Name LSA sequence number than entry in LSDB");
|
||||
NLSR_LOG_DEBUG("Received sync update with higher " << lsaType
|
||||
<< " sequence number than entry in LSDB");
|
||||
|
||||
expressInterestForLsa(update, NameLsa::TYPE_STRING, update.getNameLsaSeqNo());
|
||||
if (m_isLsaNew(originRouter, lsaType, seqNo)) {
|
||||
if (lsaType == Lsa::Type::ADJACENCY && seqNo != 0 &&
|
||||
m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
NLSR_LOG_ERROR("Got an update for adjacency LSA when hyperbolic routing"
|
||||
<< " is enabled. Not going to fetch.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLsaNew(originRouter, AdjLsa::TYPE_STRING, update.getAdjLsaSeqNo())) {
|
||||
_LOG_DEBUG("Received sync update with higher Adj LSA sequence number than entry in LSDB");
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
if (update.getAdjLsaSeqNo() != 0) {
|
||||
_LOG_ERROR("Tried to fetch an adjacency LSA when hyperbolic routing"
|
||||
<< " is enabled.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
expressInterestForLsa(update, AdjLsa::TYPE_STRING, update.getAdjLsaSeqNo());
|
||||
}
|
||||
}
|
||||
|
||||
if (isLsaNew(originRouter, CoordinateLsa::TYPE_STRING, update.getCorLsaSeqNo())) {
|
||||
_LOG_DEBUG("Received sync update with higher Cor LSA sequence number than entry in LSDB");
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
|
||||
if (update.getCorLsaSeqNo() != 0) {
|
||||
_LOG_ERROR("Tried to fetch a coordinate LSA when link-state"
|
||||
<< " is enabled.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
expressInterestForLsa(update, CoordinateLsa::TYPE_STRING, update.getCorLsaSeqNo());
|
||||
}
|
||||
if (lsaType == Lsa::Type::COORDINATE && seqNo != 0 &&
|
||||
m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
|
||||
NLSR_LOG_ERROR("Got an update for coordinate LSA when link-state"
|
||||
<< " is enabled. Not going to fetch.");
|
||||
return;
|
||||
}
|
||||
(*onNewLsa)(updateName, seqNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SyncLogicHandler::isLsaNew(const ndn::Name& originRouter, const std::string& lsaType,
|
||||
uint64_t seqNo)
|
||||
{
|
||||
ndn::Name lsaKey = originRouter;
|
||||
lsaKey.append(lsaType);
|
||||
|
||||
if (lsaType == NameLsa::TYPE_STRING)
|
||||
{
|
||||
return m_lsdb.isNameLsaNew(lsaKey, seqNo);
|
||||
}
|
||||
else if (lsaType == AdjLsa::TYPE_STRING)
|
||||
{
|
||||
return m_lsdb.isAdjLsaNew(lsaKey, seqNo);
|
||||
}
|
||||
else if (lsaType == CoordinateLsa::TYPE_STRING)
|
||||
{
|
||||
return m_lsdb.isCoordinateLsaNew(lsaKey, seqNo);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::expressInterestForLsa(const SyncUpdate& update, std::string lsaType,
|
||||
uint64_t seqNo)
|
||||
{
|
||||
ndn::Name interest(update.getName());
|
||||
interest.append(lsaType);
|
||||
interest.appendNumber(seqNo);
|
||||
|
||||
m_lsdb.expressInterest(interest, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::publishRoutingUpdate()
|
||||
SyncLogicHandler::publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo)
|
||||
{
|
||||
if (m_syncSocket == nullptr) {
|
||||
_LOG_FATAL("Cannot publish routing update; SyncSocket does not exist");
|
||||
NLSR_LOG_FATAL("Cannot publish routing update; SyncSocket does not exist");
|
||||
|
||||
BOOST_THROW_EXCEPTION(SyncLogicHandler::Error("Cannot publish routing update; SyncSocket does not exist"));
|
||||
}
|
||||
|
||||
m_sequencingManager.writeSeqNoToFile();
|
||||
|
||||
publishSyncUpdate(m_updatePrefix, m_sequencingManager.getCombinedSeqNo());
|
||||
switch (type) {
|
||||
case Lsa::Type::ADJACENCY:
|
||||
publishSyncUpdate(m_adjLsaUserPrefix, seqNo);
|
||||
break;
|
||||
case Lsa::Type::COORDINATE:
|
||||
publishSyncUpdate(m_coorLsaUserPrefix, seqNo);
|
||||
break;
|
||||
case Lsa::Type::NAME:
|
||||
publishSyncUpdate(m_nameLsaUserPrefix, seqNo);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::buildUpdatePrefix()
|
||||
{
|
||||
m_updatePrefix = m_confParam.getLsaPrefix();
|
||||
m_updatePrefix.append(m_confParam.getSiteName());
|
||||
m_updatePrefix.append(m_confParam.getRouterName());
|
||||
ndn::Name updatePrefix = m_confParam.getLsaPrefix();
|
||||
updatePrefix.append(m_confParam.getSiteName());
|
||||
updatePrefix.append(m_confParam.getRouterName());
|
||||
|
||||
m_nameLsaUserPrefix = updatePrefix;
|
||||
m_nameLsaUserPrefix.append(std::to_string(Lsa::Type::NAME));
|
||||
|
||||
m_adjLsaUserPrefix = updatePrefix;
|
||||
m_adjLsaUserPrefix.append(std::to_string(Lsa::Type::ADJACENCY));
|
||||
|
||||
m_coorLsaUserPrefix = updatePrefix;
|
||||
m_coorLsaUserPrefix.append(std::to_string(Lsa::Type::COORDINATE));
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqNo)
|
||||
{
|
||||
_LOG_DEBUG("Publishing Sync Update. Prefix: " << updatePrefix << " Seq No: " << seqNo);
|
||||
NLSR_LOG_DEBUG("Publishing Sync Update. Prefix: " << updatePrefix << " Seq No: " << seqNo);
|
||||
|
||||
ndn::Name updateName(updatePrefix);
|
||||
string data("NoData");
|
||||
std::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
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -22,29 +22,36 @@
|
||||
#ifndef NLSR_SYNC_LOGIC_HANDLER_HPP
|
||||
#define NLSR_SYNC_LOGIC_HANDLER_HPP
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/validator-null.hpp>
|
||||
#include <nsync/sync-socket.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include "conf-parameter.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
#include "signals.hpp"
|
||||
#include "lsa.hpp"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
#include <ChronoSync/socket.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
class InterestManager;
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class ConfParameter;
|
||||
class Lsdb;
|
||||
class SequencingManager;
|
||||
class SyncUpdate;
|
||||
|
||||
/*! \brief NLSR-to-ChronoSync interaction point
|
||||
*
|
||||
* This class serves as the abstraction for the syncing portion of
|
||||
* NLSR and its components. NLSR has no particular reliance on
|
||||
* ChronoSync, except that the NLSR source would need to be modified
|
||||
* for use with other sync protocols.
|
||||
*
|
||||
*/
|
||||
class SyncLogicHandler
|
||||
{
|
||||
public:
|
||||
using IsLsaNew =
|
||||
std::function<bool(const ndn::Name&, const Lsa::Type& lsaType, const uint64_t&)>;
|
||||
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
@@ -55,54 +62,85 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
SyncLogicHandler(ndn::Face& face, Lsdb& lsdb, ConfParameter& conf, SequencingManager& seqManager);
|
||||
SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew, const ConfParameter& conf);
|
||||
|
||||
/*! \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.
|
||||
/*! \brief Hook function to call whenever sync detects new data.
|
||||
*
|
||||
* This function packages the sync information into discrete updates
|
||||
* and passes those off to another function, processUpdateFromSync.
|
||||
* \sa processUpdateFromSync
|
||||
*
|
||||
* \param v A container with the new information sync has received
|
||||
*/
|
||||
void
|
||||
onNsyncUpdate(const std::vector<Sync::MissingDataInfo>& v, Sync::SyncSocket* socket);
|
||||
onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v);
|
||||
|
||||
/*! \brief Instruct ChronoSync to publish an update.
|
||||
*
|
||||
* This function instructs sync to push an update into the network,
|
||||
* based on whatever the state of the sequencing manager is when
|
||||
* this is called. Since each ChronoSync instance maintains its own
|
||||
* PIT, doing this satisfies those interests so that other routers
|
||||
* know a sync update is available.
|
||||
* \sa publishSyncUpdate
|
||||
*/
|
||||
void
|
||||
onNsyncRemoval(const std::string& prefix);
|
||||
publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo);
|
||||
|
||||
/*! \brief Create and configure a socket to enable ChronoSync for this NLSR.
|
||||
*
|
||||
* In a typical situation this only needs to be called once, when NLSR starts.
|
||||
* \param syncPrefix The sync prefix you want this ChronoSync to use
|
||||
* \param syncInterestLifetime ChronoSync sends a periodic sync interest every \p syncInterestLifetime / 2 ms
|
||||
* \sa Nlsr::initialize
|
||||
*/
|
||||
void
|
||||
publishRoutingUpdate();
|
||||
createSyncSocket(const ndn::Name& syncPrefix,
|
||||
const ndn::time::milliseconds& syncInterestLifetime =
|
||||
ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT));
|
||||
|
||||
void
|
||||
createSyncSocket(const ndn::Name& syncPrefix);
|
||||
|
||||
private:
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Simple function to glue Name components together
|
||||
*/
|
||||
void
|
||||
buildUpdatePrefix();
|
||||
|
||||
private:
|
||||
/*! \brief Determine which kind of LSA was updated and fetch it.
|
||||
*
|
||||
* Checks that the received update is not from us, which can happen,
|
||||
* and then inspects the update to determine which kind of LSA the
|
||||
* update is for. Finally, it expresses interest for the correct LSA
|
||||
* type.
|
||||
* \throws SyncUpdate::Error If the sync update doesn't look like a sync LSA update.
|
||||
*/
|
||||
void
|
||||
processUpdateFromSync(const SyncUpdate& updateName);
|
||||
|
||||
bool
|
||||
isLsaNew(const ndn::Name& originRouter, const std::string& lsaType, uint64_t seqNo);
|
||||
|
||||
void
|
||||
expressInterestForLsa(const SyncUpdate& updateName, std::string lsaType, uint64_t seqNo);
|
||||
processUpdateFromSync(const ndn::Name& originRouter,
|
||||
const ndn::Name& updateName, const uint64_t& seqNo);
|
||||
|
||||
/*! \brief Instruct ChronoSync, via the sync socket, to publish an update.
|
||||
*
|
||||
* Each ChronoSync instance maintains its own PIT for sync
|
||||
* updates. This function creates a data that satisfies that update,
|
||||
* so that the interested routers will know new data is available.
|
||||
*/
|
||||
void
|
||||
publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqNo);
|
||||
|
||||
private:
|
||||
std::shared_ptr<ndn::ValidatorNull> m_validator;
|
||||
ndn::Face& m_syncFace;
|
||||
std::shared_ptr<Sync::SyncSocket> m_syncSocket;
|
||||
ndn::Name m_syncPrefix;
|
||||
public:
|
||||
std::unique_ptr<OnNewLsa> onNewLsa;
|
||||
|
||||
private:
|
||||
Lsdb& m_lsdb;
|
||||
ConfParameter& m_confParam;
|
||||
const SequencingManager& m_sequencingManager;
|
||||
ndn::Face& m_syncFace;
|
||||
std::shared_ptr<chronosync::Socket> m_syncSocket;
|
||||
ndn::Name m_syncPrefix;
|
||||
IsLsaNew m_isLsaNew;
|
||||
const ConfParameter& m_confParam;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
ndn::Name m_updatePrefix;
|
||||
ndn::Name m_nameLsaUserPrefix;
|
||||
ndn::Name m_adjLsaUserPrefix;
|
||||
ndn::Name m_coorLsaUserPrefix;
|
||||
|
||||
private:
|
||||
static const std::string NLSR_COMPONENT;
|
||||
|
||||
+87
-112
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -19,27 +19,21 @@
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <ndn-cxx/name.hpp>
|
||||
#include <ndn-cxx/util/face-uri.hpp>
|
||||
|
||||
// boost needs to be included after ndn-cxx, otherwise there will be conflict with _1, _2, ...
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/property_tree/info_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "conf-parameter.hpp"
|
||||
#include "conf-file-processor.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "update/prefix-update-processor.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
using namespace std;
|
||||
#include <ndn-cxx/name.hpp>
|
||||
#include <ndn-cxx/net/face-uri.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
template <class T>
|
||||
class ConfigurationVariable
|
||||
@@ -144,12 +138,12 @@ bool
|
||||
ConfFileProcessor::processConfFile()
|
||||
{
|
||||
bool ret = true;
|
||||
ifstream inputFile;
|
||||
std::ifstream inputFile;
|
||||
inputFile.open(m_confFileName.c_str());
|
||||
if (!inputFile.is_open()) {
|
||||
string msg = "Failed to read configuration file: ";
|
||||
std::string msg = "Failed to read configuration file: ";
|
||||
msg += m_confFileName;
|
||||
cerr << msg << endl;
|
||||
std::cerr << msg << std::endl;
|
||||
return false;
|
||||
}
|
||||
ret = load(inputFile);
|
||||
@@ -158,7 +152,7 @@ ConfFileProcessor::processConfFile()
|
||||
}
|
||||
|
||||
bool
|
||||
ConfFileProcessor::load(istream& input)
|
||||
ConfFileProcessor::load(std::istream& input)
|
||||
{
|
||||
ConfigSection pt;
|
||||
bool ret = true;
|
||||
@@ -166,7 +160,7 @@ ConfFileProcessor::load(istream& input)
|
||||
boost::property_tree::read_info(input, pt);
|
||||
}
|
||||
catch (const boost::property_tree::info_parser_error& error) {
|
||||
stringstream msg;
|
||||
std::stringstream msg;
|
||||
std::cerr << "Failed to parse configuration file " << std::endl;
|
||||
std::cerr << m_confFileName << std::endl;
|
||||
return false;
|
||||
@@ -221,15 +215,15 @@ bool
|
||||
ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
{
|
||||
try {
|
||||
std::string network = section.get<string>("network");
|
||||
std::string site = section.get<string>("site");
|
||||
std::string router = section.get<string>("router");
|
||||
std::string network = section.get<std::string>("network");
|
||||
std::string site = section.get<std::string>("site");
|
||||
std::string router = section.get<std::string>("router");
|
||||
ndn::Name networkName(network);
|
||||
if (!networkName.empty()) {
|
||||
m_nlsr.getConfParameter().setNetwork(networkName);
|
||||
}
|
||||
else {
|
||||
cerr << " Network can not be null or empty or in bad URI format :(!" << endl;
|
||||
std::cerr << " Network can not be null or empty or in bad URI format :(!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
ndn::Name siteName(site);
|
||||
@@ -237,7 +231,7 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
m_nlsr.getConfParameter().setSiteName(siteName);
|
||||
}
|
||||
else {
|
||||
cerr << "Site can not be null or empty or in bad URI format:( !" << endl;
|
||||
std::cerr << "Site can not be null or empty or in bad URI format:( !" << std::endl;
|
||||
return false;
|
||||
}
|
||||
ndn::Name routerName(router);
|
||||
@@ -245,12 +239,12 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
m_nlsr.getConfParameter().setRouterName(routerName);
|
||||
}
|
||||
else {
|
||||
cerr << " Router name can not be null or empty or in bad URI format:( !" << endl;
|
||||
std::cerr << " Router name can not be null or empty or in bad URI format:( !" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
cerr << ex.what() << endl;
|
||||
std::cerr << ex.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -293,58 +287,25 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
return false;
|
||||
}
|
||||
|
||||
// log-level
|
||||
std::string logLevel = section.get<string>("log-level", "INFO");
|
||||
|
||||
if (isValidLogLevel(logLevel)) {
|
||||
m_nlsr.getConfParameter().setLogLevel(logLevel);
|
||||
uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime", SYNC_INTEREST_LIFETIME_DEFAULT);
|
||||
if (syncInterestLifetime >= SYNC_INTEREST_LIFETIME_MIN &&
|
||||
syncInterestLifetime <= SYNC_INTEREST_LIFETIME_MAX) {
|
||||
m_nlsr.getConfParameter().setSyncInterestLifetime(syncInterestLifetime);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Invalid value for log-level ";
|
||||
std::cerr << "Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, NONE" << std::endl;
|
||||
std::cerr << "Wrong value for sync-interest-lifetime. "
|
||||
<< "Allowed value:" << SYNC_INTEREST_LIFETIME_MIN << "-"
|
||||
<< SYNC_INTEREST_LIFETIME_MAX << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
std::string logDir = section.get<string>("log-dir");
|
||||
if (boost::filesystem::exists(logDir)) {
|
||||
if (boost::filesystem::is_directory(logDir)) {
|
||||
std::string testFileName=logDir+"/test.log";
|
||||
ofstream testOutFile;
|
||||
testOutFile.open(testFileName.c_str());
|
||||
if (testOutFile.is_open() && testOutFile.good()) {
|
||||
m_nlsr.getConfParameter().setLogDir(logDir);
|
||||
}
|
||||
else {
|
||||
std::cerr << "User does not have read and write permission on the directory";
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
testOutFile.close();
|
||||
remove(testFileName.c_str());
|
||||
}
|
||||
else {
|
||||
std::cerr << "Provided path is not a directory" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Provided log directory <" << logDir << "> does not exist" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
std::cerr << "You must configure log directory" << std::endl;
|
||||
std::cerr << ex.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
std::string seqDir = section.get<string>("seq-dir");
|
||||
std::string seqDir = section.get<std::string>("seq-dir");
|
||||
if (boost::filesystem::exists(seqDir)) {
|
||||
if (boost::filesystem::is_directory(seqDir)) {
|
||||
std::string testFileName=seqDir+"/test.seq";
|
||||
ofstream testOutFile;
|
||||
std::ofstream testOutFile;
|
||||
testOutFile.open(testFileName.c_str());
|
||||
if (testOutFile.is_open() && testOutFile.good()) {
|
||||
m_nlsr.getConfParameter().setSeqFileDir(seqDir);
|
||||
@@ -373,28 +334,6 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
std::string log4cxxPath = section.get<string>("log4cxx-conf");
|
||||
|
||||
if (log4cxxPath == "") {
|
||||
std::cerr << "No value provided for log4cxx-conf" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (boost::filesystem::exists(log4cxxPath)) {
|
||||
m_nlsr.getConfParameter().setLog4CxxConfPath(log4cxxPath);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Provided path for log4cxx-conf <" << log4cxxPath
|
||||
<< "> does not exist" << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
// Variable is optional so default configuration will be used; continue processing file
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -454,6 +393,33 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
if (!adjLsaBuildInterval.parseFromConfigSection(section)) {
|
||||
return false;
|
||||
}
|
||||
// Set the retry count for fetching the FaceStatus dataset
|
||||
ConfigurationVariable<uint32_t> faceDatasetFetchTries("face-dataset-fetch-tries",
|
||||
std::bind(&ConfParameter::setFaceDatasetFetchTries,
|
||||
&m_nlsr.getConfParameter(),
|
||||
_1));
|
||||
|
||||
faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
|
||||
FACE_DATASET_FETCH_TRIES_MAX);
|
||||
faceDatasetFetchTries.setOptional(FACE_DATASET_FETCH_TRIES_DEFAULT);
|
||||
|
||||
if (!faceDatasetFetchTries.parseFromConfigSection(section)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the interval between FaceStatus dataset fetch attempts.
|
||||
ConfigurationVariable<uint32_t> faceDatasetFetchInterval("face-dataset-fetch-interval",
|
||||
bind(&ConfParameter::setFaceDatasetFetchInterval,
|
||||
&m_nlsr.getConfParameter(),
|
||||
_1));
|
||||
|
||||
faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
|
||||
FACE_DATASET_FETCH_INTERVAL_MAX);
|
||||
faceDatasetFetchInterval.setOptional(FACE_DATASET_FETCH_INTERVAL_DEFAULT);
|
||||
|
||||
if (!faceDatasetFetchInterval.parseFromConfigSection(section)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// first-hello-interval
|
||||
ConfigurationVariable<uint32_t> firstHelloInterval("first-hello-interval",
|
||||
@@ -469,17 +435,15 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
for (ConfigSection::const_iterator tn =
|
||||
section.begin(); tn != section.end(); ++tn) {
|
||||
|
||||
if (tn->first == "neighbor")
|
||||
{
|
||||
if (tn->first == "neighbor") {
|
||||
try {
|
||||
ConfigSection CommandAttriTree = tn->second;
|
||||
std::string name = CommandAttriTree.get<std::string>("name");
|
||||
std::string faceUri = CommandAttriTree.get<std::string>("face-uri");
|
||||
std::string uriString = CommandAttriTree.get<std::string>("face-uri");
|
||||
|
||||
ndn::util::FaceUri uri;
|
||||
|
||||
if (!uri.parse(faceUri)) {
|
||||
std::cerr << "Malformed face-uri <" << faceUri << "> for " << name << std::endl;
|
||||
ndn::FaceUri faceUri;
|
||||
if (! faceUri.parse(uriString)) {
|
||||
std::cerr << "parsing failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -508,7 +472,7 @@ bool
|
||||
ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
|
||||
{
|
||||
// state
|
||||
std::string state = section.get<string>("state", "off");
|
||||
std::string state = section.get<std::string>("state", "off");
|
||||
|
||||
if (boost::iequals(state, "off")) {
|
||||
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_OFF);
|
||||
@@ -527,17 +491,29 @@ ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
|
||||
}
|
||||
|
||||
try {
|
||||
/* Radius and angle is mandatory configuration parameter in hyperbolic section.
|
||||
* Even if router can have hyperbolic routing calculation off but other router
|
||||
* in the network may use hyperbolic routing calculation for FIB generation.
|
||||
* So each router need to advertise its hyperbolic coordinates in the network
|
||||
*/
|
||||
// Radius and angle(s) are mandatory configuration parameters in hyperbolic section.
|
||||
// Even if router can have hyperbolic routing calculation off but other router
|
||||
// in the network may use hyperbolic routing calculation for FIB generation.
|
||||
// So each router need to advertise its hyperbolic coordinates in the network
|
||||
double radius = section.get<double>("radius");
|
||||
double angle = section.get<double>("angle");
|
||||
std::string angleString = section.get<std::string>("angle");
|
||||
|
||||
std::stringstream ss(angleString);
|
||||
std::vector<double> angles;
|
||||
|
||||
double angle;
|
||||
|
||||
while (ss >> angle) {
|
||||
angles.push_back(angle);
|
||||
if (ss.peek() == ',' || ss.peek() == ' ') {
|
||||
ss.ignore();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_nlsr.getConfParameter().setCorR(radius)) {
|
||||
return false;
|
||||
}
|
||||
m_nlsr.getConfParameter().setCorTheta(angle);
|
||||
m_nlsr.getConfParameter().setCorTheta(angles);
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
std::cerr << ex.what() << std::endl;
|
||||
@@ -621,7 +597,6 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
|
||||
|
||||
it++;
|
||||
if (it != section.end() && it->first == "prefix-update-validator") {
|
||||
m_nlsr.getPrefixUpdateProcessor().enable();
|
||||
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
|
||||
|
||||
it++;
|
||||
@@ -635,15 +610,15 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
|
||||
|
||||
std::string file = it->second.data();
|
||||
path certfilePath = absolute(file, path(m_confFileName).parent_path());
|
||||
std::shared_ptr<ndn::IdentityCertificate> idCert =
|
||||
ndn::io::load<ndn::IdentityCertificate>(certfilePath.string());
|
||||
std::shared_ptr<ndn::security::v2::Certificate> idCert =
|
||||
ndn::io::load<ndn::security::v2::Certificate>(certfilePath.string());
|
||||
|
||||
if (idCert == nullptr) {
|
||||
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.loadCertToPublish(idCert);
|
||||
m_nlsr.loadCertToPublish(*idCert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+64
-11
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,22 +16,33 @@
|
||||
*
|
||||
* 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 CONF_PROCESSOR_HPP
|
||||
#define CONF_PROCESSOR_HPP
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#ifndef NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
#define NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "nlsr.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/property_tree/info_parser.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*! \brief A class containing methods to parse an NLSR configuration file
|
||||
*
|
||||
* This class contains methods to parse an NLSR configuration file and
|
||||
* set all the parameters in NLSR to the received values. There are
|
||||
* defaults for any unconfigured settings.
|
||||
*
|
||||
* This is currently called by the wrapper class NlsrRunner to
|
||||
* populate the NLSR object with its configuration before NLSR is
|
||||
* started.
|
||||
*
|
||||
* \sa nlsr::ConfParameter
|
||||
* \sa NlsrRunner::run
|
||||
*/
|
||||
class ConfFileProcessor
|
||||
{
|
||||
public:
|
||||
@@ -41,40 +52,82 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/*! \brief Load and parse the configuration file, then populate NLSR.
|
||||
*
|
||||
* Entry-point function that chains all the necessary steps together
|
||||
* to configure an NLSR object.
|
||||
*
|
||||
* \return A boolean for whether configuration was successful.
|
||||
*/
|
||||
bool
|
||||
processConfFile();
|
||||
|
||||
private:
|
||||
typedef boost::property_tree::ptree ConfigSection;
|
||||
|
||||
/*! \brief Parse the configuration file into a tree and process the nodes.
|
||||
*
|
||||
* Reads the configuration file as a property tree, and then iterates
|
||||
* over them, attempting to parse each node. The nodes themselves
|
||||
* are passed to another function that determines what kind of
|
||||
* section it is and handles it appropriately. On any error in
|
||||
* reading the file, return false.
|
||||
*
|
||||
* \return Whether configuration was successful.
|
||||
*/
|
||||
bool
|
||||
load(std::istream& input);
|
||||
|
||||
/*! \brief A dispatcher-like function to send configuration tree nodes to the right subfunction.
|
||||
*/
|
||||
bool
|
||||
processSection(const std::string& sectionName, const ConfigSection& section);
|
||||
|
||||
/*! \brief Parse general options, including router name, LSA refresh.
|
||||
*/
|
||||
bool
|
||||
processConfSectionGeneral(const ConfigSection& section);
|
||||
|
||||
/*! \brief Configure options relating to neighbor configuration and detection.
|
||||
*
|
||||
* Parse options that control NLSR's behavior about neighbors. Such
|
||||
* things include how many hello interests are sent and what their
|
||||
* timeout is, as well as parsing neighbor specifications. Neighbor
|
||||
* Face URIs are parsed and confirmed as valid here by ndn-cxx.
|
||||
*/
|
||||
bool
|
||||
processConfSectionNeighbors(const ConfigSection& section);
|
||||
|
||||
/*! \brief Set the state of hyperbolic routing: off, on, dry-run.
|
||||
*/
|
||||
bool
|
||||
processConfSectionHyperbolic(const ConfigSection& section);
|
||||
|
||||
/*! \brief Set options for the FIB: nexthops per prefix, routing calculation interval.
|
||||
*/
|
||||
bool
|
||||
processConfSectionFib(const ConfigSection& section);
|
||||
|
||||
/*! \brief Set prefixes that NLSR is supposed to advertise immediately.
|
||||
*/
|
||||
bool
|
||||
processConfSectionAdvertising(const ConfigSection& section);
|
||||
|
||||
/*! \brief Parse and set rules for the validator.
|
||||
*
|
||||
* This section parses and sets rules for the validators, which
|
||||
* control what criteria Interest and Data need to follow to be
|
||||
* considered valid by this NLSR.
|
||||
*/
|
||||
bool
|
||||
processConfSectionSecurity(const ConfigSection& section);
|
||||
|
||||
private:
|
||||
/*! m_confFileName The full path of the configuration file to parse. */
|
||||
std::string m_confFileName;
|
||||
/*! m_nlsr The NLSR object to configure upon successful parsing. */
|
||||
Nlsr& m_nlsr;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
#endif //CONF_PROCESSOR_HPP
|
||||
#endif // NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
+46
-23
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -26,34 +26,57 @@
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("ConfParameter");
|
||||
INIT_LOGGER(ConfParameter);
|
||||
|
||||
// To be changed when breaking changes are made to sync
|
||||
const uint64_t ConfParameter::SYNC_VERSION = 4;
|
||||
|
||||
void
|
||||
ConfParameter::writeLog()
|
||||
{
|
||||
_LOG_DEBUG("Router Name: " << m_routerName);
|
||||
_LOG_DEBUG("Site Name: " << m_siteName);
|
||||
_LOG_DEBUG("Network: " << m_network);
|
||||
_LOG_DEBUG("Router Prefix: " << m_routerPrefix);
|
||||
_LOG_DEBUG("ChronoSync sync Prefix: " << m_chronosyncPrefix);
|
||||
_LOG_DEBUG("ChronoSync LSA prefix: " << m_lsaPrefix);
|
||||
_LOG_DEBUG("Hello Interest retry number: " << m_interestRetryNumber);
|
||||
_LOG_DEBUG("Hello Interest resend second: " << m_interestResendTime);
|
||||
_LOG_DEBUG("Info Interest interval: " << m_infoInterestInterval);
|
||||
_LOG_DEBUG("LSA refresh time: " << m_lsaRefreshTime);
|
||||
_LOG_DEBUG("LSA Interest lifetime: " << getLsaInterestLifetime());
|
||||
_LOG_DEBUG("Router dead interval: " << getRouterDeadInterval());
|
||||
_LOG_DEBUG("Max Faces Per Prefix: " << m_maxFacesPerPrefix);
|
||||
_LOG_DEBUG("Hyperbolic Routing: " << m_hyperbolicState);
|
||||
_LOG_DEBUG("Hyp R: " << m_corR);
|
||||
_LOG_DEBUG("Hyp theta: " << m_corTheta);
|
||||
_LOG_DEBUG("Log Directory: " << m_logDir);
|
||||
_LOG_DEBUG("Seq Directory: " << m_seqFileDir);
|
||||
NLSR_LOG_INFO("Router Name: " << m_routerName);
|
||||
NLSR_LOG_INFO("Site Name: " << m_siteName);
|
||||
NLSR_LOG_INFO("Network: " << m_network);
|
||||
NLSR_LOG_INFO("Router Prefix: " << m_routerPrefix);
|
||||
NLSR_LOG_INFO("ChronoSync sync Prefix: " << m_chronosyncPrefix);
|
||||
NLSR_LOG_INFO("ChronoSync LSA prefix: " << m_lsaPrefix);
|
||||
NLSR_LOG_INFO("Hello Interest retry number: " << m_interestRetryNumber);
|
||||
NLSR_LOG_INFO("Hello Interest resend second: " << m_interestResendTime);
|
||||
NLSR_LOG_INFO("Info Interest interval: " << m_infoInterestInterval);
|
||||
NLSR_LOG_INFO("LSA refresh time: " << m_lsaRefreshTime);
|
||||
NLSR_LOG_INFO("FIB Entry refresh time: " << m_lsaRefreshTime * 2);
|
||||
NLSR_LOG_INFO("LSA Interest lifetime: " << getLsaInterestLifetime());
|
||||
NLSR_LOG_INFO("Router dead interval: " << getRouterDeadInterval());
|
||||
NLSR_LOG_INFO("Max Faces Per Prefix: " << m_maxFacesPerPrefix);
|
||||
NLSR_LOG_INFO("Hyperbolic Routing: " << m_hyperbolicState);
|
||||
NLSR_LOG_INFO("Hyp R: " << m_corR);
|
||||
int i=0;
|
||||
for (auto const& value: m_corTheta) {
|
||||
NLSR_LOG_INFO("Hyp Angle " << i++ << ": "<< value);
|
||||
}
|
||||
NLSR_LOG_INFO("Seq Directory: " << m_seqFileDir);
|
||||
|
||||
// Event Intervals
|
||||
_LOG_DEBUG("Adjacency LSA build interval: " << m_adjLsaBuildInterval);
|
||||
_LOG_DEBUG("First Hello Interest interval: " << m_firstHelloInterval);
|
||||
_LOG_DEBUG("Routing calculation interval: " << m_routingCalcInterval);
|
||||
NLSR_LOG_INFO("Adjacency LSA build interval: " << m_adjLsaBuildInterval);
|
||||
NLSR_LOG_INFO("First Hello Interest interval: " << m_firstHelloInterval);
|
||||
NLSR_LOG_INFO("Routing calculation interval: " << m_routingCalcInterval);
|
||||
}
|
||||
|
||||
void
|
||||
ConfParameter::setNetwork(const ndn::Name& networkName)
|
||||
{
|
||||
m_network = networkName;
|
||||
|
||||
m_chronosyncPrefix.append("localhop");
|
||||
m_chronosyncPrefix.append(m_network);
|
||||
m_chronosyncPrefix.append("NLSR");
|
||||
m_chronosyncPrefix.append("sync");
|
||||
m_chronosyncPrefix.appendVersion(SYNC_VERSION);
|
||||
|
||||
m_lsaPrefix.append("localhop");
|
||||
m_lsaPrefix.append(m_network);
|
||||
m_lsaPrefix.append("NLSR");
|
||||
m_lsaPrefix.append("LSA");
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+72
-57
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -19,17 +19,18 @@
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef CONF_PARAMETER_HPP
|
||||
#define CONF_PARAMETER_HPP
|
||||
#ifndef NLSR_CONF_PARAMETER_HPP
|
||||
#define NLSR_CONF_PARAMETER_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <ndn-cxx/common.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
enum {
|
||||
@@ -62,6 +63,19 @@ enum {
|
||||
ROUTING_CALC_INTERVAL_MAX = 15
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
FACE_DATASET_FETCH_TRIES_MIN = 1,
|
||||
FACE_DATASET_FETCH_TRIES_MAX = 10,
|
||||
FACE_DATASET_FETCH_TRIES_DEFAULT = 3
|
||||
};
|
||||
|
||||
enum {
|
||||
FACE_DATASET_FETCH_INTERVAL_MIN = 1800,
|
||||
FACE_DATASET_FETCH_INTERVAL_MAX = 5400,
|
||||
FACE_DATASET_FETCH_INTERVAL_DEFAULT = 3600
|
||||
};
|
||||
|
||||
enum {
|
||||
HELLO_RETRIES_MIN = 1,
|
||||
HELLO_RETRIES_DEFAULT = 3,
|
||||
@@ -93,6 +107,23 @@ enum HyperbolicState {
|
||||
HYPERBOLIC_STATE_DEFAULT = 0
|
||||
};
|
||||
|
||||
enum {
|
||||
SYNC_INTEREST_LIFETIME_MIN = 1000,
|
||||
SYNC_INTEREST_LIFETIME_DEFAULT = 60000,
|
||||
SYNC_INTEREST_LIFETIME_MAX = 120000,
|
||||
};
|
||||
|
||||
/*! \brief A class to house all the configuration parameters for NLSR.
|
||||
*
|
||||
* This class is conceptually a singleton (but not mechanically) which
|
||||
* is just a collection of attributes that serve as a
|
||||
* separation-of-data for NLSR's configuration variables. NLSR refers
|
||||
* to an instance of this class for all its configuration
|
||||
* parameters. This object is typically populated by a
|
||||
* ConfFileProcessor reading a configuration file.
|
||||
*
|
||||
* \sa nlsr::ConfFileProcessor
|
||||
*/
|
||||
class ConfParameter
|
||||
{
|
||||
|
||||
@@ -102,6 +133,7 @@ public:
|
||||
, m_adjLsaBuildInterval(ADJ_LSA_BUILD_INTERVAL_DEFAULT)
|
||||
, m_firstHelloInterval(FIRST_HELLO_INTERVAL_DEFAULT)
|
||||
, m_routingCalcInterval(ROUTING_CALC_INTERVAL_DEFAULT)
|
||||
, m_faceDatasetFetchInterval(ndn::time::seconds(static_cast<int>(FACE_DATASET_FETCH_INTERVAL_DEFAULT)))
|
||||
, m_lsaInterestLifetime(ndn::time::seconds(static_cast<int>(LSA_INTEREST_LIFETIME_DEFAULT)))
|
||||
, m_routerDeadInterval(2 * LSA_REFRESH_TIME_DEFAULT)
|
||||
, m_logLevel("INFO")
|
||||
@@ -110,26 +142,13 @@ public:
|
||||
, m_infoInterestInterval(HELLO_INTERVAL_DEFAULT)
|
||||
, m_hyperbolicState(HYPERBOLIC_STATE_OFF)
|
||||
, m_corR(0)
|
||||
, m_corTheta(0)
|
||||
, m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
|
||||
, m_isLog4cxxConfAvailable(false)
|
||||
, m_syncInterestLifetime(ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
setNetwork(const ndn::Name& networkName)
|
||||
{
|
||||
m_network = networkName;
|
||||
|
||||
m_chronosyncPrefix.append("localhop");
|
||||
m_chronosyncPrefix.append("NLSR");
|
||||
m_chronosyncPrefix.append("sync");
|
||||
|
||||
m_lsaPrefix.append("localhop");
|
||||
m_lsaPrefix.append(m_network);
|
||||
m_lsaPrefix.append("NLSR");
|
||||
m_lsaPrefix.append("LSA");
|
||||
}
|
||||
setNetwork(const ndn::Name& networkName);
|
||||
|
||||
const ndn::Name&
|
||||
getNetwork() const
|
||||
@@ -261,15 +280,27 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
setLogLevel(const std::string& logLevel)
|
||||
setFaceDatasetFetchTries(uint32_t count)
|
||||
{
|
||||
m_logLevel = logLevel;
|
||||
m_faceDatasetFetchTries = count;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getLogLevel() const
|
||||
uint32_t
|
||||
getFaceDatasetFetchTries() const
|
||||
{
|
||||
return m_logLevel;
|
||||
return m_faceDatasetFetchTries;
|
||||
}
|
||||
|
||||
void
|
||||
setFaceDatasetFetchInterval(uint32_t interval)
|
||||
{
|
||||
m_faceDatasetFetchInterval = ndn::time::seconds(interval);
|
||||
}
|
||||
|
||||
const ndn::time::seconds
|
||||
getFaceDatasetFetchInterval() const
|
||||
{
|
||||
return m_faceDatasetFetchInterval;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -337,12 +368,12 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
setCorTheta(double ct)
|
||||
setCorTheta(const std::vector<double>& ct)
|
||||
{
|
||||
m_corTheta = ct;
|
||||
}
|
||||
|
||||
double
|
||||
std::vector<double>
|
||||
getCorTheta() const
|
||||
{
|
||||
return m_corTheta;
|
||||
@@ -360,18 +391,6 @@ public:
|
||||
return m_maxFacesPerPrefix;
|
||||
}
|
||||
|
||||
void
|
||||
setLogDir(const std::string& logDir)
|
||||
{
|
||||
m_logDir = logDir;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getLogDir() const
|
||||
{
|
||||
return m_logDir;
|
||||
}
|
||||
|
||||
void
|
||||
setSeqFileDir(const std::string& ssfd)
|
||||
{
|
||||
@@ -384,23 +403,16 @@ public:
|
||||
return m_seqFileDir;
|
||||
}
|
||||
|
||||
bool
|
||||
isLog4CxxConfAvailable() const
|
||||
{
|
||||
return m_isLog4cxxConfAvailable;
|
||||
}
|
||||
|
||||
void
|
||||
setLog4CxxConfPath(const std::string& path)
|
||||
setSyncInterestLifetime(uint32_t syncInterestLifetime)
|
||||
{
|
||||
m_log4CxxConfPath = path;
|
||||
m_isLog4cxxConfAvailable = true;
|
||||
m_syncInterestLifetime = ndn::time::milliseconds(syncInterestLifetime);
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getLog4CxxConfPath() const
|
||||
const ndn::time::milliseconds&
|
||||
getSyncInterestLifetime() const
|
||||
{
|
||||
return m_log4CxxConfPath;
|
||||
return m_syncInterestLifetime;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -423,6 +435,9 @@ private:
|
||||
uint32_t m_firstHelloInterval;
|
||||
uint32_t m_routingCalcInterval;
|
||||
|
||||
uint32_t m_faceDatasetFetchTries;
|
||||
ndn::time::seconds m_faceDatasetFetchInterval;
|
||||
|
||||
ndn::time::seconds m_lsaInterestLifetime;
|
||||
uint32_t m_routerDeadInterval;
|
||||
std::string m_logLevel;
|
||||
@@ -434,17 +449,17 @@ private:
|
||||
|
||||
int32_t m_hyperbolicState;
|
||||
double m_corR;
|
||||
double m_corTheta;
|
||||
std::vector<double> m_corTheta;
|
||||
|
||||
uint32_t m_maxFacesPerPrefix;
|
||||
|
||||
std::string m_logDir;
|
||||
std::string m_seqFileDir;
|
||||
ndn::time::milliseconds m_syncInterestLifetime;
|
||||
|
||||
bool m_isLog4cxxConfAvailable;
|
||||
std::string m_log4CxxConfPath;
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
static const uint64_t SYNC_VERSION;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif //CONF_PARAMETER_HPP
|
||||
#endif // NLSR_CONF_PARAMETER_HPP
|
||||
+55
-126
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,28 +16,32 @@
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
**/
|
||||
#include "hello-protocol.hpp"
|
||||
|
||||
#include "hello-protocol.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "hello-protocol.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("HelloProtocol");
|
||||
INIT_LOGGER(HelloProtocol);
|
||||
|
||||
const std::string HelloProtocol::INFO_COMPONENT = "INFO";
|
||||
const std::string HelloProtocol::NLSR_COMPONENT = "NLSR";
|
||||
|
||||
HelloProtocol::HelloProtocol(Nlsr& nlsr, ndn::Scheduler& scheduler)
|
||||
: m_nlsr(nlsr)
|
||||
, m_scheduler(scheduler)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
|
||||
{
|
||||
_LOG_DEBUG("Expressing Interest :" << interestName);
|
||||
NLSR_LOG_DEBUG("Expressing Interest :" << interestName);
|
||||
ndn::Interest i(interestName);
|
||||
i.setInterestLifetime(ndn::time::seconds(seconds));
|
||||
i.setMustBeFresh(true);
|
||||
@@ -49,6 +53,9 @@ HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
|
||||
this, _1),
|
||||
std::bind(&HelloProtocol::processInterestTimedOut,
|
||||
this, _1));
|
||||
|
||||
// increment SENT_HELLO_INTEREST
|
||||
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_INTEREST);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -66,13 +73,7 @@ HelloProtocol::sendScheduledInterest(uint32_t seconds)
|
||||
interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
|
||||
expressInterest(interestName,
|
||||
m_nlsr.getConfParameter().getInterestResendTime());
|
||||
}
|
||||
// If it does not have a Face, we need to give it one. A
|
||||
// successful registration prompts a callback that sends the hello
|
||||
// Interest to the new Face.
|
||||
else {
|
||||
registerPrefixes((*it).getName(), (*it).getConnectingFaceUri(),
|
||||
(*it).getLinkCost(), ndn::time::milliseconds::max());
|
||||
NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
|
||||
}
|
||||
}
|
||||
scheduleInterest(m_nlsr.getConfParameter().getInfoInterestInterval());
|
||||
@@ -81,7 +82,7 @@ HelloProtocol::sendScheduledInterest(uint32_t seconds)
|
||||
void
|
||||
HelloProtocol::scheduleInterest(uint32_t seconds)
|
||||
{
|
||||
_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
|
||||
NLSR_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
|
||||
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(seconds),
|
||||
std::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
|
||||
@@ -93,23 +94,36 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
{
|
||||
// interest name: /<neighbor>/NLSR/INFO/<router>
|
||||
const ndn::Name interestName = interest.getName();
|
||||
_LOG_DEBUG("Interest Received for Name: " << interestName);
|
||||
|
||||
// increment RCV_HELLO_INTEREST
|
||||
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_INTEREST);
|
||||
|
||||
NLSR_LOG_DEBUG("Interest Received for Name: " << interestName);
|
||||
if (interestName.get(-2).toUri() != INFO_COMPONENT) {
|
||||
NLSR_LOG_DEBUG("INFO_COMPONENT not found or interestName: " << interestName
|
||||
<< " does not match expression");
|
||||
return;
|
||||
}
|
||||
|
||||
ndn::Name neighbor;
|
||||
neighbor.wireDecode(interestName.get(-1).blockFromValue());
|
||||
_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
if (m_nlsr.getAdjacencyList().isNeighbor(neighbor)) {
|
||||
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
|
||||
data->setName(ndn::Name(interest.getName()).appendVersion());
|
||||
data->setFreshnessPeriod(ndn::time::seconds(10)); // 10 sec
|
||||
data->setContent(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.c_str()),
|
||||
INFO_COMPONENT.size());
|
||||
m_nlsr.getKeyChain().sign(*data, m_nlsr.getDefaultCertName());
|
||||
_LOG_DEBUG("Sending out data for name: " << interest.getName());
|
||||
|
||||
m_nlsr.getKeyChain().sign(*data, m_nlsr.getSigningInfo());
|
||||
|
||||
NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
|
||||
|
||||
m_nlsr.getNlsrFace().put(*data);
|
||||
Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
|
||||
// increment SENT_HELLO_DATA
|
||||
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
|
||||
|
||||
auto adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
|
||||
// If this neighbor was previously inactive, send our own hello interest, too
|
||||
if (adjacent->getStatus() == Adjacent::STATUS_INACTIVE) {
|
||||
// We can only do that if the neighbor currently has a face.
|
||||
@@ -122,12 +136,6 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
expressInterest(interestName,
|
||||
m_nlsr.getConfParameter().getInterestResendTime());
|
||||
}
|
||||
// If the originator of the Interest currently lacks a Face, we
|
||||
// need to give it one.
|
||||
else {
|
||||
registerPrefixes(adjacent->getName(), adjacent->getConnectingFaceUri(),
|
||||
adjacent->getLinkCost(), ndn::time::milliseconds::max());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,26 +145,27 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
|
||||
{
|
||||
// interest name: /<neighbor>/NLSR/INFO/<router>
|
||||
const ndn::Name interestName(interest.getName());
|
||||
_LOG_DEBUG("Interest timed out for Name: " << interestName);
|
||||
NLSR_LOG_DEBUG("Interest timed out for Name: " << interestName);
|
||||
if (interestName.get(-2).toUri() != INFO_COMPONENT) {
|
||||
return;
|
||||
}
|
||||
ndn::Name neighbor = interestName.getPrefix(-3);
|
||||
_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
m_nlsr.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
|
||||
|
||||
Adjacent::Status status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
|
||||
|
||||
uint32_t infoIntTimedOutCount =
|
||||
m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
|
||||
_LOG_DEBUG("Status: " << status);
|
||||
_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
|
||||
if ((infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber())) {
|
||||
NLSR_LOG_DEBUG("Status: " << status);
|
||||
NLSR_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
|
||||
if (infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber()) {
|
||||
// interest name: /<neighbor>/NLSR/INFO/<router>
|
||||
ndn::Name interestName(neighbor);
|
||||
interestName.append(NLSR_COMPONENT);
|
||||
interestName.append(INFO_COMPONENT);
|
||||
interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
|
||||
NLSR_LOG_DEBUG("Resending interest: " << interestName);
|
||||
expressInterest(interestName,
|
||||
m_nlsr.getConfParameter().getInterestResendTime());
|
||||
}
|
||||
@@ -164,6 +173,8 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
|
||||
(infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber())) {
|
||||
m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_INACTIVE);
|
||||
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor << " status changed to INACTIVE");
|
||||
|
||||
m_nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
}
|
||||
}
|
||||
@@ -174,10 +185,10 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
|
||||
void
|
||||
HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
|
||||
{
|
||||
_LOG_DEBUG("Received data for INFO(name): " << data.getName());
|
||||
NLSR_LOG_DEBUG("Received data for INFO(name): " << data.getName());
|
||||
if (data.getSignature().hasKeyLocator()) {
|
||||
if (data.getSignature().getKeyLocator().getType() == ndn::KeyLocator::KeyLocator_Name) {
|
||||
_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
|
||||
NLSR_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
|
||||
}
|
||||
}
|
||||
m_nlsr.getValidator().validate(data,
|
||||
@@ -186,17 +197,13 @@ HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
|
||||
this, _1, _2));
|
||||
}
|
||||
|
||||
// A validator is called on the incoming data, and if the data
|
||||
// passes the validator's description/definitions, this function is
|
||||
// called. Set the neighbor's status to active and refresh its
|
||||
// LSA. If there was a change in status, we schedule an adjacency
|
||||
// LSA build.
|
||||
void
|
||||
HelloProtocol::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
|
||||
HelloProtocol::onContentValidated(const ndn::Data& data)
|
||||
{
|
||||
// data name: /<neighbor>/NLSR/INFO/<router>/<version>
|
||||
ndn::Name dataName = data->getName();
|
||||
_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
|
||||
ndn::Name dataName = data.getName();
|
||||
NLSR_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
|
||||
|
||||
if (dataName.get(-3).toUri() == INFO_COMPONENT) {
|
||||
ndn::Name neighbor = dataName.getPrefix(-4);
|
||||
|
||||
@@ -205,8 +212,8 @@ HelloProtocol::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
|
||||
m_nlsr.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
|
||||
Adjacent::Status newStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
|
||||
|
||||
_LOG_DEBUG("Neighbor : " << neighbor);
|
||||
_LOG_DEBUG("Old Status: " << oldStatus << " New Status: " << newStatus);
|
||||
NLSR_LOG_DEBUG("Neighbor : " << neighbor);
|
||||
NLSR_LOG_DEBUG("Old Status: " << oldStatus << " New Status: " << newStatus);
|
||||
// change in Adjacency list
|
||||
if ((oldStatus - newStatus) != 0) {
|
||||
if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
@@ -217,93 +224,15 @@ HelloProtocol::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Simply logs a debug message that the content could not be
|
||||
// validated (and is implicitly being discarded as a result).
|
||||
void
|
||||
HelloProtocol::onContentValidationFailed(const std::shared_ptr<const ndn::Data>& data,
|
||||
const std::string& msg)
|
||||
{
|
||||
_LOG_DEBUG("Validation Error: " << msg);
|
||||
}
|
||||
|
||||
|
||||
// Asks the FIB to register the supplied adjacency (in other words,
|
||||
// create a Face for it).
|
||||
void
|
||||
HelloProtocol::registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
|
||||
double linkCost, const ndn::time::milliseconds& timeout)
|
||||
{
|
||||
m_nlsr.getFib().registerPrefix(adjName, faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0,
|
||||
std::bind(&HelloProtocol::onRegistrationSuccess,
|
||||
this, _1, adjName,timeout),
|
||||
std::bind(&HelloProtocol::onRegistrationFailure,
|
||||
this, _1, adjName));
|
||||
}
|
||||
|
||||
// After we create a new Face, we need to set it up for use. This
|
||||
// function sets the controlling strategy, registers prefixes in
|
||||
// sync, broadcast, and LSA.
|
||||
void
|
||||
HelloProtocol::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const ndn::Name& neighbor,const ndn::time::milliseconds& timeout)
|
||||
{
|
||||
Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
|
||||
if (adjacent != 0) {
|
||||
adjacent->setFaceId(commandSuccessResult.getFaceId());
|
||||
ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
|
||||
broadcastKeyPrefix.append("KEYS");
|
||||
std::string faceUri = adjacent->getConnectingFaceUri();
|
||||
double linkCost = adjacent->getLinkCost();
|
||||
m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getChronosyncPrefix(),
|
||||
faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
m_nlsr.getFib().registerPrefix(m_nlsr.getConfParameter().getLsaPrefix(),
|
||||
faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
m_nlsr.getFib().registerPrefix(broadcastKeyPrefix,
|
||||
faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
|
||||
// Sends a Hello Interest to determine status before the next scheduled.
|
||||
// interest name: /<neighbor>/NLSR/INFO/<router>
|
||||
ndn::Name interestName(neighbor);
|
||||
interestName.append(NLSR_COMPONENT);
|
||||
interestName.append(INFO_COMPONENT);
|
||||
interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
|
||||
expressInterest(interestName,
|
||||
m_nlsr.getConfParameter().getInterestResendTime());
|
||||
}
|
||||
// increment RCV_HELLO_DATA
|
||||
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_DATA);
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::onRegistrationFailure(const ndn::nfd::ControlResponse& response,
|
||||
const ndn::Name& name)
|
||||
HelloProtocol::onContentValidationFailed(const ndn::Data& data,
|
||||
const ndn::security::v2::ValidationError& ve)
|
||||
{
|
||||
_LOG_DEBUG(response.getText() << " (code: " << response.getCode() << ")");
|
||||
/*
|
||||
* If NLSR can not create face for given faceUri then it will treat this
|
||||
* failure as one INFO interest timed out. So that NLSR can move on with
|
||||
* building Adj Lsa and calculate routing table. NLSR does not build Adj
|
||||
* Lsa unless all the neighbors are ACTIVE or DEAD. For considering the
|
||||
* missconfigured(link) neighbour dead this is required.
|
||||
*/
|
||||
Adjacent *adjacent = m_nlsr.getAdjacencyList().findAdjacent(name);
|
||||
if (adjacent != 0) {
|
||||
adjacent->setInterestTimedOutNo(adjacent->getInterestTimedOutNo() + 1);
|
||||
Adjacent::Status status = adjacent->getStatus();
|
||||
uint32_t infoIntTimedOutCount = adjacent->getInterestTimedOutNo();
|
||||
|
||||
if (infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber()) {
|
||||
if (status == Adjacent::STATUS_ACTIVE) {
|
||||
adjacent->setStatus(Adjacent::STATUS_INACTIVE);
|
||||
}
|
||||
|
||||
m_nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
}
|
||||
}
|
||||
NLSR_LOG_DEBUG("Validation Error: " << ve);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+94
-43
@@ -22,12 +22,15 @@
|
||||
#ifndef NLSR_HELLO_PROTOCOL_HPP
|
||||
#define NLSR_HELLO_PROTOCOL_HPP
|
||||
|
||||
#include "statistics.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
#include <ndn-cxx/security/v2/validation-error.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
@@ -36,87 +39,135 @@ class Nlsr;
|
||||
class HelloProtocol
|
||||
{
|
||||
public:
|
||||
HelloProtocol(Nlsr& nlsr, ndn::Scheduler& scheduler)
|
||||
: m_nlsr(nlsr)
|
||||
, m_scheduler(scheduler)
|
||||
{
|
||||
}
|
||||
HelloProtocol(Nlsr& nlsr, ndn::Scheduler& scheduler);
|
||||
|
||||
/*! \brief Schedules a hello Interest event.
|
||||
|
||||
\param seconds The number of seconds to wait before calling the event.
|
||||
/*! \brief Schedules a Hello Interest event.
|
||||
*
|
||||
* This function serves as the Hello Interest loop, and must be
|
||||
* explicitly called to start the Hello cycle. This is done at
|
||||
* NLSR's initialization.
|
||||
*
|
||||
* \sa Nlsr::initialize
|
||||
* \param seconds The number of seconds to wait before calling the event.
|
||||
*/
|
||||
void
|
||||
scheduleInterest(uint32_t seconds);
|
||||
|
||||
/*! \brief Sends a hello Interest packet.
|
||||
|
||||
\param interestNamePrefix The name of the router that has published the
|
||||
update we want. Here that should be: \<router name\>/NLSR/INFO
|
||||
|
||||
\param seconds The lifetime of the Interest we construct, in seconds
|
||||
|
||||
This function attempts to contact neighboring routers to
|
||||
determine their status (which currently is one of: ACTIVE,
|
||||
INACTIVE, or UNKNOWN)
|
||||
/*! \brief Sends a Hello Interest packet.
|
||||
*
|
||||
* \param interestNamePrefix The name of the router that has published the
|
||||
* update we want. Here that should be: \<router name\>/NLSR/INFO
|
||||
*
|
||||
* \param seconds The lifetime of the Interest we construct, in seconds
|
||||
*
|
||||
* This function attempts to contact neighboring routers to
|
||||
* determine their status (which currently is one of: ACTIVE,
|
||||
* INACTIVE, or UNKNOWN)
|
||||
*/
|
||||
void
|
||||
expressInterest(const ndn::Name& interestNamePrefix, uint32_t seconds);
|
||||
|
||||
/*! \brief Sends a hello Interest packet that was previously scheduled.
|
||||
|
||||
\param seconds (ignored)
|
||||
|
||||
This function is called as part of a schedule to regularly
|
||||
determine the adjacency status of neighbors. This function checks
|
||||
if the specified neighbor has a Face, and if not creates one. If
|
||||
the neighbor had a Face, it calls \c expressInterest, else it will
|
||||
attempt to create a Face, which will itself attempt to contact the
|
||||
neighbor. Then the function schedules for this function to be invoked again.
|
||||
/*! \brief Sends Hello Interests to all neighbors
|
||||
*
|
||||
* \param seconds (ignored)
|
||||
*
|
||||
* This function is called as part of a schedule to regularly
|
||||
* determine the adjacency status of neighbors. This function
|
||||
* creates and sends a Hello Interest to each neighbor in
|
||||
* Nlsr::m_adjacencyList. If the neighbor has not been contacted
|
||||
* before and curerntly has no Face in NFD, this method will call a
|
||||
* different pipeline that creates the Face first, then registers
|
||||
* prefixes.
|
||||
*/
|
||||
void
|
||||
sendScheduledInterest(uint32_t seconds);
|
||||
|
||||
/*! \brief Processes a hello Interest from a neighbor.
|
||||
|
||||
\param name (ignored)
|
||||
|
||||
\param interest The Interest object that we have received and need to
|
||||
process.
|
||||
|
||||
Processes a hello Interest that this router receives from one of
|
||||
its neighbors. If the neighbor that sent the Interest does not
|
||||
have a Face, NLSR will attempt to register one. Also, if the
|
||||
neighbor that sent the Interest was previously marked as INACTIVE,
|
||||
NLSR will attempt to contact it with its own hello Interest.
|
||||
/*! \brief Processes a Hello Interest from a neighbor.
|
||||
*
|
||||
* \param name (ignored)
|
||||
*
|
||||
* \param interest The Interest object that we have received and need to
|
||||
* process.
|
||||
*
|
||||
* Processes a Hello Interest that this router receives from one of
|
||||
* its neighbors. If the neighbor that sent the Interest does not
|
||||
* have a Face, NLSR will attempt to create one. Also, if the
|
||||
* neighbor that sent the Interest was previously marked as
|
||||
* INACTIVE, NLSR will attempt to contact it with its own Hello
|
||||
* Interest.
|
||||
*/
|
||||
void
|
||||
processInterest(const ndn::Name& name, const ndn::Interest& interest);
|
||||
|
||||
ndn::util::signal::Signal<HelloProtocol, Statistics::PacketType> hpIncrementSignal;
|
||||
|
||||
private:
|
||||
/*! \brief Try to contact a neighbor via Hello protocol again
|
||||
*
|
||||
* This function will re-send Hello Interests a configured number
|
||||
* of times. After that many failures, HelloProtocol will mark the neighbor as
|
||||
* inactive and will not attempt to contact them until the next time
|
||||
* HelloProtocol::sendScheduledInterest is called.
|
||||
*
|
||||
* \sa nlsr::ConfParameter::getInterestRetryNumber
|
||||
*/
|
||||
void
|
||||
processInterestTimedOut(const ndn::Interest& interest);
|
||||
|
||||
/*! \brief Verify signatures and validate incoming Hello data.
|
||||
*/
|
||||
void
|
||||
onContent(const ndn::Interest& interest, const ndn::Data& data);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
|
||||
/*! \brief Change a neighbor's status
|
||||
*
|
||||
* Whenever incoming Hello data is verified and validated, change
|
||||
* the status of this neighbor and then schedule an adjacency LSA
|
||||
* build for us. This also resets the number of times we've failed
|
||||
* to contact this neighbor so that we will retry later.
|
||||
*/
|
||||
void
|
||||
onContentValidated(const std::shared_ptr<const ndn::Data>& data);
|
||||
onContentValidated(const ndn::Data& data);
|
||||
|
||||
private:
|
||||
/*! \brief Log that incoming data couldn't be validated, but do nothing else.
|
||||
*/
|
||||
void
|
||||
onContentValidationFailed(const std::shared_ptr<const ndn::Data>& data,
|
||||
const std::string& msg);
|
||||
onContentValidationFailed(const ndn::Data& data,
|
||||
const ndn::security::v2::ValidationError& ve);
|
||||
|
||||
/*! \brief Treat a failed Face registration as an INACTIVE neighbor.
|
||||
*
|
||||
* If NLSR fails to register a Face when contacting a neighbor, it
|
||||
* will instantly toggle that neighbor to INACTIVE. This is
|
||||
* necessary because NLSR will put off building its own adjacency
|
||||
* LSA until the status of each neighbor is definitively
|
||||
* known. Without this, NLSR might have to wait many scheduled Hello
|
||||
* intervals to finish building an adjacency LSA.
|
||||
*/
|
||||
void
|
||||
onRegistrationFailure(const ndn::nfd::ControlResponse& response,
|
||||
const ndn::Name& name);
|
||||
|
||||
/*! \brief Set up a Face for NLSR use.
|
||||
*
|
||||
* When NLSR receives a Hello Interest from a neighbor that it has
|
||||
* not seen before, it may need to create a Face for that
|
||||
* neighbor. After doing so, it will be necessary to inform NFD
|
||||
* about the standard prefixes that NLSR needs a node to have in
|
||||
* order to conduct normal operations. This function accomplishes
|
||||
* that, and then sends its own Hello Interest to confirm the
|
||||
* contact.
|
||||
*/
|
||||
void
|
||||
onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const ndn::Name& neighbor, const ndn::time::milliseconds& timeout);
|
||||
|
||||
/*! \brief Create a Face for an adjacency
|
||||
* \sa HelloProtocol::onRegistrationSuccess
|
||||
*/
|
||||
void
|
||||
registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
|
||||
double linkCost, const ndn::time::milliseconds& timeout);
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, 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/>.
|
||||
*
|
||||
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
*
|
||||
**/
|
||||
#include <log4cxx/logger.h>
|
||||
#include <log4cxx/basicconfigurator.h>
|
||||
#include <log4cxx/xml/domconfigurator.h>
|
||||
#include <log4cxx/propertyconfigurator.h>
|
||||
#include <log4cxx/patternlayout.h>
|
||||
#include <log4cxx/level.h>
|
||||
#include <log4cxx/helpers/exception.h>
|
||||
#include <log4cxx/rollingfileappender.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "logger.hpp"
|
||||
|
||||
void
|
||||
INIT_LOG4CXX(const std::string& log4cxxConfPath)
|
||||
{
|
||||
if (boost::filesystem::path(log4cxxConfPath).extension().string() == ".xml") {
|
||||
log4cxx::xml::DOMConfigurator::configure(log4cxxConfPath);
|
||||
}
|
||||
else {
|
||||
log4cxx::PropertyConfigurator::configure(log4cxxConfPath);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
INIT_LOGGERS(const std::string& logDir, const std::string& logLevel)
|
||||
{
|
||||
static bool configured = false;
|
||||
|
||||
if (configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
log4cxx::PatternLayoutPtr
|
||||
layout(new log4cxx::PatternLayout("%date{yyyyMMddHHmmssSSS} %p: [%c] %m%n"));
|
||||
|
||||
log4cxx::RollingFileAppender* rollingFileAppender =
|
||||
new log4cxx::RollingFileAppender(layout, logDir+"/nlsr.log", true);
|
||||
|
||||
rollingFileAppender->setMaxFileSize("10MB");
|
||||
rollingFileAppender->setMaxBackupIndex(10);
|
||||
|
||||
log4cxx::helpers::Pool p;
|
||||
rollingFileAppender->activateOptions(p);
|
||||
|
||||
log4cxx::BasicConfigurator::configure(log4cxx::AppenderPtr(rollingFileAppender));
|
||||
|
||||
if (boost::iequals(logLevel, "none")) {
|
||||
log4cxx::Logger::getRootLogger()->setLevel(log4cxx::Level::getOff());
|
||||
}
|
||||
else {
|
||||
log4cxx::Logger::getRootLogger()->setLevel(log4cxx::Level::toLevel(logLevel));
|
||||
}
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
||||
bool
|
||||
isValidLogLevel(const std::string& logLevel)
|
||||
{
|
||||
return boost::iequals(logLevel, "all") || boost::iequals(logLevel, "trace") ||
|
||||
boost::iequals(logLevel, "debug") || boost::iequals(logLevel, "info") ||
|
||||
boost::iequals(logLevel, "warn") || boost::iequals(logLevel, "error") ||
|
||||
boost::iequals(logLevel, "none");
|
||||
}
|
||||
+18
-33
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,44 +16,29 @@
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
**/
|
||||
|
||||
/*! \file logger.hpp
|
||||
* \brief Define macros and auxiliary functions for logging.
|
||||
*
|
||||
* This file defines the macros that NLSR uses for logging
|
||||
* messages. An intrepid hacker could replace this system cleanly by
|
||||
* providing a system that redefines all of the _LOG_* macros with an
|
||||
* arbitrary system, as long as the underlying system accepts strings.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_LOGGER_HPP
|
||||
#define NLSR_LOGGER_HPP
|
||||
|
||||
#include <log4cxx/logger.h>
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
|
||||
#define INIT_LOGGER(name) \
|
||||
static log4cxx::LoggerPtr staticModuleLogger = log4cxx::Logger::getLogger(name)
|
||||
#define INIT_LOGGER(name) NDN_LOG_INIT(nlsr.name)
|
||||
|
||||
#define _LOG_TRACE(x) \
|
||||
LOG4CXX_TRACE(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_DEBUG(x) \
|
||||
LOG4CXX_DEBUG(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_INFO(x) \
|
||||
LOG4CXX_INFO(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_WARN(x) \
|
||||
LOG4CXX_WARN(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_ERROR(x) \
|
||||
LOG4CXX_ERROR(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_FATAL(x) \
|
||||
LOG4CXX_FATAL(staticModuleLogger, x);
|
||||
|
||||
void
|
||||
INIT_LOGGERS(const std::string& logDir, const std::string& logLevel);
|
||||
|
||||
void
|
||||
INIT_LOG4CXX(const std::string& log4cxxConfPath);
|
||||
|
||||
bool
|
||||
isValidLogLevel(const std::string& logLevel);
|
||||
#define NLSR_LOG_TRACE(x) NDN_LOG_TRACE(x)
|
||||
#define NLSR_LOG_DEBUG(x) NDN_LOG_DEBUG(x)
|
||||
#define NLSR_LOG_INFO(x) NDN_LOG_INFO(x)
|
||||
#define NLSR_LOG_WARN(x) NDN_LOG_WARN(x)
|
||||
#define NLSR_LOG_ERROR(x) NDN_LOG_ERROR(x)
|
||||
#define NLSR_LOG_FATAL(x) NDN_LOG_FATAL(x)
|
||||
|
||||
#endif // NLSR_LOGGER_HPP
|
||||
Loaded 100 of 239 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user