Compare commits
137
Commits
NLSR-0.2.0
...
NLSR-0.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
f023a88ec1 | ||
|
|
4c2bb361ae | ||
|
|
1de901f161 | ||
|
|
9f93666519 | ||
|
|
48daea20d7 | ||
|
|
218aaef118 | ||
|
|
87911dacd5 | ||
|
|
54e726cf5e | ||
|
|
a4cf402084 | ||
|
|
f590fecfc2 | ||
|
|
6077ea910c | ||
|
|
d1f4f33cfd | ||
|
|
d8c9d8cdab | ||
|
|
feae5574b8 | ||
|
|
4fc69e49a9 | ||
|
|
c6a852234d | ||
|
|
44395237b8 | ||
|
|
c5fa320239 | ||
|
|
41330f4256 | ||
|
|
96bf2f0db8 | ||
|
|
2b057af9e1 | ||
|
|
b71684744f | ||
|
|
b50e51b374 | ||
|
|
3e5120c543 | ||
|
|
ef21d8eab0 | ||
|
|
97e3494256 | ||
|
|
d69f9a3c82 | ||
|
|
63bd0348b3 | ||
|
|
b9d43d06cc | ||
|
|
e2d3fe9d9a | ||
|
|
7b5872ec86 | ||
|
|
fad8e257c0 | ||
|
|
f8b5bcd27e | ||
|
|
800833b7ac | ||
|
|
e8e03ac303 | ||
|
|
5ec9ae4271 | ||
|
|
f7eec4f4c0 | ||
|
|
5c467f0ca8 | ||
|
|
aa3b085384 | ||
|
|
d02c3880d5 | ||
|
|
3ac0728e5a | ||
|
|
c778e814db | ||
|
|
af909fcc13 | ||
|
|
c69da0a350 | ||
|
|
0ff5d45ba8 | ||
|
|
5d9c0573c0 | ||
|
|
4c7caadb72 | ||
|
|
f9f3910dd2 | ||
|
|
53c0e3e9ee | ||
|
|
c57c64b633 | ||
|
|
97473d47fd | ||
|
|
5363c7946b | ||
|
|
f4772d4f21 | ||
|
|
46ccaae829 | ||
|
|
c69c9af931 | ||
|
|
d33e5bc475 | ||
|
|
dce3f18229 | ||
|
|
cae33b69f2 | ||
|
|
18df0602d3 | ||
|
|
41b173ed54 | ||
|
|
9630fbf4e0 | ||
|
|
a6f3e645f5 |
No files matched your search
@@ -3,7 +3,8 @@ set -e
|
||||
|
||||
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
|
||||
for i in $( find "$DIR/.jenkins.d" -type f -perm +111 | sort ); do
|
||||
echo "Run: $i"
|
||||
"$i"
|
||||
for file in "$DIR"/.jenkins.d/*; do
|
||||
[[ -f $file && -x $file ]] || continue
|
||||
echo "Run: $file"
|
||||
"$file"
|
||||
done
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/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 cryptopp log4cxx 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 link --force log4cxx
|
||||
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 \
|
||||
libcrypto++-dev libsqlite3-dev libssl-dev \
|
||||
liblog4cxx10-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,27 +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 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
+44
@@ -0,0 +1,44 @@
|
||||
#!/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
|
||||
|
||||
# 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
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
elif [[ -n $BUILD_WITH_ASAN || -z $TRAVIS ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
fi
|
||||
./waf --color=yes configure --debug --with-tests $COVERAGE $ASAN
|
||||
./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,31 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
set -e
|
||||
|
||||
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 --without-osx-keychain
|
||||
./waf -j1 --color=yes
|
||||
sudo ./waf install -j1 --color=yes
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
@@ -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}
|
||||
}
|
||||
+35
-11
@@ -1,15 +1,39 @@
|
||||
sudo: true
|
||||
language: cpp
|
||||
os:
|
||||
- linux
|
||||
compiler:
|
||||
- gcc
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
||||
on_failure: always
|
||||
sudo: required
|
||||
language: generic
|
||||
env:
|
||||
global:
|
||||
- NODE_LABELS="Linux Ubuntu Ubuntu-12.04 Ubuntu-12.04-64bit Boost1.48"
|
||||
- JOB_NAME=limited-build
|
||||
- WAF_JOBS=2
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Linux/gcc
|
||||
- os: linux
|
||||
dist: trusty
|
||||
env:
|
||||
- CXX=g++-4.8
|
||||
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
|
||||
- BUILD_WITH_ASAN=yes
|
||||
|
||||
# Linux/clang
|
||||
- os: linux
|
||||
dist: trusty
|
||||
env:
|
||||
- CXX=clang++
|
||||
- NODE_LABELS="Linux Ubuntu Ubuntu-14.04"
|
||||
- BUILD_WITH_ASAN=yes
|
||||
|
||||
# macOS/clang
|
||||
# https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
env:
|
||||
- NODE_LABELS="OSX OSX-10.12"
|
||||
- BUILD_WITH_ASAN=yes
|
||||
|
||||
before_script:
|
||||
- ${CXX:-c++} --version
|
||||
- python --version
|
||||
|
||||
script:
|
||||
- ./.jenkins
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -1,53 +1,78 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
from waflib import Logs, Configure
|
||||
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):
|
||||
areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
|
||||
defaultFlags = ['-std=c++0x', '-std=c++11',
|
||||
'-stdlib=libc++', # clang on OSX < 10.9 by default uses a non
|
||||
# C++11-compatible STL library
|
||||
'-Wall', '-Wno-long-long']
|
||||
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()
|
||||
|
||||
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)
|
||||
|
||||
# General flags are always applied (e.g., selecting C++11 mode)
|
||||
generalFlags = flags.getGeneralFlags(conf)
|
||||
conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
|
||||
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
|
||||
conf.env.DEFINES += generalFlags['DEFINES']
|
||||
|
||||
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
|
||||
# corresponding environment variables are not set.
|
||||
# DEFINES are always applied.
|
||||
if conf.options.debug:
|
||||
conf.define('_DEBUG', 1)
|
||||
defaultFlags += ['-O0',
|
||||
'-Og', # gcc >= 4.8
|
||||
'-g3',
|
||||
'-fcolor-diagnostics', # clang
|
||||
'-fdiagnostics-color', # gcc >= 4.9
|
||||
'-Werror',
|
||||
'-Wno-error=deprecated-register',
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
'-Wno-error=unneeded-internal-declaration', # Bug #1588
|
||||
'-Wno-nested-anon-types',
|
||||
]
|
||||
extraFlags = flags.getDebugFlags(conf)
|
||||
if areCustomCxxflagsPresent:
|
||||
missingFlags = [x for x in defaultFlags if x not in conf.env.CXXFLAGS]
|
||||
missingFlags = [x for x in extraFlags['CXXFLAGS'] if x not in conf.env.CXXFLAGS]
|
||||
if len(missingFlags) > 0:
|
||||
Logs.warn("Selected debug mode, but CXXFLAGS is set to a custom value '%s'"
|
||||
% " ".join(conf.env.CXXFLAGS))
|
||||
Logs.warn("Default flags '%s' are not activated" % " ".join(missingFlags))
|
||||
else:
|
||||
conf.add_supported_cxxflags(defaultFlags)
|
||||
else:
|
||||
defaultFlags += ['-O2', '-g']
|
||||
if not areCustomCxxflagsPresent:
|
||||
conf.add_supported_cxxflags(defaultFlags)
|
||||
extraFlags = flags.getOptimizedFlags(conf)
|
||||
|
||||
# clang on OSX < 10.9 by default uses a non C++11-compatible STL library
|
||||
conf.add_supported_linkflags(['-stdlib=libc++'])
|
||||
if not areCustomCxxflagsPresent:
|
||||
conf.add_supported_cxxflags(extraFlags['CXXFLAGS'])
|
||||
conf.add_supported_linkflags(extraFlags['LINKFLAGS'])
|
||||
|
||||
conf.env.DEFINES += extraFlags['DEFINES']
|
||||
|
||||
@Configure.conf
|
||||
def add_supported_cxxflags(self, cxxflags):
|
||||
"""
|
||||
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
|
||||
"""
|
||||
self.start_msg('Checking allowed compile-stage flags for c++ compiler')
|
||||
if len(cxxflags) == 0:
|
||||
return
|
||||
|
||||
self.start_msg('Checking supported CXXFLAGS')
|
||||
|
||||
supportedFlags = []
|
||||
for flag in cxxflags:
|
||||
@@ -55,14 +80,17 @@ 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):
|
||||
"""
|
||||
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
|
||||
"""
|
||||
self.start_msg('Checking allowed link-stage flags for c++ compiler')
|
||||
if len(linkflags) == 0:
|
||||
return
|
||||
|
||||
self.start_msg('Checking supported LINKFLAGS')
|
||||
|
||||
supportedFlags = []
|
||||
for flag in linkflags:
|
||||
@@ -70,4 +98,105 @@ 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):
|
||||
def getGeneralFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['_DEBUG']}
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
|
||||
|
||||
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-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):
|
||||
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O2',
|
||||
'-g',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
|
||||
return flags
|
||||
|
||||
class GccFlags(GccBasicFlags):
|
||||
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'] += ['-fdiagnostics-color'] # gcc >= 4.9
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccFlags, self).getOptimizedFlags(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'] += ['-fdiagnostics-color'] # gcc >= 4.9
|
||||
return flags
|
||||
|
||||
class ClangFlags(GccBasicFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getGeneralFlags(conf)
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
flags['CXXFLAGS'] += ['-stdlib=libc++']
|
||||
flags['LINKFLAGS'] += ['-stdlib=libc++']
|
||||
return flags
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-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-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wno-keyword-macro',
|
||||
'-Wno-nested-anon-types',
|
||||
'-Wno-sign-compare',
|
||||
'-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)
|
||||
+21
-9
@@ -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,21 +26,31 @@ 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>
|
||||
|
||||
* 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.linkedin.com/in/shijunxiao>
|
||||
|
||||
* University Pierre & Marie Curie, Sorbonne University
|
||||
|
||||
* Davide Pesavento <https://www.linkedin.com/in/davidepesavento>
|
||||
|
||||
## Queries about NLSR
|
||||
|
||||
Any general question related to NLSR should be directed to Vince Lehman
|
||||
(vslehman@memphis.edu) and security related question should be directed to
|
||||
Yingdi Yu (yingdi@cs.ucla.edu)
|
||||
Any question related to NLSR should be directed to Ashlesh Gawande (agawande@memphis.edu),
|
||||
Muktadir R Chowdhury (mrchwdhr@memphis.edu), and Nicholas Gordon (nmgordon@memphis.edu).
|
||||
@@ -19,9 +19,6 @@ licenses:
|
||||
- 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)
|
||||
|
||||
- waf build system is licensed under the conditions of
|
||||
|
||||
@@ -41,3 +41,7 @@ Additional information
|
||||
- [NLSR Wiki](http://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 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
|
||||
-------------
|
||||
|
||||
|
||||
+6
-28
@@ -12,6 +12,12 @@ Prerequisites
|
||||
Refer to `Getting started with NFD <http://named-data.net/doc/NFD/current/INSTALL.html>`_
|
||||
for detailed installation and running instruction.
|
||||
|
||||
- ChronoSync library
|
||||
|
||||
::
|
||||
|
||||
https://github.com/named-data/ChronoSync#build
|
||||
|
||||
- log4cxx library
|
||||
|
||||
On Ubuntu Linux:
|
||||
@@ -26,34 +32,6 @@ for detailed installation and running instruction.
|
||||
|
||||
sudo port install log4cxx
|
||||
|
||||
- protobuf
|
||||
|
||||
On Ubuntu Linux:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install libprotobuf-dev protobuf-compiler
|
||||
|
||||
On OS X with MacPorts:
|
||||
|
||||
::
|
||||
|
||||
sudo port install protobuf-cpp
|
||||
|
||||
- openssl
|
||||
|
||||
On Ubuntu Linux:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install libssl-dev
|
||||
|
||||
On OS X with MacPorts:
|
||||
|
||||
::
|
||||
|
||||
sudo port install openssl
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
|
||||
+3
-127
@@ -1,128 +1,4 @@
|
||||
Release Notes
|
||||
=============
|
||||
NLSR Release Notes
|
||||
==================
|
||||
|
||||
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
|
||||
+110
-17
@@ -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.
|
||||
|
||||
@@ -87,6 +87,7 @@ configuration commands follows:
|
||||
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
|
||||
@@ -104,13 +105,25 @@ 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 5 ; default value 5. Valid values 0-5. It is recommended that
|
||||
; 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
|
||||
|
||||
first-hello-interval 10 ; Default value 10. Valid values 0-10
|
||||
|
||||
; neighbor command is used to configure router's neighbor. Each neighbor will need
|
||||
; one block of neighbor command
|
||||
|
||||
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
|
||||
@@ -118,7 +131,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
|
||||
@@ -135,9 +148,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
|
||||
@@ -152,8 +165,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
|
||||
|
||||
}
|
||||
|
||||
@@ -170,10 +183,90 @@ configuration commands follows:
|
||||
prefix /ndn/news/memphis/politics/lutherking
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
Security configuration is discussed in :doc:`SECURITY-CONFIG`, which will be also part
|
||||
of this configuration file
|
||||
NLSR will have the following error if ``log-dir`` does not exist:
|
||||
|
||||
::
|
||||
|
||||
Provided log directory </var/log/nlsr/> does not exist
|
||||
Error in configuration file processing! Exiting from NLSR
|
||||
|
||||
By default ``/var/log/nlsr/`` is set to be NLSR's log directory and ``/var/lib/nlsr/`` is set to be
|
||||
NLSR's sequence file directory. They do not exist and will need to be created.
|
||||
Also, since these are system directories it will require the user to run NLSR as root.
|
||||
If one does not have permission to write to the specified directory,
|
||||
then NLSR will produce the following error:
|
||||
|
||||
::
|
||||
|
||||
User does not have read and write permission on the directory
|
||||
Error in configuration file processing! Exiting from NLSR
|
||||
|
||||
To avoid this, the directories can be set in a user owned directory.
|
||||
The directories for log and sequence file can be same.
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
general
|
||||
{
|
||||
...
|
||||
|
||||
log-dir /home/username/nlsr/log ; path for log directory (Absolute path)
|
||||
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
|
||||
-------------------------------------------------
|
||||
@@ -195,9 +288,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:
|
||||
|
||||
@@ -207,7 +300,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
|
||||
@@ -37,6 +37,11 @@ NLSR /\<network\>/\<site\>/%C1.Router/\<router-name\>/NLSR /ndn/edu/ucla/%C
|
||||
|
||||
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/"
|
||||
+16
-17
@@ -408,7 +408,7 @@ EXTRACT_PRIVATE = NO
|
||||
# scope will be included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_PACKAGE = NO
|
||||
EXTRACT_PACKAGE = YES
|
||||
|
||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
|
||||
# included in the documentation.
|
||||
@@ -1782,18 +1782,6 @@ GENERATE_XML = NO
|
||||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||
# listings (including syntax highlighting and cross-referencing information) to
|
||||
# the XML output. Note that enabling this will significantly increase the size
|
||||
@@ -1928,7 +1916,18 @@ INCLUDE_FILE_PATTERNS =
|
||||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED =
|
||||
PREDEFINED = DOXYGEN=1 \
|
||||
INIT_LOGGER(x)= \
|
||||
BOOST_STATIC_ASSERT(x)= \
|
||||
BOOST_CONCEPT_ASSERT(x)= \
|
||||
BOOST_CONCEPT_REQUIRES(x)= \
|
||||
DECL_OVERRIDE=override \
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE=private \
|
||||
PUBLIC_WITH_TESTS_ELSE_PROTECTED=protected \
|
||||
PROTECTED_WITH_TESTS_ELSE_PRIVATE=private \
|
||||
VIRTUAL_WITH_TESTS \
|
||||
DECL_CLASS_FINAL=final \
|
||||
DECL_FINAL=final
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
@@ -2026,7 +2025,7 @@ MSCGEN_PATH =
|
||||
# and usage relations if the target is undocumented or is not a class.
|
||||
# The default value is: YES.
|
||||
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = NO
|
||||
|
||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||
# available from the path. This tool is part of Graphviz (see:
|
||||
@@ -2151,7 +2150,7 @@ INCLUDED_BY_GRAPH = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
CALL_GRAPH = NO
|
||||
CALL_GRAPH = YES
|
||||
|
||||
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
|
||||
# dependency graph for every global function or class method.
|
||||
@@ -2162,7 +2161,7 @@ CALL_GRAPH = NO
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
CALLER_GRAPH = NO
|
||||
CALLER_GRAPH = YES
|
||||
|
||||
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
|
||||
# hierarchy of all classes instead of a textual one.
|
||||
|
||||
+28
-7
@@ -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,18 +29,20 @@ NLSR Documentation
|
||||
:hidden:
|
||||
:maxdepth: 3
|
||||
|
||||
RELEASE-NOTES
|
||||
INSTALL
|
||||
GETTING-STARTED
|
||||
INSTALL
|
||||
ROUTER-CONFIG
|
||||
SECURITY-CONFIG
|
||||
RELEASE-NOTES
|
||||
releases
|
||||
manpages
|
||||
|
||||
- :doc:`INSTALL`
|
||||
- :doc:`GETTING-STARTED`
|
||||
- :doc:`INSTALL`
|
||||
- :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
|
||||
@@ -45,6 +45,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,63 @@
|
||||
NLSR Versions
|
||||
+++++++++++++
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 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.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>`__)
|
||||
@@ -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
|
||||
@@ -39,7 +39,7 @@ general
|
||||
;log4cxx-conf /path/to/log4cxx-conf ; path for log4cxx configuration file (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 +65,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 +111,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
|
||||
{
|
||||
@@ -140,7 +150,7 @@ security
|
||||
{
|
||||
rule
|
||||
{
|
||||
id "NSLR Hello Rule"
|
||||
id "NLSR Hello Rule"
|
||||
for data
|
||||
filter
|
||||
{
|
||||
@@ -156,7 +166,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><><>$
|
||||
@@ -168,7 +178,7 @@ security
|
||||
|
||||
rule
|
||||
{
|
||||
id "NSLR LSA Rule"
|
||||
id "NLSR LSA Rule"
|
||||
for data
|
||||
filter
|
||||
{
|
||||
@@ -184,10 +194,11 @@ 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><LSA>]*)<NLSR><LSA>(<>*)<><><>$
|
||||
; the last four components in the prefix should be <lsaType><seqNo><version><segmentNo>
|
||||
p-regex ^<localhop>([^<NLSR><LSA>]*)<NLSR><LSA>(<>*)<><><><>$
|
||||
p-expand \\1\\2
|
||||
}
|
||||
}
|
||||
@@ -196,12 +207,12 @@ security
|
||||
|
||||
rule
|
||||
{
|
||||
id "NSLR Hierarchy Exception Rule"
|
||||
id "NLSR Hierarchy Exception Rule"
|
||||
for data
|
||||
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
|
||||
{
|
||||
@@ -212,10 +223,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
|
||||
}
|
||||
}
|
||||
@@ -224,12 +235,12 @@ security
|
||||
|
||||
rule
|
||||
{
|
||||
id "NSLR Hierarchical Rule"
|
||||
id "NLSR Hierarchical Rule"
|
||||
for data
|
||||
filter
|
||||
{
|
||||
type name
|
||||
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
|
||||
regex ^[^<KEY>]*<KEY><><><>$
|
||||
}
|
||||
checker
|
||||
{
|
||||
@@ -254,7 +265,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
|
||||
{
|
||||
@@ -263,7 +276,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><>$
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +288,7 @@ security
|
||||
filter
|
||||
{
|
||||
type name
|
||||
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
|
||||
regex ^[^<KEY>]*<KEY><><><>$
|
||||
}
|
||||
checker
|
||||
{
|
||||
@@ -290,6 +303,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 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,749 +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 <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, 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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
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, 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,174 +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>
|
||||
|
||||
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,
|
||||
onValidated, onValidationFailed));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SyncSocket::onData(const ndn::Interest& interest, 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));
|
||||
|
||||
}
|
||||
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, 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
|
||||
+73
-68
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
@@ -16,25 +17,20 @@
|
||||
*
|
||||
* 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 <algorithm>
|
||||
#include <ndn-cxx/common.hpp>
|
||||
|
||||
#include "adjacency-list.hpp"
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "common.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("AdjacencyList");
|
||||
|
||||
using namespace std;
|
||||
|
||||
AdjacencyList::AdjacencyList()
|
||||
{
|
||||
}
|
||||
@@ -88,32 +84,35 @@ 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==(AdjacencyList& adl) const
|
||||
{
|
||||
if (getSize() != adl.getSize()) {
|
||||
if (size() != adl.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;
|
||||
|
||||
auto comparator =
|
||||
[] (const Adjacent* lhs, const Adjacent* rhs) {
|
||||
return *lhs < *rhs;
|
||||
};
|
||||
|
||||
std::vector<const Adjacent*> ourList;
|
||||
std::transform(m_adjList.begin(), m_adjList.end(),
|
||||
std::back_inserter(ourList), std::pointer_traits<const Adjacent*>::pointer_to);
|
||||
|
||||
std::vector<const Adjacent*> theirList;
|
||||
std::transform(adl.getAdjList().begin(), adl.getAdjList().end(),
|
||||
std::back_inserter(theirList), std::pointer_traits<const Adjacent*>::pointer_to);
|
||||
|
||||
std::sort(ourList.begin(), ourList.end(), std::bind(comparator, _1, _2));
|
||||
std::sort(theirList.begin(), theirList.end(), std::bind(comparator, _1, _2));
|
||||
|
||||
for (size_t i = 0; i < ourList.size(); i++) {
|
||||
if (*(ourList[i]) != *(theirList[i])) {
|
||||
return false;
|
||||
}
|
||||
equalAdjCount++;
|
||||
}
|
||||
return equalAdjCount == getSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t
|
||||
@@ -196,26 +195,33 @@ AdjacencyList::getAdjList()
|
||||
return m_adjList;
|
||||
}
|
||||
|
||||
bool
|
||||
AdjacencyList::isAdjLsaBuildable(Nlsr& pnlsr)
|
||||
const std::list<Adjacent>&
|
||||
AdjacencyList::getAdjList() const
|
||||
{
|
||||
uint32_t nbrCount = 0;
|
||||
for (std::list<Adjacent>::iterator it = m_adjList.begin(); it != m_adjList.end() ; it++) {
|
||||
return m_adjList;
|
||||
}
|
||||
|
||||
if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
nbrCount++;
|
||||
bool
|
||||
AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
|
||||
{
|
||||
uint32_t nTimedOutNeighbors = 0;
|
||||
|
||||
for (const Adjacent& adjacency : m_adjList) {
|
||||
|
||||
if (adjacency.getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if ((*it).getInterestTimedOutNo() >=
|
||||
pnlsr.getConfParameter().getInterestRetryNumber()) {
|
||||
nbrCount++;
|
||||
}
|
||||
else if (adjacency.getInterestTimedOutNo() >= interestRetryNo) {
|
||||
nTimedOutNeighbors++;
|
||||
}
|
||||
}
|
||||
if (nbrCount == m_adjList.size()) {
|
||||
|
||||
if (nTimedOutNeighbors == m_adjList.size()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
@@ -236,45 +242,44 @@ AdjacencyList::find(const ndn::Name& adjName)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
ndn::bind(&Adjacent::compare,
|
||||
_1, ndn::cref(adjName)));
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
return it;
|
||||
}
|
||||
|
||||
Adjacent *
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(const ndn::Name& adjName)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
ndn::bind(&Adjacent::compare,
|
||||
_1, ndn::cref(adjName)));
|
||||
if (it != m_adjList.end()) {
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
}
|
||||
|
||||
Adjacent *
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(uint64_t faceId)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
ndn::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(),
|
||||
ndn::bind(&Adjacent::compareFaceUri,
|
||||
std::bind(&Adjacent::compareFaceUri,
|
||||
_1, faceUri));
|
||||
if (it != m_adjList.end()) {
|
||||
return it->getFaceId();
|
||||
@@ -286,11 +291,11 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace nlsr
|
||||
} // namespace nlsr
|
||||
+92
-19
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
@@ -16,32 +17,50 @@
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
**/
|
||||
|
||||
#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 {
|
||||
class Nlsr;
|
||||
|
||||
class AdjacencyList
|
||||
{
|
||||
|
||||
public:
|
||||
typedef std::list<Adjacent>::const_iterator const_iterator;
|
||||
typedef std::list<Adjacent>::iterator iterator;
|
||||
|
||||
AdjacencyList();
|
||||
~AdjacencyList();
|
||||
|
||||
/*! \brief Inserts an adjacency into the list.
|
||||
|
||||
\param adjacent The adjacency that we want to add to this list.
|
||||
|
||||
\retval 0 Indicates success.
|
||||
\retval 1 Indicates failure.
|
||||
|
||||
This function attempts to insert the supplied adjacency into this
|
||||
object, which is an adjacency list.
|
||||
*/
|
||||
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);
|
||||
|
||||
@@ -51,6 +70,9 @@ public:
|
||||
std::list<Adjacent>&
|
||||
getAdjList();
|
||||
|
||||
const std::list<Adjacent>&
|
||||
getAdjList() const;
|
||||
|
||||
bool
|
||||
isNeighbor(const ndn::Name& adjName);
|
||||
|
||||
@@ -69,11 +91,33 @@ public:
|
||||
void
|
||||
setTimedOutInterestCount(const ndn::Name& neighbor, uint32_t count);
|
||||
|
||||
/*! \brief Copies the adjacencies in a list to this one.
|
||||
|
||||
\param adl The adjacency list, the entries of which we want to
|
||||
copy into this object.
|
||||
|
||||
Copies the entries contained in one list into this object.
|
||||
*/
|
||||
void
|
||||
addAdjacents(AdjacencyList& adl);
|
||||
|
||||
/*! \brief Determines whether this list can be used to build an adj. LSA.
|
||||
\param interestRetryNo The maximum number of hello-interest
|
||||
retries to contact a neighbor.
|
||||
|
||||
\return Returns a boolean indicating whether this list can be used
|
||||
to build an adj. LSA.
|
||||
|
||||
Determines whether this adjacency list object could be used to
|
||||
build an adjacency LSA. An LSA is buildable when the status of all
|
||||
neighbors is known. A neighbor's status is known when their status
|
||||
is ACTIVE, or INACTIVE and some number of hello interests
|
||||
(specified by nlsr::ConfParameter::getInterestRetryNumber()) have
|
||||
failed. To be explicit, a neighbor's status is unknown if we are
|
||||
still sending hello interests.
|
||||
*/
|
||||
bool
|
||||
isAdjLsaBuildable(Nlsr& pnlsr);
|
||||
isAdjLsaBuildable(const uint32_t interestRetryNo) const;
|
||||
|
||||
int32_t
|
||||
getNumOfActiveNeighbor();
|
||||
@@ -82,10 +126,10 @@ public:
|
||||
getAdjacent(const ndn::Name& adjName);
|
||||
|
||||
bool
|
||||
operator==(AdjacencyList& adl);
|
||||
operator==(AdjacencyList& adl) const;
|
||||
|
||||
size_t
|
||||
getSize()
|
||||
size() const
|
||||
{
|
||||
return m_adjList.size();
|
||||
}
|
||||
@@ -98,25 +142,54 @@ 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();
|
||||
|
||||
public:
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return m_adjList.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return m_adjList.end();
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<Adjacent>::iterator
|
||||
iterator
|
||||
find(const ndn::Name& adjName);
|
||||
|
||||
private:
|
||||
std::list<Adjacent> m_adjList;
|
||||
};
|
||||
|
||||
} //namespace nlsr
|
||||
#endif //NLSR_ADJACENCY_LIST_HPP
|
||||
} // namespace nlsr
|
||||
#endif // NLSR_ADJACENCY_LIST_HPP
|
||||
+30
-24
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -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;
|
||||
|
||||
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
|
||||
} // namespace nlsr
|
||||
+45
-17
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -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,14 +121,24 @@ 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)
|
||||
{
|
||||
@@ -131,15 +146,15 @@ public:
|
||||
}
|
||||
|
||||
inline bool
|
||||
compareFaceId(uint64_t faceId)
|
||||
compareFaceId(const uint64_t faceId)
|
||||
{
|
||||
return m_faceId == faceId;
|
||||
}
|
||||
|
||||
inline bool
|
||||
compareFaceUri(std::string& faceUri)
|
||||
compareFaceUri(const ndn::FaceUri& faceUri)
|
||||
{
|
||||
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
|
||||
+28
-3
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -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-2015, The University of Memphis,
|
||||
* Copyright (c) 2014-2017, 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");
|
||||
|
||||
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) {
|
||||
throw Error("Cannot parse update name because expected components are missing");
|
||||
}
|
||||
|
||||
ndn::Name networkName = m_name.getSubName(0, nlsrPosition);
|
||||
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,14 +43,11 @@ 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, ConfParameter& conf)
|
||||
: onNewLsa(ndn::make_unique<OnNewLsa>())
|
||||
, m_syncFace(face)
|
||||
, m_lsdb(lsdb)
|
||||
, m_isLsaNew(isLsaNew)
|
||||
, m_confParam(conf)
|
||||
, m_sequencingManager(seqManager)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -141,7 +55,7 @@ void
|
||||
SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix)
|
||||
{
|
||||
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,148 +64,137 @@ 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
|
||||
ndn::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
|
||||
std::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
|
||||
|
||||
m_syncSocket = ndn::make_shared<Sync::SyncSocket>(m_syncPrefix, m_validator, facePtr,
|
||||
ndn::bind(&SyncLogicHandler::onNsyncUpdate,
|
||||
this, _1, _2),
|
||||
ndn::bind(&SyncLogicHandler::onNsyncRemoval,
|
||||
this, _1));
|
||||
m_syncSocket = std::make_shared<chronosync::Socket>(m_syncPrefix, m_nameLsaUserPrefix, *facePtr,
|
||||
std::bind(&SyncLogicHandler::onChronoSyncUpdate, this, _1));
|
||||
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
|
||||
m_syncSocket->addSyncNode(m_adjLsaUserPrefix);
|
||||
}
|
||||
else {
|
||||
m_syncSocket->addSyncNode(m_coorLsaUserPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
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 (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;
|
||||
|
||||
try {
|
||||
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");
|
||||
|
||||
expressInterestForLsa(update, AdjLsa::TYPE_STRING, update.getAdjLsaSeqNo());
|
||||
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;
|
||||
}
|
||||
|
||||
if (isLsaNew(originRouter, CoordinateLsa::TYPE_STRING, update.getCorLsaSeqNo())) {
|
||||
_LOG_DEBUG("Received sync update with higher Cor LSA sequence number than entry in LSDB");
|
||||
|
||||
expressInterestForLsa(update, CoordinateLsa::TYPE_STRING, update.getCorLsaSeqNo());
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
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");
|
||||
|
||||
throw SyncLogicHandler::Error("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
|
||||
} // namespace nlsr
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -22,28 +22,35 @@
|
||||
#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 "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:
|
||||
@@ -54,49 +61,82 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
SyncLogicHandler(ndn::Face& face, Lsdb& lsdb, ConfParameter& conf, SequencingManager& seqManager);
|
||||
SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew, ConfParameter& conf);
|
||||
|
||||
/*! \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);
|
||||
|
||||
void
|
||||
publishRoutingUpdate();
|
||||
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
|
||||
* \sa Nlsr::initialize
|
||||
*/
|
||||
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:
|
||||
ndn::shared_ptr<ndn::ValidatorNull> m_validator;
|
||||
ndn::Face& m_syncFace;
|
||||
ndn::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;
|
||||
@@ -104,6 +144,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} //namespace nlsr
|
||||
} // namespace nlsr
|
||||
|
||||
#endif //NLSR_SYNC_LOGIC_HANDLER_HPP
|
||||
#endif // NLSR_SYNC_LOGIC_HANDLER_HPP
|
||||
+106
-82
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -19,33 +19,27 @@
|
||||
* 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
|
||||
{
|
||||
public:
|
||||
typedef ndn::function<void(T)> ConfParameterCallback;
|
||||
typedef std::function<void(T)> ConfParameterCallback;
|
||||
typedef boost::property_tree::ptree ConfigSection;
|
||||
|
||||
ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -294,7 +288,7 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
}
|
||||
|
||||
// log-level
|
||||
std::string logLevel = section.get<string>("log-level", "INFO");
|
||||
std::string logLevel = section.get<std::string>("log-level", "INFO");
|
||||
|
||||
if (isValidLogLevel(logLevel)) {
|
||||
m_nlsr.getConfParameter().setLogLevel(logLevel);
|
||||
@@ -306,11 +300,11 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
}
|
||||
|
||||
try {
|
||||
std::string logDir = section.get<string>("log-dir");
|
||||
std::string logDir = section.get<std::string>("log-dir");
|
||||
if (boost::filesystem::exists(logDir)) {
|
||||
if (boost::filesystem::is_directory(logDir)) {
|
||||
std::string testFileName=logDir+"/test.log";
|
||||
ofstream testOutFile;
|
||||
std::ofstream testOutFile;
|
||||
testOutFile.open(testFileName.c_str());
|
||||
if (testOutFile.is_open() && testOutFile.good()) {
|
||||
m_nlsr.getConfParameter().setLogDir(logDir);
|
||||
@@ -340,11 +334,11 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -374,7 +368,7 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
}
|
||||
|
||||
try {
|
||||
std::string log4cxxPath = section.get<string>("log4cxx-conf");
|
||||
std::string log4cxxPath = section.get<std::string>("log4cxx-conf");
|
||||
|
||||
if (log4cxxPath == "") {
|
||||
std::cerr << "No value provided for log4cxx-conf" << std::endl;
|
||||
@@ -446,7 +440,7 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
// Event intervals
|
||||
// adj-lsa-build-interval
|
||||
ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
|
||||
bind(&ConfParameter::setAdjLsaBuildInterval,
|
||||
std::bind(&ConfParameter::setAdjLsaBuildInterval,
|
||||
&m_nlsr.getConfParameter(), _1));
|
||||
adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
|
||||
adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
|
||||
@@ -454,10 +448,37 @@ 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",
|
||||
bind(&ConfParameter::setFirstHelloInterval,
|
||||
std::bind(&ConfParameter::setFirstHelloInterval,
|
||||
&m_nlsr.getConfParameter(), _1));
|
||||
firstHelloInterval.setMinAndMaxValue(FIRST_HELLO_INTERVAL_MIN, FIRST_HELLO_INTERVAL_MAX);
|
||||
firstHelloInterval.setOptional(FIRST_HELLO_INTERVAL_DEFAULT);
|
||||
@@ -469,17 +490,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 +527,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 +546,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;
|
||||
@@ -569,7 +600,7 @@ ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
|
||||
|
||||
// routing-calc-interval
|
||||
ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
|
||||
bind(&ConfParameter::setRoutingCalcInterval,
|
||||
std::bind(&ConfParameter::setRoutingCalcInterval,
|
||||
&m_nlsr.getConfParameter(), _1));
|
||||
routingCalcInterval.setMinAndMaxValue(ROUTING_CALC_INTERVAL_MIN, ROUTING_CALC_INTERVAL_MAX);
|
||||
routingCalcInterval.setOptional(ROUTING_CALC_INTERVAL_DEFAULT);
|
||||
@@ -612,46 +643,39 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
|
||||
{
|
||||
ConfigSection::const_iterator it = section.begin();
|
||||
|
||||
if (it == section.end() || it->first != "validator")
|
||||
{
|
||||
std::cerr << "Error: Expect validator section!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (it == section.end() || it->first != "validator") {
|
||||
std::cerr << "Error: Expect validator section!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.loadValidator(it->second, m_confFileName);
|
||||
|
||||
it++;
|
||||
if (it != section.end() && it->first == "prefix-update-validator") {
|
||||
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
|
||||
|
||||
if (it == section.end() || it->first != "prefix-update-validator")
|
||||
{
|
||||
std::cerr << "Error: Expect prefix-update-validator section" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
|
||||
it++;
|
||||
|
||||
for (; it != section.end(); it++)
|
||||
{
|
||||
it++;
|
||||
for (; it != section.end(); it++) {
|
||||
using namespace boost::filesystem;
|
||||
if (it->first != "cert-to-publish")
|
||||
{
|
||||
std::cerr << "Error: Expect cert-to-publish!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (it->first != "cert-to-publish") {
|
||||
std::cerr << "Error: Expect cert-to-publish!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file = it->second.data();
|
||||
path certfilePath = absolute(file, path(m_confFileName).parent_path());
|
||||
ndn::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 (!static_cast<bool>(idCert))
|
||||
{
|
||||
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (idCert == nullptr) {
|
||||
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.loadCertToPublish(idCert);
|
||||
m_nlsr.loadCertToPublish(*idCert);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+66
-13
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -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, logging directory, 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
|
||||
} // namespace nlsr
|
||||
#endif // NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
+27
-23
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -31,29 +31,33 @@ INIT_LOGGER("ConfParameter");
|
||||
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("Log Directory: " << m_logDir);
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+70
-14
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -19,17 +19,17 @@
|
||||
* 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 <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 +62,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,
|
||||
@@ -86,13 +99,24 @@ enum {
|
||||
MAX_FACES_PER_PREFIX_MAX = 60
|
||||
};
|
||||
|
||||
enum {
|
||||
enum HyperbolicState {
|
||||
HYPERBOLIC_STATE_OFF = 0,
|
||||
HYPERBOLIC_STATE_ON = 1,
|
||||
HYPERBOLIC_STATE_DRY_RUN = 2,
|
||||
HYPERBOLIC_STATE_DEFAULT = 0
|
||||
};
|
||||
|
||||
/*! \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 +126,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,7 +135,6 @@ 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)
|
||||
{
|
||||
@@ -120,11 +144,14 @@ public:
|
||||
setNetwork(const ndn::Name& networkName)
|
||||
{
|
||||
m_network = networkName;
|
||||
m_chronosyncPrefix = m_network;
|
||||
|
||||
m_chronosyncPrefix.append("localhop");
|
||||
m_chronosyncPrefix.append(m_network);
|
||||
m_chronosyncPrefix.append("NLSR");
|
||||
m_chronosyncPrefix.append("sync");
|
||||
|
||||
m_lsaPrefix = m_network;
|
||||
m_lsaPrefix.append("localhop");
|
||||
m_lsaPrefix.append(m_network);
|
||||
m_lsaPrefix.append("NLSR");
|
||||
m_lsaPrefix.append("LSA");
|
||||
}
|
||||
@@ -258,6 +285,30 @@ public:
|
||||
return m_routerDeadInterval;
|
||||
}
|
||||
|
||||
void
|
||||
setFaceDatasetFetchTries(uint32_t count)
|
||||
{
|
||||
m_faceDatasetFetchTries = count;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
getFaceDatasetFetchTries() const
|
||||
{
|
||||
return m_faceDatasetFetchTries;
|
||||
}
|
||||
|
||||
void
|
||||
setFaceDatasetFetchInterval(uint32_t interval)
|
||||
{
|
||||
m_faceDatasetFetchInterval = ndn::time::seconds(interval);
|
||||
}
|
||||
|
||||
const ndn::time::seconds
|
||||
getFaceDatasetFetchInterval() const
|
||||
{
|
||||
return m_faceDatasetFetchInterval;
|
||||
}
|
||||
|
||||
void
|
||||
setLogLevel(const std::string& logLevel)
|
||||
{
|
||||
@@ -335,12 +386,12 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
setCorTheta(double ct)
|
||||
setCorTheta(const std::vector<double>& ct)
|
||||
{
|
||||
m_corTheta = ct;
|
||||
}
|
||||
|
||||
double
|
||||
std::vector<double>
|
||||
getCorTheta() const
|
||||
{
|
||||
return m_corTheta;
|
||||
@@ -401,6 +452,8 @@ public:
|
||||
return m_log4CxxConfPath;
|
||||
}
|
||||
|
||||
/*! \brief Dump the current state of all attributes to the log.
|
||||
*/
|
||||
void
|
||||
writeLog();
|
||||
|
||||
@@ -421,6 +474,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;
|
||||
@@ -432,7 +488,7 @@ private:
|
||||
|
||||
int32_t m_hyperbolicState;
|
||||
double m_corR;
|
||||
double m_corTheta;
|
||||
std::vector<double> m_corTheta;
|
||||
|
||||
uint32_t m_maxFacesPerPrefix;
|
||||
|
||||
@@ -445,4 +501,4 @@ private:
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif //CONF_PARAMETER_HPP
|
||||
#endif // NLSR_CONF_PARAMETER_HPP
|
||||
+86
-125
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -16,13 +16,12 @@
|
||||
*
|
||||
* 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"
|
||||
|
||||
@@ -33,19 +32,30 @@ 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);
|
||||
m_nlsr.getNlsrFace().expressInterest(i,
|
||||
ndn::bind(&HelloProtocol::onContent,
|
||||
std::bind(&HelloProtocol::onContent,
|
||||
this,
|
||||
_1, _2),
|
||||
ndn::bind(&HelloProtocol::processInterestTimedOut,
|
||||
std::bind(&HelloProtocol::processInterestTimedOut, // Nack
|
||||
this, _1),
|
||||
std::bind(&HelloProtocol::processInterestTimedOut,
|
||||
this, _1));
|
||||
|
||||
// increment SENT_HELLO_INTEREST
|
||||
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_INTEREST);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -54,18 +64,16 @@ HelloProtocol::sendScheduledInterest(uint32_t seconds)
|
||||
std::list<Adjacent> adjList = m_nlsr.getAdjacencyList().getAdjList();
|
||||
for (std::list<Adjacent>::iterator it = adjList.begin(); it != adjList.end();
|
||||
++it) {
|
||||
// If this adjacency has a Face, just proceed as usual.
|
||||
if((*it).getFaceId() != 0) {
|
||||
/* interest name: /<neighbor>/NLSR/INFO/<router> */
|
||||
// interest name: /<neighbor>/NLSR/INFO/<router>
|
||||
ndn::Name interestName = (*it).getName() ;
|
||||
interestName.append(NLSR_COMPONENT);
|
||||
interestName.append(INFO_COMPONENT);
|
||||
interestName.append(m_nlsr.getConfParameter().getRouterPrefix().wireEncode());
|
||||
expressInterest(interestName,
|
||||
m_nlsr.getConfParameter().getInterestResendTime());
|
||||
}
|
||||
else {
|
||||
registerPrefixes((*it).getName(), (*it).getConnectingFaceUri(),
|
||||
(*it).getLinkCost(), ndn::time::milliseconds::max());
|
||||
NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
|
||||
}
|
||||
}
|
||||
scheduleInterest(m_nlsr.getConfParameter().getInfoInterestInterval());
|
||||
@@ -74,38 +82,53 @@ 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),
|
||||
ndn::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
|
||||
std::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::processInterest(const ndn::Name& name,
|
||||
const ndn::Interest& interest)
|
||||
{
|
||||
/* interest name: /<neighbor>/NLSR/INFO/<router> */
|
||||
// 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)) {
|
||||
ndn::shared_ptr<ndn::Data> data = ndn::make_shared<ndn::Data>();
|
||||
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.
|
||||
if(adjacent->getFaceId() != 0){
|
||||
/* interest name: /<neighbor>/NLSR/INFO/<router> */
|
||||
// interest name: /<neighbor>/NLSR/INFO/<router>
|
||||
ndn::Name interestName(neighbor);
|
||||
interestName.append(NLSR_COMPONENT);
|
||||
interestName.append(INFO_COMPONENT);
|
||||
@@ -113,10 +136,6 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
expressInterest(interestName,
|
||||
m_nlsr.getConfParameter().getInterestResendTime());
|
||||
}
|
||||
else {
|
||||
registerPrefixes(adjacent->getName(), adjacent->getConnectingFaceUri(),
|
||||
adjacent->getLinkCost(), ndn::time::milliseconds::max());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,28 +143,29 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
void
|
||||
HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
|
||||
{
|
||||
/* interest name: /<neighbor>/NLSR/INFO/<router> */
|
||||
// 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())) {
|
||||
/* interest name: /<neighbor>/NLSR/INFO/<router> */
|
||||
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());
|
||||
}
|
||||
@@ -153,31 +173,37 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
// This is the first function that incoming Hello data will
|
||||
// see. This checks if the data appears to be signed, and passes it
|
||||
// on to validate the content of the data.
|
||||
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,
|
||||
ndn::bind(&HelloProtocol::onContentValidated, this, _1),
|
||||
ndn::bind(&HelloProtocol::onContentValidationFailed,
|
||||
std::bind(&HelloProtocol::onContentValidated, this, _1),
|
||||
std::bind(&HelloProtocol::onContentValidationFailed,
|
||||
this, _1, _2));
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::onContentValidated(const ndn::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);
|
||||
// data name: /<neighbor>/NLSR/INFO/<router>/<version>
|
||||
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);
|
||||
|
||||
@@ -186,92 +212,27 @@ HelloProtocol::onContentValidated(const ndn::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) {
|
||||
m_nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::onContentValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
|
||||
const std::string& msg)
|
||||
{
|
||||
_LOG_DEBUG("Validation Error: " << msg);
|
||||
}
|
||||
|
||||
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,
|
||||
ndn::bind(&HelloProtocol::onRegistrationSuccess,
|
||||
this, _1, adjName,timeout),
|
||||
ndn::bind(&HelloProtocol::onRegistrationFailure,
|
||||
this, _1, _2, adjName));
|
||||
}
|
||||
|
||||
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);
|
||||
m_nlsr.setStrategies();
|
||||
|
||||
/* 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());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::onRegistrationFailure(uint32_t code, const std::string& error,
|
||||
const ndn::Name& name)
|
||||
{
|
||||
_LOG_DEBUG(error << " (code: " << code << ")");
|
||||
/*
|
||||
* 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);
|
||||
if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
|
||||
}
|
||||
else {
|
||||
m_nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
}
|
||||
|
||||
m_nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
}
|
||||
}
|
||||
// increment RCV_HELLO_DATA
|
||||
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_DATA);
|
||||
}
|
||||
|
||||
} //namespace nlsr
|
||||
void
|
||||
HelloProtocol::onContentValidationFailed(const ndn::Data& data,
|
||||
const ndn::security::v2::ValidationError& ve)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Validation Error: " << ve);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+108
-14
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -22,10 +22,15 @@
|
||||
#ifndef NLSR_HELLO_PROTOCOL_HPP
|
||||
#define NLSR_HELLO_PROTOCOL_HPP
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "statistics.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/management/nfd-control-parameters.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 {
|
||||
|
||||
@@ -34,46 +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.
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
void
|
||||
expressInterest(const ndn::Name& interestNamePrefix, uint32_t seconds);
|
||||
|
||||
/*! \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 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);
|
||||
|
||||
void
|
||||
onContentValidated(const ndn::shared_ptr<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
|
||||
onContentValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
|
||||
const std::string& msg);
|
||||
onContentValidated(const ndn::Data& data);
|
||||
|
||||
private:
|
||||
/*! \brief Log that incoming data couldn't be validated, but do nothing else.
|
||||
*/
|
||||
void
|
||||
onRegistrationFailure(uint32_t code, const std::string& error,
|
||||
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);
|
||||
@@ -85,6 +179,6 @@ private:
|
||||
static const std::string NLSR_COMPONENT;
|
||||
};
|
||||
|
||||
} //namespace nlsr
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_HELLO_PROTOCOL_HPP
|
||||
+7
-9
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -16,10 +16,10 @@
|
||||
*
|
||||
* 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 "logger.hpp"
|
||||
|
||||
#include <log4cxx/logger.h>
|
||||
#include <log4cxx/basicconfigurator.h>
|
||||
#include <log4cxx/xml/domconfigurator.h>
|
||||
@@ -32,8 +32,6 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "logger.hpp"
|
||||
|
||||
void
|
||||
INIT_LOG4CXX(const std::string& log4cxxConfPath)
|
||||
{
|
||||
@@ -55,7 +53,7 @@ INIT_LOGGERS(const std::string& logDir, const std::string& logLevel)
|
||||
}
|
||||
|
||||
log4cxx::PatternLayoutPtr
|
||||
layout(new log4cxx::PatternLayout("%date{yyyyMMddHHmmssSSS} %p: [%c] %m%n"));
|
||||
layout(new log4cxx::PatternLayout("%date{%s}.%date{SSS} %p: [%c] %m%n"));
|
||||
|
||||
log4cxx::RollingFileAppender* rollingFileAppender =
|
||||
new log4cxx::RollingFileAppender(layout, logDir+"/nlsr.log", true);
|
||||
@@ -85,4 +83,4 @@ isValidLogLevel(const std::string& logLevel)
|
||||
boost::iequals(logLevel, "debug") || boost::iequals(logLevel, "info") ||
|
||||
boost::iequals(logLevel, "warn") || boost::iequals(logLevel, "error") ||
|
||||
boost::iequals(logLevel, "none");
|
||||
}
|
||||
}
|
||||
+17
-11
@@ -1,7 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* 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.
|
||||
@@ -16,11 +16,17 @@
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -29,22 +35,22 @@
|
||||
#define INIT_LOGGER(name) \
|
||||
static log4cxx::LoggerPtr staticModuleLogger = log4cxx::Logger::getLogger(name)
|
||||
|
||||
#define _LOG_TRACE(x) \
|
||||
#define NLSR_LOG_TRACE(x) \
|
||||
LOG4CXX_TRACE(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_DEBUG(x) \
|
||||
#define NLSR_LOG_DEBUG(x) \
|
||||
LOG4CXX_DEBUG(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_INFO(x) \
|
||||
#define NLSR_LOG_INFO(x) \
|
||||
LOG4CXX_INFO(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_WARN(x) \
|
||||
#define NLSR_LOG_WARN(x) \
|
||||
LOG4CXX_WARN(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_ERROR(x) \
|
||||
#define NLSR_LOG_ERROR(x) \
|
||||
LOG4CXX_ERROR(staticModuleLogger, x)
|
||||
|
||||
#define _LOG_FATAL(x) \
|
||||
#define NLSR_LOG_FATAL(x) \
|
||||
LOG4CXX_FATAL(staticModuleLogger, x);
|
||||
|
||||
void
|
||||
|
||||
+230
-177
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -19,203 +19,188 @@
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "lsa.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "name-prefix-list.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "nlsr.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "name-prefix-list.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("Lsa");
|
||||
|
||||
using namespace std;
|
||||
|
||||
const std::string NameLsa::TYPE_STRING = "name";
|
||||
const std::string AdjLsa::TYPE_STRING = "adjacency";
|
||||
const std::string CoordinateLsa::TYPE_STRING = "coordinate";
|
||||
|
||||
const ndn::Name
|
||||
NameLsa::getKey() const
|
||||
std::string
|
||||
Lsa::getData() const
|
||||
{
|
||||
ndn::Name key = m_origRouter;
|
||||
key.append(NameLsa::TYPE_STRING);
|
||||
return key;
|
||||
std::ostringstream os;
|
||||
os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
|
||||
<< ndn::time::toIsoString(m_expirationTimePoint) << "|";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
NameLsa::NameLsa(const ndn::Name& origR, const string& lst, uint32_t lsn,
|
||||
const ndn::Name
|
||||
Lsa::getKey() const
|
||||
{
|
||||
return ndn::Name(m_origRouter).append(std::to_string(getType()));
|
||||
}
|
||||
|
||||
bool
|
||||
Lsa::deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator)
|
||||
{
|
||||
m_origRouter = ndn::Name(*iterator++);
|
||||
if (m_origRouter.size() <= 0)
|
||||
return false;
|
||||
if (*iterator++ != std::to_string(getType()))
|
||||
return false;
|
||||
m_lsSeqNo = boost::lexical_cast<uint32_t>(*iterator++);
|
||||
m_expirationTimePoint = ndn::time::fromIsoString(*iterator++);
|
||||
return true;
|
||||
}
|
||||
|
||||
NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
|
||||
const ndn::time::system_clock::TimePoint& lt,
|
||||
NamePrefixList& npl)
|
||||
{
|
||||
m_origRouter = origR;
|
||||
m_lsType = lst;
|
||||
m_lsSeqNo = lsn;
|
||||
m_expirationTimePoint = lt;
|
||||
std::list<ndn::Name>& nl = npl.getNameList();
|
||||
for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++) {
|
||||
addName((*it));
|
||||
for (const auto& name : npl.getNames()) {
|
||||
addName(name);
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
NameLsa::getData()
|
||||
std::string
|
||||
NameLsa::serialize() const
|
||||
{
|
||||
string nameLsaData;
|
||||
nameLsaData = m_origRouter.toUri() + "|" + NameLsa::TYPE_STRING + "|"
|
||||
+ boost::lexical_cast<std::string>(m_lsSeqNo) + "|"
|
||||
+ ndn::time::toIsoString(m_expirationTimePoint);
|
||||
nameLsaData += "|";
|
||||
nameLsaData += boost::lexical_cast<std::string>(m_npl.getSize());
|
||||
std::list<ndn::Name> nl = m_npl.getNameList();
|
||||
for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++) {
|
||||
nameLsaData += "|";
|
||||
nameLsaData += (*it).toUri();
|
||||
std::ostringstream os;
|
||||
os << getData() << m_npl.size();
|
||||
for (const auto& name : m_npl.getNames()) {
|
||||
os << "|" << name;
|
||||
}
|
||||
return nameLsaData + "|";
|
||||
os << "|";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
NameLsa::initializeFromContent(const std::string& content)
|
||||
NameLsa::deserialize(const std::string& content) noexcept
|
||||
{
|
||||
uint32_t numName = 0;
|
||||
boost::char_separator<char> sep("|");
|
||||
boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
|
||||
boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
|
||||
tokens.begin();
|
||||
m_origRouter = ndn::Name(*tok_iter++);
|
||||
if (!(m_origRouter.size() > 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
m_lsType = *tok_iter++;
|
||||
m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
|
||||
m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
|
||||
if (!deserializeCommon(tok_iter))
|
||||
return false;
|
||||
numName = boost::lexical_cast<uint32_t>(*tok_iter++);
|
||||
for (uint32_t i = 0; i < numName; i++) {
|
||||
ndn::Name name(*tok_iter++);
|
||||
addName(name);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
catch (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < numName; i++) {
|
||||
ndn::Name name(*tok_iter++);
|
||||
addName(name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
NameLsa::writeLog()
|
||||
bool
|
||||
NameLsa::isEqualContent(const NameLsa& other) const
|
||||
{
|
||||
_LOG_DEBUG("Name Lsa: ");
|
||||
_LOG_DEBUG(" Origination Router: " << m_origRouter);
|
||||
_LOG_DEBUG(" Ls Type: " << m_lsType);
|
||||
_LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
|
||||
_LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
|
||||
_LOG_DEBUG(" Names: ");
|
||||
int i = 1;
|
||||
std::list<ndn::Name> nl = m_npl.getNameList();
|
||||
for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
|
||||
{
|
||||
_LOG_DEBUG(" Name " << i << ": " << (*it));
|
||||
}
|
||||
_LOG_DEBUG("name_lsa_end");
|
||||
return m_npl == other.getNpl();
|
||||
}
|
||||
|
||||
CoordinateLsa::CoordinateLsa(const ndn::Name& origR, const string lst,
|
||||
uint32_t lsn,
|
||||
void
|
||||
NameLsa::writeLog() const
|
||||
{
|
||||
NLSR_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
|
||||
const ndn::time::system_clock::TimePoint& lt,
|
||||
double r, double theta)
|
||||
double r, std::vector<double> theta)
|
||||
{
|
||||
m_origRouter = origR;
|
||||
m_lsType = lst;
|
||||
m_lsSeqNo = lsn;
|
||||
m_expirationTimePoint = lt;
|
||||
m_corRad = r;
|
||||
m_corTheta = theta;
|
||||
}
|
||||
|
||||
const ndn::Name
|
||||
CoordinateLsa::getKey() const
|
||||
{
|
||||
ndn::Name key = m_origRouter;
|
||||
key.append(CoordinateLsa::TYPE_STRING);
|
||||
return key;
|
||||
m_angles = theta;
|
||||
}
|
||||
|
||||
bool
|
||||
CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
|
||||
{
|
||||
if (clsa.getCorTheta().size() != m_angles.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double> m_angles2 = clsa.getCorTheta();
|
||||
for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
|
||||
if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (std::abs(m_corRad - clsa.getCorRadius()) <
|
||||
std::numeric_limits<double>::epsilon()) &&
|
||||
(std::abs(m_corTheta - clsa.getCorTheta()) <
|
||||
std::numeric_limits<double>::epsilon());
|
||||
}
|
||||
|
||||
string
|
||||
CoordinateLsa::getData()
|
||||
std::string
|
||||
CoordinateLsa::serialize() const
|
||||
{
|
||||
string corLsaData;
|
||||
corLsaData = m_origRouter.toUri() + "|";
|
||||
corLsaData += CoordinateLsa::TYPE_STRING;
|
||||
corLsaData += "|";
|
||||
corLsaData += (boost::lexical_cast<std::string>(m_lsSeqNo) + "|");
|
||||
corLsaData += (ndn::time::toIsoString(m_expirationTimePoint) + "|");
|
||||
corLsaData += (boost::lexical_cast<std::string>(m_corRad) + "|");
|
||||
corLsaData += (boost::lexical_cast<std::string>(m_corTheta) + "|");
|
||||
return corLsaData;
|
||||
std::ostringstream os;
|
||||
os << getData() << m_corRad << "|" << m_angles.size() << "|";
|
||||
for (const auto& angle: m_angles) {
|
||||
os << angle << "|";
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
CoordinateLsa::initializeFromContent(const std::string& content)
|
||||
CoordinateLsa::deserialize(const std::string& content) noexcept
|
||||
{
|
||||
boost::char_separator<char> sep("|");
|
||||
boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
|
||||
boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
|
||||
tokens.begin();
|
||||
m_origRouter = ndn::Name(*tok_iter++);
|
||||
if (!(m_origRouter.size() > 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
m_lsType = *tok_iter++;
|
||||
m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
|
||||
m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
|
||||
m_corRad = boost::lexical_cast<double>(*tok_iter++);
|
||||
m_corTheta = boost::lexical_cast<double>(*tok_iter++);
|
||||
if (!deserializeCommon(tok_iter))
|
||||
return false;
|
||||
m_corRad = boost::lexical_cast<double>(*tok_iter++);
|
||||
int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
|
||||
for (int i = 0; i < numAngles; i++) {
|
||||
m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
catch (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CoordinateLsa::writeLog()
|
||||
CoordinateLsa::writeLog() const
|
||||
{
|
||||
_LOG_DEBUG("Cor Lsa: ");
|
||||
_LOG_DEBUG(" Origination Router: " << m_origRouter);
|
||||
_LOG_DEBUG(" Ls Type: " << m_lsType);
|
||||
_LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
|
||||
_LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
|
||||
_LOG_DEBUG(" Hyperbolic Radius: " << m_corRad);
|
||||
_LOG_DEBUG(" Hyperbolic Theta: " << m_corTheta);
|
||||
NLSR_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
AdjLsa::AdjLsa(const ndn::Name& origR, const string& lst, uint32_t lsn,
|
||||
AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
|
||||
const ndn::time::system_clock::TimePoint& lt,
|
||||
uint32_t nl , AdjacencyList& adl)
|
||||
{
|
||||
m_origRouter = origR;
|
||||
m_lsType = lst;
|
||||
m_lsSeqNo = lsn;
|
||||
m_expirationTimePoint = lt;
|
||||
m_noLink = nl;
|
||||
@@ -227,83 +212,61 @@ AdjLsa::AdjLsa(const ndn::Name& origR, const string& lst, uint32_t lsn,
|
||||
}
|
||||
}
|
||||
|
||||
const ndn::Name
|
||||
AdjLsa::getKey() const
|
||||
{
|
||||
ndn::Name key = m_origRouter;
|
||||
key.append(AdjLsa::TYPE_STRING);
|
||||
return key;
|
||||
}
|
||||
|
||||
bool
|
||||
AdjLsa::isEqualContent(AdjLsa& alsa)
|
||||
{
|
||||
return m_adl == alsa.getAdl();
|
||||
}
|
||||
|
||||
|
||||
string
|
||||
AdjLsa::getData()
|
||||
std::string
|
||||
AdjLsa::serialize() const
|
||||
{
|
||||
string adjLsaData;
|
||||
adjLsaData = m_origRouter.toUri() + "|" + AdjLsa::TYPE_STRING + "|"
|
||||
+ boost::lexical_cast<std::string>(m_lsSeqNo) + "|"
|
||||
+ ndn::time::toIsoString(m_expirationTimePoint);
|
||||
adjLsaData += "|";
|
||||
adjLsaData += boost::lexical_cast<std::string>(m_adl.getSize());
|
||||
std::list<Adjacent> al = m_adl.getAdjList();
|
||||
for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
|
||||
adjLsaData += "|";
|
||||
adjLsaData += (*it).getName().toUri();
|
||||
adjLsaData += "|";
|
||||
adjLsaData += (*it).getConnectingFaceUri();
|
||||
adjLsaData += "|";
|
||||
adjLsaData += boost::lexical_cast<std::string>((*it).getLinkCost());
|
||||
std::ostringstream os;
|
||||
os << getData() << m_adl.size();
|
||||
for (const auto& adjacent : m_adl.getAdjList()) {
|
||||
os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
|
||||
<< "|" << adjacent.getLinkCost();
|
||||
}
|
||||
return adjLsaData + "|";
|
||||
os << "|";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
AdjLsa::initializeFromContent(const std::string& content)
|
||||
AdjLsa::deserialize(const std::string& content) noexcept
|
||||
{
|
||||
uint32_t numLink = 0;
|
||||
boost::char_separator<char> sep("|");
|
||||
boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
|
||||
boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
|
||||
tokens.begin();
|
||||
m_origRouter = ndn::Name(*tok_iter++);
|
||||
if (!(m_origRouter.size() > 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
m_lsType = *tok_iter++;
|
||||
m_lsSeqNo = boost::lexical_cast<uint32_t>(*tok_iter++);
|
||||
m_expirationTimePoint = ndn::time::fromIsoString(*tok_iter++);
|
||||
numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < numLink; i++) {
|
||||
try {
|
||||
if (!deserializeCommon(tok_iter))
|
||||
return false;
|
||||
numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
|
||||
for (uint32_t i = 0; i < numLink; i++) {
|
||||
ndn::Name adjName(*tok_iter++);
|
||||
std::string connectingFaceUri(*tok_iter++);
|
||||
double linkCost = boost::lexical_cast<double>(*tok_iter++);
|
||||
Adjacent adjacent(adjName, connectingFaceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
|
||||
Adjacent adjacent(adjName, ndn::FaceUri(connectingFaceUri), linkCost,
|
||||
Adjacent::STATUS_INACTIVE, 0, 0);
|
||||
addAdjacent(adjacent);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdjLsa::addNptEntries(Nlsr& pnlsr)
|
||||
{
|
||||
// Only add NPT entries if this is an adj LSA from another router.
|
||||
if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
|
||||
// Pass the originating router as both the name to register and
|
||||
// where it came from.
|
||||
pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
|
||||
}
|
||||
}
|
||||
@@ -318,24 +281,114 @@ AdjLsa::removeNptEntries(Nlsr& pnlsr)
|
||||
}
|
||||
|
||||
void
|
||||
AdjLsa::writeLog()
|
||||
AdjLsa::writeLog() const
|
||||
{
|
||||
_LOG_DEBUG("Adj Lsa: ");
|
||||
_LOG_DEBUG(" Origination Router: " << m_origRouter);
|
||||
_LOG_DEBUG(" Ls Type: " << m_lsType);
|
||||
_LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
|
||||
_LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
|
||||
_LOG_DEBUG(" Adjacents: ");
|
||||
int i = 1;
|
||||
std::list<Adjacent> al = m_adl.getAdjList();
|
||||
for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++)
|
||||
{
|
||||
_LOG_DEBUG(" Adjacent " << i << ": ");;
|
||||
_LOG_DEBUG(" Adjacent Name: " << (*it).getName());
|
||||
_LOG_DEBUG(" Connecting FaceUri: " << (*it).getConnectingFaceUri());
|
||||
_LOG_DEBUG(" Link Cost: " << (*it).getLinkCost());
|
||||
}
|
||||
_LOG_DEBUG("adj_lsa_end");
|
||||
NLSR_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
}//namespace nlsr
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& lsa)
|
||||
{
|
||||
os << lsa.toString();
|
||||
os << "-Adjacents:";
|
||||
|
||||
int adjacencyIndex = 1;
|
||||
|
||||
for (const Adjacent& adjacency : lsa.m_adl) {
|
||||
os << "--Adjacent" << adjacencyIndex++ << ":\n"
|
||||
<< "---Adjacent Name: " << adjacency.getName() << "\n"
|
||||
<< "---Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
|
||||
<< "---Link Cost: " << adjacency.getLinkCost() << "\n";
|
||||
}
|
||||
os << "adj_lsa_end";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const CoordinateLsa& lsa)
|
||||
{
|
||||
os << lsa.toString();
|
||||
os << "--Hyperbolic Radius: " << lsa.m_corRad << "\n";
|
||||
int i = 0;
|
||||
for (const auto& value : lsa.m_angles) {
|
||||
os << "---Hyperbolic Theta: " << i++ << ": " << value << "\n";
|
||||
}
|
||||
os << "cor_lsa_end";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NameLsa& lsa)
|
||||
{
|
||||
os << lsa.toString();
|
||||
os << "--Names:\n";
|
||||
int i = 0;
|
||||
auto names = lsa.m_npl.getNames();
|
||||
for (const auto& name : names) {
|
||||
os << "---Name " << i++ << ": " << name << "\n";
|
||||
}
|
||||
os << "name_lsa_end";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Lsa::Type& type)
|
||||
{
|
||||
os << std::to_string(type);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::istream&
|
||||
operator>>(std::istream& is, Lsa::Type& type)
|
||||
{
|
||||
std::string typeString;
|
||||
is >> typeString;
|
||||
if (typeString == "ADJACENCY") {
|
||||
type = Lsa::Type::ADJACENCY;
|
||||
}
|
||||
else if (typeString == "COORDINATE") {
|
||||
type = Lsa::Type::COORDINATE;
|
||||
}
|
||||
else if (typeString == "NAME") {
|
||||
type = Lsa::Type::NAME;
|
||||
}
|
||||
else {
|
||||
type = Lsa::Type::BASE;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
std::string
|
||||
Lsa::toString() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "LSA of type " << getType() << ":\n-Origin Router: " << getOrigRouter()
|
||||
<< "\n-Sequence Number: " << getLsSeqNo() << "\n-Expiration Point: "
|
||||
<< getExpirationTimePoint() << "\n";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
namespace std {
|
||||
std::string
|
||||
to_string(const nlsr::Lsa::Type& type)
|
||||
{
|
||||
switch (type) {
|
||||
case nlsr::Lsa::Type::ADJACENCY:
|
||||
return "ADJACENCY";
|
||||
case nlsr::Lsa::Type::COORDINATE:
|
||||
return "COORDINATE";
|
||||
case nlsr::Lsa::Type::NAME:
|
||||
return "NAME";
|
||||
case nlsr::Lsa::Type::MOCK:
|
||||
return "MOCK";
|
||||
default:
|
||||
return "BASE";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
+199
-62
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, The University of Memphis,
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -22,19 +22,30 @@
|
||||
#ifndef NLSR_LSA_HPP
|
||||
#define NLSR_LSA_HPP
|
||||
|
||||
#include "name-prefix-list.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "adjacency-list.hpp"
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "name-prefix-list.hpp"
|
||||
#include "adjacency-list.hpp"
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class Nlsr;
|
||||
|
||||
class Lsa
|
||||
{
|
||||
public:
|
||||
enum class Type {
|
||||
ADJACENCY,
|
||||
COORDINATE,
|
||||
NAME,
|
||||
BASE,
|
||||
MOCK
|
||||
};
|
||||
|
||||
Lsa()
|
||||
: m_origRouter()
|
||||
, m_lsSeqNo()
|
||||
@@ -43,17 +54,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setLsType(const std::string& lst)
|
||||
virtual Type
|
||||
getType() const
|
||||
{
|
||||
m_lsType = lst;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getLsType() const
|
||||
{
|
||||
return m_lsType;
|
||||
return Type::BASE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -104,9 +108,48 @@ public:
|
||||
return m_expiringEventId;
|
||||
}
|
||||
|
||||
/*! \brief Return the data that this LSA represents.
|
||||
*/
|
||||
virtual std::string
|
||||
serialize() const = 0;
|
||||
|
||||
/*! \brief Gets the key for this LSA.
|
||||
|
||||
Format is: \<router name\>/\<LSA type>\
|
||||
*/
|
||||
const ndn::Name
|
||||
getKey() const;
|
||||
|
||||
/*! \brief Populate this LSA with content from the string "content".
|
||||
\param content The string containing a valid serialization of LSA content.
|
||||
|
||||
This method populates "this" LSA with data from the string.
|
||||
*/
|
||||
virtual bool
|
||||
deserialize(const std::string& content) noexcept = 0;
|
||||
|
||||
virtual void
|
||||
writeLog() const = 0;
|
||||
|
||||
protected:
|
||||
/*! Get data common to all LSA types.
|
||||
|
||||
This method should be called by all LSA classes in their
|
||||
serialize() method.
|
||||
*/
|
||||
std::string
|
||||
getData() const;
|
||||
|
||||
/*! Print data common to all LSA types.
|
||||
*/
|
||||
std::string
|
||||
toString() const;
|
||||
|
||||
bool
|
||||
deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator);
|
||||
|
||||
protected:
|
||||
ndn::Name m_origRouter;
|
||||
std::string m_lsType;
|
||||
uint32_t m_lsSeqNo;
|
||||
ndn::time::system_clock::TimePoint m_expirationTimePoint;
|
||||
ndn::EventId m_expiringEventId;
|
||||
@@ -116,22 +159,31 @@ class NameLsa: public Lsa
|
||||
{
|
||||
public:
|
||||
NameLsa()
|
||||
: Lsa()
|
||||
, m_npl()
|
||||
{
|
||||
setLsType(NameLsa::TYPE_STRING);
|
||||
}
|
||||
|
||||
NameLsa(const ndn::Name& origR, const std::string& lst, uint32_t lsn,
|
||||
NameLsa(const ndn::Name& origR, uint32_t lsn,
|
||||
const ndn::time::system_clock::TimePoint& lt,
|
||||
NamePrefixList& npl);
|
||||
|
||||
Lsa::Type
|
||||
getType() const override
|
||||
{
|
||||
return Lsa::Type::NAME;
|
||||
}
|
||||
|
||||
NamePrefixList&
|
||||
getNpl()
|
||||
{
|
||||
return m_npl;
|
||||
}
|
||||
|
||||
const NamePrefixList&
|
||||
getNpl() const
|
||||
{
|
||||
return m_npl;
|
||||
}
|
||||
|
||||
void
|
||||
addName(const ndn::Name& name)
|
||||
{
|
||||
@@ -144,58 +196,83 @@ public:
|
||||
m_npl.remove(name);
|
||||
}
|
||||
|
||||
const ndn::Name
|
||||
getKey() const;
|
||||
/*! \brief Initializes this LSA object with content's data.
|
||||
|
||||
std::string
|
||||
getData();
|
||||
\param content The data (e.g. name prefixes) to initialize this LSA with.
|
||||
|
||||
This function initializes this object to represent the data
|
||||
contained in content. The format for this is the same as for
|
||||
getData(); getData() returns data of this format, in other words.
|
||||
*/
|
||||
bool
|
||||
deserialize(const std::string& content) noexcept override;
|
||||
|
||||
bool
|
||||
initializeFromContent(const std::string& content);
|
||||
isEqualContent(const NameLsa& other) const;
|
||||
|
||||
void
|
||||
writeLog();
|
||||
writeLog() const override;
|
||||
|
||||
/*! \brief Returns the data that this name LSA has.
|
||||
|
||||
Format is: \<original router
|
||||
prefix\>|name|\<seq. no.\>|\<exp. time\>|\<prefix 1\>|\<prefix
|
||||
2\>|...|\<prefix n\>|
|
||||
*/
|
||||
std::string
|
||||
serialize() const override;
|
||||
|
||||
private:
|
||||
NamePrefixList m_npl;
|
||||
public:
|
||||
static const std::string TYPE_STRING;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const NameLsa& lsa);
|
||||
};
|
||||
|
||||
class AdjLsa: public Lsa
|
||||
{
|
||||
public:
|
||||
typedef AdjacencyList::const_iterator const_iterator;
|
||||
|
||||
AdjLsa()
|
||||
: Lsa()
|
||||
, m_adl()
|
||||
{
|
||||
setLsType(AdjLsa::TYPE_STRING);
|
||||
}
|
||||
|
||||
AdjLsa(const ndn::Name& origR, const std::string& lst, uint32_t lsn,
|
||||
AdjLsa(const ndn::Name& origR, uint32_t lsn,
|
||||
const ndn::time::system_clock::TimePoint& lt,
|
||||
uint32_t nl , AdjacencyList& adl);
|
||||
|
||||
Lsa::Type
|
||||
getType() const override
|
||||
{
|
||||
return Lsa::Type::ADJACENCY;
|
||||
}
|
||||
|
||||
AdjacencyList&
|
||||
getAdl()
|
||||
{
|
||||
return m_adl;
|
||||
}
|
||||
|
||||
const AdjacencyList&
|
||||
getAdl() const
|
||||
{
|
||||
return m_adl;
|
||||
}
|
||||
|
||||
void
|
||||
addAdjacent(Adjacent adj)
|
||||
{
|
||||
m_adl.insert(adj);
|
||||
}
|
||||
|
||||
const ndn::Name
|
||||
getKey() const;
|
||||
|
||||
std::string
|
||||
getData();
|
||||
/*! \brief Initializes this adj. LSA from the supplied content.
|
||||
|
||||
\param content The content that this LSA is to have, formatted
|
||||
according to getData().
|
||||
*/
|
||||
bool
|
||||
initializeFromContent(const std::string& content);
|
||||
deserialize(const std::string& content) noexcept override;
|
||||
|
||||
uint32_t
|
||||
getNoLink()
|
||||
@@ -206,6 +283,11 @@ public:
|
||||
bool
|
||||
isEqualContent(AdjLsa& alsa);
|
||||
|
||||
/*! \brief Installs this LSA's name prefixes into the NPT.
|
||||
|
||||
\param pnlsr The NLSR top-level whose NPT you want to install the
|
||||
entries into.
|
||||
*/
|
||||
void
|
||||
addNptEntries(Nlsr& pnlsr);
|
||||
|
||||
@@ -213,39 +295,66 @@ public:
|
||||
removeNptEntries(Nlsr& pnlsr);
|
||||
|
||||
void
|
||||
writeLog();
|
||||
writeLog() const override;
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return m_adl.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return m_adl.end();
|
||||
}
|
||||
|
||||
/*! \brief Returns the data this adjacency LSA has.
|
||||
|
||||
The format is: \<original
|
||||
router\>|adjacency|\<seq. no.\>|\<exp. time\>|\<size\>|\<adjacency prefix
|
||||
1\>|\<face uri 1\>|\<cost 1\>|...|\<adjacency prefix n\>|\<face uri
|
||||
n\>|\<cost n\>|
|
||||
*/
|
||||
std::string
|
||||
serialize() const override;
|
||||
|
||||
private:
|
||||
uint32_t m_noLink;
|
||||
AdjacencyList m_adl;
|
||||
|
||||
public:
|
||||
static const std::string TYPE_STRING;
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& lsa);
|
||||
};
|
||||
|
||||
class CoordinateLsa: public Lsa
|
||||
{
|
||||
public:
|
||||
CoordinateLsa()
|
||||
: Lsa()
|
||||
, m_corRad(0)
|
||||
, m_corTheta(0)
|
||||
: m_corRad(0)
|
||||
{
|
||||
setLsType(CoordinateLsa::TYPE_STRING);
|
||||
}
|
||||
|
||||
CoordinateLsa(const ndn::Name& origR, const std::string lst, uint32_t lsn,
|
||||
CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
|
||||
const ndn::time::system_clock::TimePoint& lt,
|
||||
double r, double theta);
|
||||
double r, std::vector<double> theta);
|
||||
|
||||
const ndn::Name
|
||||
getKey() const;
|
||||
Lsa::Type
|
||||
getType() const override
|
||||
{
|
||||
return Lsa::Type::COORDINATE;
|
||||
}
|
||||
|
||||
std::string
|
||||
getData();
|
||||
/*! \brief Initializes this coordinate LSA with the data in content.
|
||||
|
||||
\param content The string content that is used to build the LSA.
|
||||
|
||||
This function initializes this LSA object to represent the data
|
||||
specified by the parameter. The format that it is expecting is the
|
||||
same as for getData();
|
||||
*/
|
||||
bool
|
||||
initializeFromContent(const std::string& content);
|
||||
deserialize(const std::string& content) noexcept override;
|
||||
|
||||
double
|
||||
getCorRadius() const
|
||||
@@ -259,32 +368,60 @@ public:
|
||||
m_corRad = cr;
|
||||
}
|
||||
|
||||
double
|
||||
const std::vector<double>
|
||||
getCorTheta() const
|
||||
{
|
||||
return m_corTheta;
|
||||
return m_angles;
|
||||
}
|
||||
|
||||
void
|
||||
setCorTheta(double ct)
|
||||
setCorTheta(std::vector<double> ct)
|
||||
{
|
||||
m_corTheta = ct;
|
||||
m_angles = ct;
|
||||
}
|
||||
|
||||
bool
|
||||
isEqualContent(const CoordinateLsa& clsa);
|
||||
|
||||
void
|
||||
writeLog();
|
||||
writeLog() const override;
|
||||
|
||||
/*! \brief Returns the data that this coordinate LSA represents.
|
||||
|
||||
The format is: \<original
|
||||
router\>|coordinate|\<seq. no.\>|\<exp. time\>|\<radians\>|\<theta\>|
|
||||
*/
|
||||
std::string
|
||||
serialize() const override;
|
||||
|
||||
private:
|
||||
double m_corRad;
|
||||
double m_corTheta;
|
||||
std::vector<double> m_angles;
|
||||
|
||||
public:
|
||||
static const std::string TYPE_STRING;
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const CoordinateLsa& lsa);
|
||||
};
|
||||
|
||||
}//namespace nlsr
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& lsa);
|
||||
|
||||
#endif //NLSR_LSA_HPP
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const CoordinateLsa& lsa);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NameLsa& lsa);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Lsa::Type& type);
|
||||
|
||||
std::istream&
|
||||
operator>>(std::istream& is, Lsa::Type& type);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
namespace std {
|
||||
std::string
|
||||
to_string(const nlsr::Lsa::Type& type);
|
||||
} // namespace std
|
||||
|
||||
#endif // NLSR_LSA_HPP
|
||||
+532
-275
File diff suppressed because it is too large.
Load diff
Loaded 100 of 253 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user