Compare commits
121
Commits
NLSR-0.4.3
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd1e940648 | ||
|
|
5849ee7582 | ||
|
|
2ecb059eb9 | ||
|
|
20377645fb | ||
|
|
6593a43fa3 | ||
|
|
931ca9f576 | ||
|
|
cd77aabaa9 | ||
|
|
eed3209c8d | ||
|
|
5110a8a4ee | ||
|
|
52f16644ab | ||
|
|
43f37a08fc | ||
|
|
ecb0b7180e | ||
|
|
771a0de40c | ||
|
|
907675bd06 | ||
|
|
7543f590a3 | ||
|
|
a2599dafa9 | ||
|
|
f7ea150405 | ||
|
|
658fd85bc7 | ||
|
|
070ee3b52d | ||
|
|
e0ad5808e3 | ||
|
|
fa54ee99b4 | ||
|
|
1e9faf1d1b | ||
|
|
1b640fd092 | ||
|
|
fcef058206 | ||
|
|
7d2d689d89 | ||
|
|
65ee992149 | ||
|
|
69904fcb73 | ||
|
|
1954a0c5ce | ||
|
|
d1cb063482 | ||
|
|
ede5963845 | ||
|
|
c1d0e8e34d | ||
|
|
0c87b12458 | ||
|
|
fabe9729b9 | ||
|
|
135288cf4f | ||
|
|
8de8a8b37a | ||
|
|
b032fcb38f | ||
|
|
583473a76f | ||
|
|
e28d8756ce | ||
|
|
d1f1df802c | ||
|
|
a3a63975d1 | ||
|
|
ea94f83039 | ||
|
|
cf14807f7d | ||
|
|
7bc3d438e7 | ||
|
|
ba8a4ed2d2 | ||
|
|
7ae8b08fc2 | ||
|
|
6f0f35d96d | ||
|
|
3781c7ebc1 | ||
|
|
22520e68f5 | ||
|
|
6184c2088b | ||
|
|
e63b7fa7dc | ||
|
|
04bfe0465a | ||
|
|
30d96e4875 | ||
|
|
6002e6ab4b | ||
|
|
5d93aa5b04 | ||
|
|
d90338d230 | ||
|
|
cf06444860 | ||
|
|
214032e7ac | ||
|
|
0af4627ad7 | ||
|
|
e4edb3952c | ||
|
|
d8d6bbcbe6 | ||
|
|
4a90b9ae52 | ||
|
|
7a231c0dc1 | ||
|
|
57a8717ec7 | ||
|
|
0421bc6bcd | ||
|
|
0ad01f3834 | ||
|
|
96ebd9b7c3 | ||
|
|
a122abf5f6 | ||
|
|
4b9d30f8e2 | ||
|
|
f6be8e37f6 | ||
|
|
0db4d4d8fc | ||
|
|
f89878c12c | ||
|
|
fd021d5e3d | ||
|
|
1158c55878 | ||
|
|
427e012304 | ||
|
|
4a5334cba7 | ||
|
|
55d1b5c2c0 | ||
|
|
cb065f1773 | ||
|
|
328fc11217 | ||
|
|
6b388fc36d | ||
|
|
f75bfdaa34 | ||
|
|
842b1cf1f0 | ||
|
|
d21d83d892 | ||
|
|
4187857a9a | ||
|
|
d0816a3ced | ||
|
|
c64bed22a8 | ||
|
|
9ea3639be2 | ||
|
|
cf22053914 | ||
|
|
348321368d | ||
|
|
08bce9c325 | ||
|
|
0b1b7d9ff4 | ||
|
|
15052408e9 | ||
|
|
dec85d2da4 | ||
|
|
af7a2113e4 | ||
|
|
0b0eddd60c | ||
|
|
9ecbdc95c5 | ||
|
|
b2fea6d79f | ||
|
|
d3b60a8b24 | ||
|
|
0da3eab4da | ||
|
|
82a34c2cd8 | ||
|
|
85998a1dc9 | ||
|
|
7e3f6d75c8 | ||
|
|
e3c741da9a | ||
|
|
5859ed3dfb | ||
|
|
e556991595 | ||
|
|
72b2b25cd2 | ||
|
|
7c13ba5448 | ||
|
|
008c9b18a5 | ||
|
|
7526cee087 | ||
|
|
939b6f8652 | ||
|
|
e5002b3fc4 | ||
|
|
32ec3fd51e | ||
|
|
2fa23ea104 | ||
|
|
744e481642 | ||
|
|
8433cfeace | ||
|
|
2e6c8bb896 | ||
|
|
3494f7366a | ||
|
|
05cb728c63 | ||
|
|
057005460e | ||
|
|
e8d8bd5276 | ||
|
|
481010723b | ||
|
|
a08dc3f1f1 |
No files matched your search
@@ -0,0 +1,16 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
- '.mailmap'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
Ubuntu:
|
||||
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
|
||||
macOS:
|
||||
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skip-deploy:
|
||||
description: 'Skip deployment?'
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
html:
|
||||
uses: named-data/actions/.github/workflows/docs-html.yml@v1
|
||||
with:
|
||||
# Deploy only the master branch and release tags
|
||||
deploy: ${{ !inputs.skip-deploy && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/NLSR-')) }}
|
||||
secrets: inherit
|
||||
man:
|
||||
uses: named-data/actions/.github/workflows/docs-man.yml@v1
|
||||
+1
-1
@@ -29,4 +29,4 @@ __pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# Other
|
||||
/VERSION
|
||||
/VERSION.info
|
||||
@@ -1,10 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
case $(uname) in
|
||||
Linux)
|
||||
if [[ -e /etc/os-release ]]; then
|
||||
source /etc/os-release
|
||||
else
|
||||
source /usr/lib/os-release
|
||||
fi
|
||||
export ID VERSION_ID
|
||||
export ID_LIKE="${ID} ${ID_LIKE} linux"
|
||||
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
|
||||
;;
|
||||
Darwin)
|
||||
# Emulate a subset of os-release(5)
|
||||
export ID=macos
|
||||
export VERSION_ID=$(sw_vers -productVersion)
|
||||
export PATH="/usr/local/bin${PATH:+:}${PATH}"
|
||||
if [[ -x /opt/homebrew/bin/brew ]]; then
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
elif [[ -x /usr/local/bin/brew ]]; then
|
||||
eval "$(/usr/local/bin/brew shellenv)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
for file in "$DIR"/.jenkins.d/*; do
|
||||
export CACHE_DIR=${CACHE_DIR:-/tmp}
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
export DISABLE_ASAN=yes
|
||||
export DISABLE_HEADERS_CHECK=yes
|
||||
fi
|
||||
|
||||
# https://reproducible-builds.org/docs/source-date-epoch/
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
|
||||
|
||||
for file in .jenkins.d/*; do
|
||||
[[ -f $file && -x $file ]] || continue
|
||||
echo "Run: $file"
|
||||
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
|
||||
echo "::group::${label}"
|
||||
fi
|
||||
|
||||
echo "\$ $file"
|
||||
"$file"
|
||||
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
done
|
||||
+29
-25
@@ -1,34 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
APT_PKGS=(build-essential pkg-config python3-minimal
|
||||
libboost-all-dev libssl-dev libsqlite3-dev)
|
||||
FORMULAE=(boost openssl pkg-config)
|
||||
PIP_PKGS=()
|
||||
case $JOB_NAME in
|
||||
*code-coverage)
|
||||
APT_PKGS+=(lcov python3-pip)
|
||||
PIP_PKGS+=('gcovr~=5.2')
|
||||
;;
|
||||
*Docs)
|
||||
APT_PKGS+=(doxygen graphviz python3-pip)
|
||||
FORMULAE+=(doxygen graphviz)
|
||||
PIP_PKGS+=(sphinx sphinxcontrib-doxylink)
|
||||
;;
|
||||
esac
|
||||
|
||||
set -x
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
FORMULAE=(boost pkg-config openssl)
|
||||
if [[ $ID == macos ]]; then
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
fi
|
||||
brew update
|
||||
if [[ -n $TRAVIS ]]; then
|
||||
# travis images come with a large number of brew packages
|
||||
# pre-installed, don't waste time upgrading all of them
|
||||
for FORMULA in "${FORMULAE[@]}"; do
|
||||
brew outdated $FORMULA || brew upgrade $FORMULA
|
||||
done
|
||||
else
|
||||
brew upgrade
|
||||
fi
|
||||
brew install "${FORMULAE[@]}"
|
||||
brew cleanup
|
||||
fi
|
||||
|
||||
if has Ubuntu $NODE_LABELS; then
|
||||
brew install --formula "${FORMULAE[@]}"
|
||||
elif [[ $ID_LIKE == *debian* ]]; then
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qy install build-essential pkg-config libboost-all-dev \
|
||||
libsqlite3-dev libssl-dev
|
||||
sudo apt-get -qy install "${APT_PKGS[@]}"
|
||||
elif [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo dnf -y install gcc-c++ libasan lld pkgconf-pkg-config python3 \
|
||||
boost-devel openssl-devel sqlite-devel
|
||||
fi
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
sudo apt-get -qy install lcov libgd-perl python-setuptools
|
||||
sudo easy_install --upgrade gcovr
|
||||
fi
|
||||
if (( ${#PIP_PKGS[@]} )); then
|
||||
pip3 install --user --upgrade --upgrade-strategy=eager "${PIP_PKGS[@]}"
|
||||
fi
|
||||
+17
-23
@@ -1,16 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -exo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
|
||||
pushd "${CACHE_DIR:-/tmp}" >/dev/null
|
||||
pushd "$CACHE_DIR" >/dev/null
|
||||
|
||||
INSTALLED_VERSION=
|
||||
if has OSX $NODE_LABELS; then
|
||||
BOOST=$(brew ls --versions boost)
|
||||
if [[ $ID == macos ]]; then
|
||||
BOOST=$(brew list --formula --versions boost)
|
||||
OLD_BOOST=$(cat boost.txt || :)
|
||||
if [[ $OLD_BOOST != $BOOST ]]; then
|
||||
echo "$BOOST" > boost.txt
|
||||
@@ -22,35 +17,34 @@ 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
|
||||
|
||||
sudo rm -rf ndn-cxx-latest
|
||||
git clone --depth 1 https://github.com/named-data/ndn-cxx.git 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
|
||||
sudo rm -rf ndn-cxx
|
||||
mv ndn-cxx-latest ndn-cxx
|
||||
else
|
||||
sudo rm -Rf ndn-cxx-latest
|
||||
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
|
||||
sudo rm -f /usr/local/lib{,64}/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib{,64}/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
|
||||
./waf --color=yes configure --without-osx-keychain
|
||||
./waf --color=yes build
|
||||
sudo ./waf --color=yes install
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if [[ $ID_LIKE == *linux* ]]; then
|
||||
sudo ldconfig
|
||||
elif has FreeBSD10 $NODE_LABELS; then
|
||||
sudo ldconfig -m
|
||||
fi
|
||||
+26
-36
@@ -1,59 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -exo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
PROJ=ChronoSync
|
||||
|
||||
set -x
|
||||
|
||||
pushd "${CACHE_DIR:-/tmp}" >/dev/null
|
||||
pushd "$CACHE_DIR" >/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
|
||||
NDN_CXX=$(ndnsec version)
|
||||
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
|
||||
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
|
||||
echo "$NDN_CXX" > "$PROJ-ndn-cxx.txt"
|
||||
INSTALLED_VERSION=NONE
|
||||
fi
|
||||
|
||||
if [[ -z $INSTALLED_VERSION ]]; then
|
||||
INSTALLED_VERSION=$(git -C ChronoSync rev-parse HEAD 2>/dev/null || echo NONE)
|
||||
INSTALLED_VERSION=$(git -C "$PROJ" 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)
|
||||
sudo rm -rf "$PROJ-latest"
|
||||
git clone --depth 1 "https://github.com/named-data/$PROJ.git" "$PROJ-latest"
|
||||
LATEST_VERSION=$(git -C "$PROJ-latest" rev-parse HEAD 2>/dev/null || echo UNKNOWN)
|
||||
|
||||
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
|
||||
sudo rm -Rf ChronoSync
|
||||
mv ChronoSync-latest ChronoSync
|
||||
sudo rm -rf "$PROJ"
|
||||
mv "$PROJ-latest" "$PROJ"
|
||||
else
|
||||
sudo rm -Rf ChronoSync-latest
|
||||
sudo rm -rf "$PROJ-latest"
|
||||
fi
|
||||
|
||||
sudo rm -fr /usr/local/include/ChronoSync
|
||||
sudo rm -f /usr/local/lib/libChronoSync*
|
||||
sudo rm -f /usr/local/lib/pkgconfig/ChronoSync*
|
||||
sudo rm -fr /usr/local/include/"$PROJ"
|
||||
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/"$PROJ".pc
|
||||
|
||||
pushd ChronoSync >/dev/null
|
||||
pushd "$PROJ" >/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
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build
|
||||
sudo ./waf --color=yes install
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if [[ $ID_LIKE == *linux* ]]; then
|
||||
sudo ldconfig
|
||||
elif has FreeBSD10 $NODE_LABELS; then
|
||||
sudo ldconfig -m
|
||||
fi
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
|
||||
PROJ=PSync
|
||||
|
||||
pushd "$CACHE_DIR" >/dev/null
|
||||
|
||||
INSTALLED_VERSION=
|
||||
NDN_CXX=$(ndnsec version)
|
||||
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
|
||||
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
|
||||
echo "$NDN_CXX" > "$PROJ-ndn-cxx.txt"
|
||||
INSTALLED_VERSION=NONE
|
||||
fi
|
||||
|
||||
if [[ -z $INSTALLED_VERSION ]]; then
|
||||
INSTALLED_VERSION=$(git -C "$PROJ" rev-parse HEAD 2>/dev/null || echo NONE)
|
||||
fi
|
||||
|
||||
sudo rm -rf "$PROJ-latest"
|
||||
git clone --depth 1 "https://github.com/named-data/$PROJ.git" "$PROJ-latest"
|
||||
LATEST_VERSION=$(git -C "$PROJ-latest" rev-parse HEAD 2>/dev/null || echo UNKNOWN)
|
||||
|
||||
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
|
||||
sudo rm -rf "$PROJ"
|
||||
mv "$PROJ-latest" "$PROJ"
|
||||
else
|
||||
sudo rm -rf "$PROJ-latest"
|
||||
fi
|
||||
|
||||
sudo rm -fr /usr/local/include/"$PROJ"
|
||||
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/"$PROJ".pc
|
||||
|
||||
pushd "$PROJ" >/dev/null
|
||||
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build
|
||||
sudo ./waf --color=yes install
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if [[ $ID_LIKE == *linux* ]]; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
|
||||
PROJ=ndn-svs
|
||||
|
||||
pushd "$CACHE_DIR" >/dev/null
|
||||
|
||||
INSTALLED_VERSION=
|
||||
NDN_CXX=$(ndnsec version)
|
||||
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
|
||||
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
|
||||
echo "$NDN_CXX" > "$PROJ-ndn-cxx.txt"
|
||||
INSTALLED_VERSION=NONE
|
||||
fi
|
||||
|
||||
if [[ -z $INSTALLED_VERSION ]]; then
|
||||
INSTALLED_VERSION=$(git -C "$PROJ" rev-parse HEAD 2>/dev/null || echo NONE)
|
||||
fi
|
||||
|
||||
sudo rm -rf "$PROJ-latest"
|
||||
git clone --depth 1 "https://github.com/named-data/$PROJ.git" "$PROJ-latest"
|
||||
LATEST_VERSION=$(git -C "$PROJ-latest" rev-parse HEAD 2>/dev/null || echo UNKNOWN)
|
||||
|
||||
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
|
||||
sudo rm -rf "$PROJ"
|
||||
mv "$PROJ-latest" "$PROJ"
|
||||
else
|
||||
sudo rm -rf "$PROJ-latest"
|
||||
fi
|
||||
|
||||
sudo rm -fr /usr/local/include/"$PROJ"
|
||||
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/"$PROJ".pc
|
||||
|
||||
pushd "$PROJ" >/dev/null
|
||||
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build
|
||||
sudo ./waf --color=yes install
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if [[ $ID_LIKE == *linux* ]]; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
+22
-31
@@ -1,45 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
if [[ -z $DISABLE_ASAN ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
fi
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
fi
|
||||
|
||||
set -x
|
||||
|
||||
git submodule init
|
||||
git submodule sync
|
||||
git submodule update
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
elif [[ -z $DISABLE_ASAN ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
|
||||
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
|
||||
# Configure/build in optimized mode with tests
|
||||
./waf --color=yes configure --with-tests
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build in release mode with tests
|
||||
./waf --color=yes configure --with-tests
|
||||
./waf --color=yes build
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
|
||||
# Configure/build in optimized mode without tests
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build in release mode without tests
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
fi
|
||||
|
||||
# Configure/build in debug mode with tests
|
||||
./waf --color=yes configure --debug --with-tests $ASAN $COVERAGE
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build in debug mode with tests
|
||||
./waf --color=yes configure --debug --with-chronosync --with-psync --with-svs --with-tests $ASAN $COVERAGE
|
||||
./waf --color=yes build
|
||||
|
||||
# (tests will be run against debug version)
|
||||
# (tests will be run against the debug version)
|
||||
|
||||
# Install
|
||||
sudo env "PATH=$PATH" ./waf --color=yes install
|
||||
sudo ./waf --color=yes install
|
||||
+20
-16
@@ -1,23 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Prepare environment
|
||||
rm -Rf ~/.ndn
|
||||
|
||||
ut_log_args() {
|
||||
echo --log_level=test_suite
|
||||
}
|
||||
set -eo pipefail
|
||||
|
||||
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
|
||||
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+=":check_initialization_order=1"
|
||||
ASAN_OPTIONS+=":detect_stack_use_after_return=1"
|
||||
ASAN_OPTIONS+=":strict_init_order=1"
|
||||
ASAN_OPTIONS+=":strict_string_checks=1"
|
||||
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=2"
|
||||
ASAN_OPTIONS+=":detect_container_overflow=0"
|
||||
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
|
||||
export ASAN_OPTIONS
|
||||
|
||||
# https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/runtime_config/summary.html
|
||||
export BOOST_TEST_BUILD_INFO=1
|
||||
export BOOST_TEST_COLOR_OUTPUT=1
|
||||
export BOOST_TEST_DETECT_MEMORY_LEAK=0
|
||||
export BOOST_TEST_LOGGER=HRF,test_suite,stdout:XML,all,build/xunit-log.xml
|
||||
|
||||
set -x
|
||||
|
||||
# Prepare environment
|
||||
rm -rf ~/.ndn
|
||||
|
||||
# Run unit tests
|
||||
./build/unit-tests-nlsr $(ut_log_args)
|
||||
./build/unit-tests-nlsr
|
||||
+14
-13
@@ -1,29 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
set -exo pipefail
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
# Generate an XML report (Cobertura format) and a detailed HTML report using gcovr
|
||||
# Note: trailing slashes are important in the paths below. Do not remove them!
|
||||
gcovr --object-directory build \
|
||||
--filter src/ \
|
||||
--exclude-throw-branches \
|
||||
--exclude-unreachable-branches \
|
||||
--cobertura build/coverage.xml \
|
||||
--html-details build/gcovr/ \
|
||||
--print-summary
|
||||
|
||||
# Generate a detailed HTML report using lcov
|
||||
lcov --quiet \
|
||||
--capture \
|
||||
--directory . \
|
||||
--exclude "$PWD/tests/*" \
|
||||
--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 \
|
||||
--output-directory build/lcov \
|
||||
--title "NLSR unit tests" \
|
||||
build/coverage.info
|
||||
fi
|
||||
+24
-24
@@ -1,36 +1,36 @@
|
||||
CONTINUOUS INTEGRATION SCRIPTS
|
||||
==============================
|
||||
# Continuous Integration Scripts
|
||||
|
||||
Environment Variables Used in Build Scripts
|
||||
-------------------------------------------
|
||||
## Environment Variables
|
||||
|
||||
- `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.
|
||||
- `ID`: lower-case string that identifies the operating system, for example: `ID=ubuntu`,
|
||||
`ID=centos`. See [os-release(5)] for more information. On macOS, where `os-release` is
|
||||
not available, we emulate it by setting `ID=macos`.
|
||||
|
||||
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
|
||||
- `ID_LIKE`: space-separated list of operating system identifiers that are closely related
|
||||
to the running OS. See [os-release(5)] for more information. The listed values are used
|
||||
by the CI scripts to select the proper behavior for different platforms and OS flavors.
|
||||
|
||||
Possible values for Linux:
|
||||
Examples:
|
||||
|
||||
* `[OS_TYPE]`: `Linux`
|
||||
* `[DISTRO_TYPE]`: `Ubuntu`
|
||||
* `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04`
|
||||
- On CentOS, `ID_LIKE="centos rhel fedora linux"`
|
||||
- On Ubuntu, `ID_LIKE="ubuntu debian linux"`
|
||||
|
||||
Possible values for OS X / macOS:
|
||||
- `VERSION_ID`: identifies the operating system version, excluding any release code names.
|
||||
See [os-release(5)] for more information. Examples: `VERSION_ID=42`, `VERSION_ID=22.04`.
|
||||
|
||||
* `[OS_TYPE]`: `OSX`
|
||||
* `[DISTRO_TYPE]`: `OSX` (can be absent)
|
||||
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12`
|
||||
- `JOB_NAME`: defines the type of the current CI job. Depending on the job type, the CI
|
||||
scripts can perform different tasks.
|
||||
|
||||
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
|
||||
the build scripts can perform different tasks.
|
||||
Supported values:
|
||||
|
||||
Possible values:
|
||||
- empty: default build task
|
||||
- `code-coverage`: debug build with tests and code coverage analysis
|
||||
- `limited-build`: only a single debug build with tests
|
||||
|
||||
* 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`: directory containing cached files from previous builds, e.g., a compiled
|
||||
version of ndn-cxx. If not set, `/tmp` is used.
|
||||
|
||||
- `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.
|
||||
- `DISABLE_ASAN`: disable building with AddressSanitizer. This is automatically set for
|
||||
the `code-coverage` job type.
|
||||
|
||||
- `WAF_JOBS`: number of parallel build jobs used by waf, defaults to 1.
|
||||
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
@@ -1,18 +0,0 @@
|
||||
has() {
|
||||
local saved_xtrace
|
||||
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
|
||||
set +x
|
||||
|
||||
local p=$1
|
||||
shift
|
||||
local i ret=1
|
||||
for i in "$@"; do
|
||||
if [[ "${i}" == "${p}" ]]; then
|
||||
ret=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
set ${saved_xtrace}
|
||||
return ${ret}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
A K M Mahmudul Hoque <akmhoque@gmail.com>
|
||||
<agawande@memphis.edu> <ashu2493@gmail.com>
|
||||
Nick Gordon <nmgordon@memphis.edu>
|
||||
Laqin Fan <lfan1@memphis.edu>
|
||||
Syed Obaid Amin <soamin@memphis.edu>
|
||||
Syed Obaid Amin <soamin@memphis.edu> <obaidasyed@gmail.com>
|
||||
Syed Obaid Amin <soamin@memphis.edu> <obaid@Obaids-MacBook.local>
|
||||
Syed Obaid Amin <soamin@memphis.edu> <obaid@obaids-macbook.memphis.edu>
|
||||
Syed Obaid Amin <soamin@memphis.edu> <soamin@mira.cs.memphis.edu>
|
||||
Syed Obaid Amin <soamin@memphis.edu> <soamin@wd222yx4.memphis.edu>
|
||||
Muktadir R Chowdhury <mrchwdhr@memphis.edu>
|
||||
Muktadir R Chowdhury <mrchwdhr@memphis.edu> <muktadir.rahman.c@gmail.com>
|
||||
<aa@cs.fiu.edu> <alexander.afanasyev@ucla.edu>
|
||||
<davidepesa@gmail.com> <davide.pesavento@lip6.fr>
|
||||
<enewberry@email.arizona.edu> <enewberry@cs.arizona.edu>
|
||||
Md Ashiqur Rahman <marahman@email.arizona.edu>
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
language: cpp
|
||||
dist: trusty
|
||||
sudo: required
|
||||
env:
|
||||
global:
|
||||
- JOB_NAME=limited-build
|
||||
- WAF_JOBS=2
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Linux/gcc
|
||||
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
|
||||
- os: linux
|
||||
env: COMPILER=g++-4.8
|
||||
- os: linux
|
||||
env: COMPILER=g++-4.9
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-4.9
|
||||
- os: linux
|
||||
env: COMPILER=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-5
|
||||
- os: linux
|
||||
env: COMPILER=g++-6
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-6
|
||||
- os: linux
|
||||
env: COMPILER=g++-7
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-7
|
||||
|
||||
# Linux/clang
|
||||
# https://apt.llvm.org/
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.5
|
||||
addons:
|
||||
apt:
|
||||
packages: clang-3.5
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.6
|
||||
addons:
|
||||
apt:
|
||||
packages: clang-3.6
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-precise-3.7", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.7
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.8
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-precise-3.8", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.8
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.9 DISABLE_ASAN=yes
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-3.9", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.9
|
||||
- os: linux
|
||||
env: COMPILER=clang++-4.0
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-4.0", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-4.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-5.0
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-5.0", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-5.0
|
||||
|
||||
# macOS/clang
|
||||
# https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
env: OSX_VERSION=10.11
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
env: OSX_VERSION=10.12
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
env: OSX_VERSION=10.12
|
||||
|
||||
before_script:
|
||||
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-14.04"; fi
|
||||
- if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi
|
||||
- if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi
|
||||
- ${CXX:-c++} --version
|
||||
- python --version
|
||||
|
||||
script:
|
||||
- ./.jenkins
|
||||
+53
-42
@@ -54,8 +54,9 @@ from waflib import Utils, Logs, Errors
|
||||
from waflib.Configure import conf
|
||||
from waflib.TaskGen import feature, after_method
|
||||
|
||||
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
|
||||
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/homebrew/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/homebrew/include', '/opt/local/include', '/sw/include']
|
||||
|
||||
BOOST_VERSION_FILE = 'boost/version.hpp'
|
||||
BOOST_VERSION_CODE = '''
|
||||
#include <iostream>
|
||||
@@ -90,13 +91,18 @@ int main() { boost::thread t; }
|
||||
|
||||
BOOST_LOG_CODE = '''
|
||||
#include <boost/log/trivial.hpp>
|
||||
int main() { BOOST_LOG_TRIVIAL(info) << "boost_log is working"; }
|
||||
'''
|
||||
|
||||
BOOST_LOG_SETUP_CODE = '''
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup/console.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
int main() {
|
||||
using namespace boost::log;
|
||||
add_common_attributes();
|
||||
add_console_log(std::clog, keywords::format = "%Message%");
|
||||
BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
|
||||
BOOST_LOG_TRIVIAL(info) << "boost_log_setup is working";
|
||||
}
|
||||
'''
|
||||
|
||||
@@ -145,7 +151,7 @@ def options(opt):
|
||||
opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
|
||||
help='''select libraries with tags (gd for debug, static is automatically added),
|
||||
see doc Boost, Getting Started, chapter 6.1''')
|
||||
opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
|
||||
opt.add_option('--boost-linkage_autodetect', action='store_true', dest='boost_linkage_autodetect',
|
||||
help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
|
||||
opt.add_option('--boost-toolset', type='string',
|
||||
default='', dest='boost_toolset',
|
||||
@@ -175,7 +181,7 @@ def boost_get_version(self, d):
|
||||
try:
|
||||
txt = node.read()
|
||||
except EnvironmentError:
|
||||
Logs.error("Could not read the file %r" % node.abspath())
|
||||
Logs.error('Could not read the file %r' % node.abspath())
|
||||
else:
|
||||
re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
|
||||
m1 = re_but1.search(txt)
|
||||
@@ -183,7 +189,7 @@ def boost_get_version(self, d):
|
||||
m2 = re_but2.search(txt)
|
||||
if m1 and m2:
|
||||
return (m1.group(1), m2.group(1))
|
||||
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
|
||||
return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(':')
|
||||
|
||||
@conf
|
||||
def boost_get_includes(self, *k, **kw):
|
||||
@@ -194,10 +200,10 @@ def boost_get_includes(self, *k, **kw):
|
||||
if self.__boost_get_version_file(d):
|
||||
return d
|
||||
if includes:
|
||||
self.end_msg('headers not found in %s' % includes)
|
||||
self.end_msg('headers not found in %s' % includes, 'YELLOW')
|
||||
self.fatal('The configuration failed')
|
||||
else:
|
||||
self.end_msg('headers not found, please provide a --boost-includes argument (see help)')
|
||||
self.end_msg('headers not found, please provide a --boost-includes argument (see help)', 'YELLOW')
|
||||
self.fatal('The configuration failed')
|
||||
|
||||
|
||||
@@ -240,10 +246,10 @@ def __boost_get_libs_path(self, *k, **kw):
|
||||
break
|
||||
if not path:
|
||||
if libs:
|
||||
self.end_msg('libs not found in %s' % libs)
|
||||
self.end_msg('libs not found in %s' % libs, 'YELLOW')
|
||||
self.fatal('The configuration failed')
|
||||
else:
|
||||
self.end_msg('libs not found, please provide a --boost-libs argument (see help)')
|
||||
self.end_msg('libs not found, please provide a --boost-libs argument (see help)', 'YELLOW')
|
||||
self.fatal('The configuration failed')
|
||||
|
||||
self.to_log('Found the boost path in %r with the libraries:' % path)
|
||||
@@ -313,7 +319,7 @@ def boost_get_libs(self, *k, **kw):
|
||||
libs.append(format_lib_name(file.name))
|
||||
break
|
||||
else:
|
||||
self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
|
||||
self.end_msg('lib %s not found in %s' % (lib, path.abspath()), 'YELLOW')
|
||||
self.fatal('The configuration failed')
|
||||
return libs
|
||||
|
||||
@@ -354,7 +360,7 @@ def _check_pthread_flag(self, *k, **kw):
|
||||
# ... -mt is also the pthreads flag for HP/aCC
|
||||
# -lpthread: GNU Linux, etc.
|
||||
# --thread-safe: KAI C++
|
||||
if Utils.unversioned_sys_platform() == "sunos":
|
||||
if Utils.unversioned_sys_platform() == 'sunos':
|
||||
# On Solaris (at least, for some versions), libc contains stubbed
|
||||
# (non-functional) versions of the pthreads routines, so link-based
|
||||
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
|
||||
@@ -362,23 +368,22 @@ def _check_pthread_flag(self, *k, **kw):
|
||||
# a function called by this macro, so we could check for that, but
|
||||
# who knows whether they'll stub that too in a future libc.) So,
|
||||
# we'll just look for -pthreads and -lpthread first:
|
||||
boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
|
||||
boost_pthread_flags = ['-pthreads', '-lpthread', '-mt', '-pthread']
|
||||
else:
|
||||
boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
|
||||
"-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
|
||||
boost_pthread_flags = ['', '-lpthreads', '-Kthread', '-kthread', '-llthread', '-pthread',
|
||||
'-pthreads', '-mthreads', '-lpthread', '--thread-safe', '-mt']
|
||||
|
||||
for boost_pthread_flag in boost_pthread_flags:
|
||||
try:
|
||||
self.env.stash()
|
||||
self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
|
||||
self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
|
||||
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
|
||||
|
||||
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False, quiet=True)
|
||||
self.end_msg(boost_pthread_flag)
|
||||
return
|
||||
except self.errors.ConfigurationError:
|
||||
self.env.revert()
|
||||
self.end_msg('None')
|
||||
self.end_msg('none')
|
||||
|
||||
@conf
|
||||
def check_boost(self, *k, **kw):
|
||||
@@ -403,21 +408,24 @@ def check_boost(self, *k, **kw):
|
||||
|
||||
var = kw.get('uselib_store', 'BOOST')
|
||||
|
||||
self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
|
||||
if self.env.DPKG_ARCHITECTURE:
|
||||
deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
|
||||
BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())
|
||||
if not self.env.DONE_FIND_BOOST_COMMON:
|
||||
self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
|
||||
if self.env.DPKG_ARCHITECTURE:
|
||||
deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
|
||||
BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())
|
||||
|
||||
self.start_msg('Checking boost includes')
|
||||
self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
|
||||
versions = self.boost_get_version(inc)
|
||||
self.env.BOOST_VERSION = versions[0]
|
||||
self.env.BOOST_VERSION_NUMBER = int(versions[1])
|
||||
self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
|
||||
int(versions[1]) / 100 % 1000,
|
||||
int(versions[1]) % 100))
|
||||
if Logs.verbose:
|
||||
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
|
||||
self.start_msg('Checking boost includes')
|
||||
self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
|
||||
versions = self.boost_get_version(inc)
|
||||
self.env.BOOST_VERSION = versions[0]
|
||||
self.env.BOOST_VERSION_NUMBER = int(versions[1])
|
||||
self.end_msg('%d.%d.%d' % (int(versions[1]) / 100000,
|
||||
int(versions[1]) / 100 % 1000,
|
||||
int(versions[1]) % 100))
|
||||
if Logs.verbose:
|
||||
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
|
||||
|
||||
self.env.DONE_FIND_BOOST_COMMON = True
|
||||
|
||||
if not params['lib'] and not params['stlib']:
|
||||
return
|
||||
@@ -429,7 +437,7 @@ def check_boost(self, *k, **kw):
|
||||
self.env['STLIBPATH_%s' % var] = [path]
|
||||
self.env['LIB_%s' % var] = libs
|
||||
self.env['STLIB_%s' % var] = stlibs
|
||||
self.end_msg('ok')
|
||||
self.end_msg(' '.join(libs + stlibs))
|
||||
if Logs.verbose:
|
||||
Logs.pprint('CYAN', ' path : %s' % path)
|
||||
Logs.pprint('CYAN', ' shared libs : %s' % libs)
|
||||
@@ -450,15 +458,18 @@ def check_boost(self, *k, **kw):
|
||||
self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
|
||||
if has_lib('thread'):
|
||||
self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
|
||||
if has_lib('log'):
|
||||
if has_lib('log') or has_lib('log_setup'):
|
||||
if not has_lib('thread'):
|
||||
self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
|
||||
if has_shlib('log'):
|
||||
if has_shlib('log') or has_shlib('log_setup'):
|
||||
self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
|
||||
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
|
||||
if has_lib('log_setup'):
|
||||
self.check_cxx(fragment=BOOST_LOG_SETUP_CODE, use=var, execute=False)
|
||||
else:
|
||||
self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
|
||||
|
||||
if params.get('linkage_autodetect', False):
|
||||
self.start_msg("Attempting to detect boost linkage flags")
|
||||
self.start_msg('Attempting to detect boost linkage flags')
|
||||
toolset = self.boost_get_toolset(kw.get('toolset', ''))
|
||||
if toolset in ('vc',):
|
||||
# disable auto-linking feature, causing error LNK1181
|
||||
@@ -480,10 +491,10 @@ def check_boost(self, *k, **kw):
|
||||
# we attempt to play with some known-to-work CXXFLAGS combinations
|
||||
for cxxflags in (['/MD', '/EHsc'], []):
|
||||
self.env.stash()
|
||||
self.env["CXXFLAGS_%s" % var] += cxxflags
|
||||
self.env['CXXFLAGS_%s' % var] += cxxflags
|
||||
try:
|
||||
try_link()
|
||||
self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
|
||||
self.end_msg('ok: winning cxxflags combination: %s' % (self.env['CXXFLAGS_%s' % var]))
|
||||
exc = None
|
||||
break
|
||||
except Errors.ConfigurationError as e:
|
||||
@@ -491,17 +502,17 @@ def check_boost(self, *k, **kw):
|
||||
exc = e
|
||||
|
||||
if exc is not None:
|
||||
self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
|
||||
self.end_msg('Could not auto-detect boost linking flags combination, you may report it to boost.py author', ex=exc)
|
||||
self.fatal('The configuration failed')
|
||||
else:
|
||||
self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
|
||||
self.end_msg('Boost linkage flags auto-detection not implemented (needed ?) for this toolchain')
|
||||
self.fatal('The configuration failed')
|
||||
else:
|
||||
self.start_msg('Checking for boost linkage')
|
||||
try:
|
||||
try_link()
|
||||
except Errors.ConfigurationError as e:
|
||||
self.end_msg("Could not link against boost libraries using supplied options")
|
||||
self.end_msg('Could not link against boost libraries using supplied options', 'YELLOW')
|
||||
self.fatal('The configuration failed')
|
||||
self.end_msg('ok')
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
import platform
|
||||
from waflib import Configure, Logs, Utils
|
||||
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
|
||||
help='Compile in debugging mode with minimal optimizations (-O0 or -Og)')
|
||||
help='Compile in debugging mode with minimal optimizations (-Og)')
|
||||
|
||||
|
||||
def configure(conf):
|
||||
conf.start_msg('Checking C++ compiler version')
|
||||
@@ -15,17 +18,27 @@ def configure(conf):
|
||||
errmsg = ''
|
||||
warnmsg = ''
|
||||
if cxx == 'gcc':
|
||||
if ccver < (4, 8, 2):
|
||||
if ccver < (7, 4, 0):
|
||||
errmsg = ('The version of gcc you are using is too old.\n'
|
||||
'The minimum supported gcc version is 4.8.2.')
|
||||
'The minimum supported gcc version is 9.3.')
|
||||
elif ccver < (9, 3, 0):
|
||||
warnmsg = ('Using a version of gcc older than 9.3 is not '
|
||||
'officially supported and may result in build failures.')
|
||||
conf.flags = GccFlags()
|
||||
elif cxx == 'clang':
|
||||
if ccver < (3, 4, 0):
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
if ccver < (10, 0, 0):
|
||||
errmsg = ('The version of Xcode you are using is too old.\n'
|
||||
'The minimum supported Xcode version is 12.4.')
|
||||
elif ccver < (12, 0, 0):
|
||||
warnmsg = ('Using a version of Xcode older than 12.4 is not '
|
||||
'officially supported and may result in build failures.')
|
||||
elif ccver < (7, 0, 0):
|
||||
errmsg = ('The version of clang you are using is too old.\n'
|
||||
'The minimum supported clang version is 3.4.0.')
|
||||
'The minimum supported clang version is 7.0.')
|
||||
conf.flags = ClangFlags()
|
||||
else:
|
||||
warnmsg = 'Note: %s compiler is unsupported' % cxx
|
||||
warnmsg = f'{cxx} compiler is unsupported'
|
||||
conf.flags = CompilerFlags()
|
||||
|
||||
if errmsg:
|
||||
@@ -33,18 +46,19 @@ def configure(conf):
|
||||
conf.fatal(errmsg)
|
||||
elif warnmsg:
|
||||
conf.end_msg(ccverstr, color='YELLOW')
|
||||
Logs.warn(warnmsg)
|
||||
Logs.warn('WARNING: ' + warnmsg)
|
||||
else:
|
||||
conf.end_msg(ccverstr)
|
||||
|
||||
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
|
||||
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
|
||||
|
||||
# General flags are always applied (e.g., selecting C++11 mode)
|
||||
# General flags are always applied (e.g., selecting C++ language standard)
|
||||
generalFlags = conf.flags.getGeneralFlags(conf)
|
||||
conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
|
||||
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
|
||||
conf.env.DEFINES += generalFlags['DEFINES']
|
||||
|
||||
|
||||
@Configure.conf
|
||||
def check_compiler_flags(conf):
|
||||
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
|
||||
@@ -67,10 +81,11 @@ def check_compiler_flags(conf):
|
||||
|
||||
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
|
||||
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
|
||||
"""
|
||||
if len(cxxflags) == 0:
|
||||
return
|
||||
@@ -86,10 +101,11 @@ def add_supported_cxxflags(self, cxxflags):
|
||||
self.end_msg(' '.join(supportedFlags))
|
||||
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
|
||||
Check which linkflags are supported by the active compiler and add them to env.LINKFLAGS variable.
|
||||
"""
|
||||
if len(linkflags) == 0:
|
||||
return
|
||||
@@ -106,13 +122,17 @@ def add_supported_linkflags(self, linkflags):
|
||||
self.env.prepend_value('LINKFLAGS', supportedFlags)
|
||||
|
||||
|
||||
class CompilerFlags(object):
|
||||
class CompilerFlags:
|
||||
def getCompilerVersion(self, conf):
|
||||
return tuple(int(i) for i in conf.env.CC_VERSION)
|
||||
|
||||
def getGeneralFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
|
||||
return {
|
||||
'CXXFLAGS': [],
|
||||
'LINKFLAGS': [],
|
||||
'DEFINES': ['BOOST_ASIO_NO_DEPRECATED', 'BOOST_FILESYSTEM_NO_DEPRECATED'],
|
||||
}
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
|
||||
@@ -122,93 +142,99 @@ class CompilerFlags(object):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
|
||||
|
||||
class GccBasicFlags(CompilerFlags):
|
||||
|
||||
class GccClangCommonFlags(CompilerFlags):
|
||||
"""
|
||||
This class defines basic flags that work for both gcc and clang compilers
|
||||
This class defines common flags that work for both gcc and clang compilers.
|
||||
"""
|
||||
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++11']
|
||||
flags = super().getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++17']
|
||||
if Utils.unversioned_sys_platform() != 'darwin':
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=lld']
|
||||
return flags
|
||||
|
||||
__cxxFlags = [
|
||||
'-fdiagnostics-color',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wpedantic',
|
||||
'-Wenum-conversion',
|
||||
'-Wextra-semi',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
__linkFlags = ['-Wl,-O1']
|
||||
|
||||
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',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-Og', '-g'] + self.__cxxFlags + [
|
||||
'-Werror',
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
]
|
||||
flags['LINKFLAGS'] += self.__linkFlags
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O2',
|
||||
'-g',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O2', '-g1'] + self.__cxxFlags
|
||||
flags['LINKFLAGS'] += self.__linkFlags
|
||||
return flags
|
||||
|
||||
class GccFlags(GccBasicFlags):
|
||||
|
||||
class GccFlags(GccClangCommonFlags):
|
||||
__cxxFlags = [
|
||||
'-Wcatch-value=2',
|
||||
'-Wcomma-subscript', # enabled by default in C++20
|
||||
'-Wduplicated-branches',
|
||||
'-Wduplicated-cond',
|
||||
'-Wlogical-op',
|
||||
'-Wredundant-tags',
|
||||
'-Wvolatile', # enabled by default in C++20
|
||||
]
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccFlags, self).getDebugFlags(conf)
|
||||
if self.getCompilerVersion(conf) < (5, 1, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
if platform.machine() == 'armv7l':
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccFlags, self).getOptimizedFlags(conf)
|
||||
if self.getCompilerVersion(conf) < (5, 1, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
if platform.machine() == 'armv7l':
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
class ClangFlags(GccBasicFlags):
|
||||
|
||||
class ClangFlags(GccClangCommonFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getGeneralFlags(conf)
|
||||
if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0):
|
||||
flags = super().getGeneralFlags(conf)
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
# Bug #4296
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include']] # for MacPorts
|
||||
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
|
||||
flags['CXXFLAGS'] += [
|
||||
['-isystem', f'{brewdir}/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include'], # for MacPorts
|
||||
]
|
||||
elif Utils.unversioned_sys_platform() == 'freebsd':
|
||||
# Bug #4790
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
|
||||
return flags
|
||||
|
||||
__cxxFlags = [
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wextra-semi',
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-error=deprecated-register',
|
||||
'-Wno-error=infinite-recursion', # Bug #3358
|
||||
'-Wno-error=keyword-macro', # Bug #3235
|
||||
'-Wno-error=unneeded-internal-declaration', # Bug #1588
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
version = self.getCompilerVersion(conf)
|
||||
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
|
||||
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wextra-semi',
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
version = self.getCompilerVersion(conf)
|
||||
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
|
||||
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
return flags
|
||||
@@ -44,28 +44,28 @@ def apply_sphinx(self):
|
||||
task.inputs.append(conf)
|
||||
|
||||
confdir = conf.parent.abspath()
|
||||
buildername = getattr(self, "builder", "html")
|
||||
srcdir = getattr(self, "srcdir", confdir)
|
||||
outdir = self.path.find_or_declare(getattr(self, "outdir", buildername)).get_bld()
|
||||
doctreedir = getattr(self, "doctreedir", os.path.join(outdir.abspath(), ".doctrees"))
|
||||
buildername = getattr(self, 'builder', 'html')
|
||||
srcdir = getattr(self, 'srcdir', confdir)
|
||||
outdir = self.path.find_or_declare(getattr(self, 'outdir', buildername)).get_bld()
|
||||
doctreedir = getattr(self, 'doctreedir', os.path.join(outdir.abspath(), '.doctrees'))
|
||||
|
||||
task.env['BUILDERNAME'] = buildername
|
||||
task.env['SRCDIR'] = srcdir
|
||||
task.env['DOCTREEDIR'] = doctreedir
|
||||
task.env['OUTDIR'] = outdir.abspath()
|
||||
task.env['VERSION'] = "version=%s" % self.VERSION
|
||||
task.env['RELEASE'] = "release=%s" % self.VERSION
|
||||
task.env['VERSION'] = 'version=%s' % self.version
|
||||
task.env['RELEASE'] = 'release=%s' % getattr(self, 'release', self.version)
|
||||
|
||||
import imp
|
||||
confData = imp.load_source('sphinx_conf', conf.abspath())
|
||||
|
||||
if buildername == "man":
|
||||
if buildername == 'man':
|
||||
for i in confData.man_pages:
|
||||
target = outdir.find_or_declare('%s.%d' % (i[1], i[4]))
|
||||
task.outputs.append(target)
|
||||
|
||||
if self.install_path:
|
||||
self.bld.install_files("%s/man%d/" % (self.install_path, i[4]), target)
|
||||
self.bld.install_files('%s/man%d/' % (self.install_path, i[4]), target)
|
||||
else:
|
||||
task.outputs.append(outdir)
|
||||
|
||||
|
||||
+34
-53
@@ -1,57 +1,38 @@
|
||||
NLSR Authors
|
||||
============
|
||||
# NLSR Authors
|
||||
|
||||
NLSR is an open source project includes contributions from the members of the
|
||||
[NDN project team](http://named-data.net/project/participants/).
|
||||
The following lists maintainers, primary developers, and all much-appreciated contributors to NLSR in alphabetical order.
|
||||
The specific contributions of individual authors can be obtained from the git history of the [official NLSR repository](https://github.com/named-data/NLSR).
|
||||
If you would like to become a contributor to the official repository, please follow the recommendations in <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>.
|
||||
|
||||
## Project co-leads:
|
||||
* Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
|
||||
* Adam Alyyan <https://github.com/a64adam>
|
||||
* Syed Obaid Amin <http://obaidamin.weebly.com/>
|
||||
* Pedro David Arjona Villicaña <https://github.com/david-arjona>
|
||||
* Muktadir R. Chowdhury <https://github.com/alvyC>
|
||||
* Damian Coomes <https://github.com/dmcoomes>
|
||||
* ***(Maintainer)*** Saurab Dulal <https://dulalsaurab.github.io>
|
||||
* Laqin Fan <https://github.com/laqinfan>
|
||||
* Simon Fayer <https://github.com/sfayer>
|
||||
* ***(Former Maintainer)*** Ashlesh Gawande <https://www.linkedin.com/in/agawande>
|
||||
* ***(Former Maintainer)*** Nicholas Gordon <https://github.com/gorgonical>
|
||||
* ***(Former Maintainer)*** A. K. M. Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
|
||||
* ***(Former Maintainer)*** Vince Lehman <http://vslehman.com>
|
||||
* Tianxing Ma <https://github.com/matianxing1992>
|
||||
* Spyridon Mastorakis <https://sites.google.com/site/spyridonmastorakis>
|
||||
* Eric Newberry <https://ericnewberry.com>
|
||||
* João Pereira <http://website.jpereira.co.uk>
|
||||
* Davide Pesavento <https://github.com/Pesa>
|
||||
* Md Ashiqur Rahman <https://ashiqrahman.com>
|
||||
* Junxiao Shi <https://cs.arizona.edu/~shijunxiao>
|
||||
* Salvatore Signorello <https://wwwen.uni.lu/snt/people/salvatore_signorello>
|
||||
* Jiewen Tan <https://www.linkedin.com/in/jiewentan>
|
||||
* Alejandro Gil Torres <https://github.com/gltorres>
|
||||
* Ryan Wickman <http://rwickman.github.io>
|
||||
* Yingdi Yu <https://irl.cs.ucla.edu/~yingdi>
|
||||
* Minsheng Zhang <https://www.linkedin.com/in/minsheng-zhang-032023a1>
|
||||
|
||||
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
|
||||
* Nicholas Gordon <nmgordon@memphis.edu>
|
||||
## Technical Advisors
|
||||
|
||||
## Past project leads:
|
||||
|
||||
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
|
||||
## Technical advisors:
|
||||
|
||||
* Lan Wang <http://www.cs.memphis.edu/~lanwang/>
|
||||
* Beichuan Zhang <http://www.cs.arizona.edu/~bzhang/>
|
||||
* Lixia Zhang <http://www.cs.ucla.edu/~lixia/>
|
||||
|
||||
|
||||
## All project authors, contributors and their affiliations:
|
||||
|
||||
* The University of Memphis
|
||||
|
||||
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
|
||||
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
|
||||
* Minsheng Zhang <https://www.linkedin.com/in/minsheng-zhang-032023a1>
|
||||
* Syed Obaid Amin <http://obaidamin.weebly.com/>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
* Muktadir R Chowdhury <mrchwdhr@memphis.edu>
|
||||
* Nicholas Gordon <nmgordon@memphis.edu>
|
||||
* Laqin Fan <lfan1@memphis.edu>
|
||||
* Damian Coomes <dmcoomes@memphis.edu>
|
||||
* Saurab Dulal <sdulal@memphis.edu>
|
||||
|
||||
* University of California, Los Angeles
|
||||
|
||||
* Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
|
||||
* Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
* Spyridon Mastorakis <http://cs.ucla.edu/~mastorakis/>
|
||||
* Jiewen Tan <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 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).
|
||||
* Lan Wang <http://www.cs.memphis.edu/~lanwang>
|
||||
* Beichuan Zhang <https://cs.arizona.edu/~bzhang>
|
||||
* Lixia Zhang <https://web.cs.ucla.edu/~lixia>
|
||||
+371
-370
File diff suppressed because it is too large.
Load diff
+18
-18
@@ -1,15 +1,17 @@
|
||||
Requirements
|
||||
------------
|
||||
# Notes for NLSR developers
|
||||
|
||||
Contributions to NLSR must be licensed under GPL 3.0 or compatible license. If you are
|
||||
choosing GPL 3.0, please use the following license boilerplate in all `.hpp` and `.cpp`
|
||||
files:
|
||||
If you are new to the NDN software community, please read our
|
||||
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md).
|
||||
|
||||
Include the following header in all `.hpp` and `.cpp` files:
|
||||
## Licensing requirements
|
||||
|
||||
Contributions to NLSR must be licensed under the GPL v3 or a compatible license.
|
||||
If you choose the GPL v3, please use the following license boilerplate in all `.hpp`
|
||||
and `.cpp` files:
|
||||
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) [Year(s)], [Copyright Holder(s)].
|
||||
/*
|
||||
* Copyright (c) [Year(s)], [Copyright Holder(s)].
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
@@ -24,17 +26,15 @@ Include the following header in all `.hpp` and `.cpp` files:
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
If you are affiliated with an NSF-supported NDN project institution,
|
||||
please use the [NDN Team License Boilerplate]
|
||||
(https://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
|
||||
If you are affiliated with an NSF-supported NDN project institution, please use the [NDN Team License
|
||||
Boilerplate](https://redmine.named-data.net/projects/nlsr/wiki/NDN_Team_License_Boilerplate_(NLSR)).
|
||||
|
||||
Recommendations
|
||||
---------------
|
||||
## Recommendations
|
||||
|
||||
NLSR code is subject to the code style, defined here:
|
||||
https://redmine.named-data.net/projects/nfd/wiki/CodeStyle
|
||||
NLSR code is subject to the code style defined
|
||||
[here](https://redmine.named-data.net/projects/nfd/wiki/CodeStyle).
|
||||
|
||||
NLSR Developer's guide can be found here:
|
||||
https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf
|
||||
NLSR Developer's guide can be found
|
||||
[here](https://github.com/named-data/NLSR/blob/developers-guide/NLSR-Developers-Guide.pdf).
|
||||
@@ -1,51 +1,51 @@
|
||||
NLSR - Named Data Link State Routing Protocol
|
||||
=============================================
|
||||
# NLSR: Named Data Link State Routing Protocol
|
||||
|
||||
For complete documentation and more extensive information,
|
||||
please visit the [NLSR homepage](http://named-data.net/doc/NLSR/current/).
|
||||
[](https://github.com/named-data/NLSR/actions/workflows/ci.yml)
|
||||
[](https://github.com/named-data/NLSR/actions/workflows/docs.yml)
|
||||

|
||||

|
||||
|
||||
If you are new to the NDN community of software generally, read the
|
||||
[Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md).
|
||||
> For more extensive documentation, please visit the [NLSR homepage](https://docs.named-data.net/NLSR/current/).
|
||||
|
||||
## Overview
|
||||
|
||||
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/).
|
||||
NLSR is a routing protocol for Named Data Networking (NDN) that populates the Routing Information
|
||||
Base (RIB) of an NDN router, such as [NFD](https://github.com/named-data/NFD). NLSR continues to
|
||||
evolve alongside the core [NDN protocol](https://docs.named-data.net/NDN-packet-spec/current/).
|
||||
|
||||
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
|
||||
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](https://named-data.net/project/participants/).
|
||||
For more details, please refer to [AUTHORS.md](https://github.com/named-data/NLSR/blob/master/AUTHORS.md).
|
||||
Bug reports and feedback are highly appreciated and can be made through the
|
||||
[Redmine site](https://redmine.named-data.net/projects/nlsr).
|
||||
|
||||
The main design goal of NLSR is to provide a routing protocol to populate NDN's FIB.
|
||||
The main design goal of NLSR is to provide a routing protocol to populate NDN's 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. NLSR
|
||||
will continue to evolve over time to include neighbor discovery and to become a full
|
||||
fledged inter-domain routing protocol for NDN.
|
||||
|
||||
NLSR was mainly developed by members of the NSF-sponsored [NDN project team](
|
||||
https://named-data.net/project/participants/). See [`AUTHORS.md`](AUTHORS.md) for details.
|
||||
|
||||
Source releases
|
||||
---------------
|
||||
## Source releases
|
||||
|
||||
The source code and source-code installation instructions are always available at
|
||||
the following links:
|
||||
The source code and installation instructions are available at the following locations:
|
||||
|
||||
- [Installation](https://named-data.net/doc/NLSR/current/INSTALL.html)
|
||||
- [Getting Started with NLSR](https://named-data.net/doc/NLSR/current/GETTING-STARTED.html)
|
||||
- [GitHub NLSR repository](https://github.com/named-data/NLSR)
|
||||
- [Installation](https://docs.named-data.net/NLSR/current/INSTALL.html)
|
||||
- [Getting started with NLSR](https://docs.named-data.net/NLSR/current/GETTING-STARTED.html)
|
||||
- [NLSR GitHub repository](https://github.com/named-data/NLSR)
|
||||
|
||||
Additional information
|
||||
----------------------
|
||||
## Reporting bugs
|
||||
|
||||
- [Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md)
|
||||
- [NLSR Wiki](https://redmine.named-data.net/projects/nlsr/wiki/)
|
||||
- Feature requests and bug reports are welcome on our
|
||||
[NLSR on NDN Redmine](https://redmine.named-data.net/projects/nlsr)
|
||||
Please submit any bug reports or feature requests to the
|
||||
[NLSR issue tracker](https://redmine.named-data.net/projects/nlsr/issues).
|
||||
|
||||
## Additional resources
|
||||
|
||||
- [Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md)
|
||||
- [NLSR Wiki](https://redmine.named-data.net/projects/nlsr/wiki)
|
||||
- [NLSR Issue Tracker](https://redmine.named-data.net/projects/nlsr/issues)
|
||||
- [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)
|
||||
|
||||
## License
|
||||
|
||||
NLSR is free software distributed under the GNU General Public License version 3.
|
||||
See [`COPYING.md`](COPYING.md) for details.
|
||||
+21
-12
@@ -7,14 +7,13 @@ Getting Started with NLSR
|
||||
Getting Source
|
||||
--------------
|
||||
|
||||
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`_
|
||||
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`__
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
:doc:`INSTALL`
|
||||
|
||||
|
||||
Important Notes About Configuration
|
||||
-----------------------------------
|
||||
|
||||
@@ -23,10 +22,9 @@ 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>`_
|
||||
For users who were relying on NLSR to automagically configure their networks,
|
||||
this must now be done with ``nfdc``. See ``man nfdc`` for its documentation
|
||||
(`online version <https://docs.named-data.net/NFD/current/manpages/nfdc.html>`__).
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
@@ -70,9 +68,20 @@ value are enabled.
|
||||
ERROR error messages
|
||||
FATAL fatal (will be logged unconditionally)
|
||||
|
||||
To obtain logs for NLSR, set the NDN_LOG environment variable with the correct prefix and
|
||||
log-level settings. For example, running the command `export NDN_LOG=nlsr.*=TRACE && nlsr`
|
||||
will display all log messages in NLSR with a DEBUG level or below. If the user is presented
|
||||
with an error message `User does not have read and write permission on the directory` it can
|
||||
be circumvented by running the application with sudo: `sudo env NDN_LOG=nlsr.*=DEBUG nlsr`.
|
||||
Use `man ndn-log` for more detailed instructions.
|
||||
To obtain logs for NLSR, set the ``NDN_LOG`` environment variable with the correct prefix
|
||||
and log-level settings. For example, running the following command will display all log
|
||||
messages in NLSR with a DEBUG level or below.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
NDN_LOG='nlsr.*=DEBUG' nlsr
|
||||
|
||||
If the user is presented with an error message "User does not have read and write
|
||||
permission on the directory" it can be circumvented by running the application with sudo:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo env NDN_LOG='nlsr.*=DEBUG' nlsr
|
||||
|
||||
See ``man ndn-log`` for more details (`online version
|
||||
<https://docs.named-data.net/ndn-cxx/current/manpages/ndn-log.html>`__).
|
||||
+32
-13
@@ -7,36 +7,55 @@ NLSR Installation Instructions
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
- `NFD <https://named-data.net/doc/NFD/>`_ and its requirements:
|
||||
- `NFD <https://github.com/named-data/NFD>`__ and its dependencies.
|
||||
|
||||
Refer to `Getting started with NFD <https://named-data.net/doc/NFD/current/INSTALL.html>`_
|
||||
for detailed installation and running instruction.
|
||||
Check out the `documentation <https://docs.named-data.net/NFD/current/INSTALL.html>`__
|
||||
for detailed installation and running instructions.
|
||||
|
||||
- ChronoSync library
|
||||
- PSync library [optional but recommended, enabled by default]
|
||||
|
||||
::
|
||||
Download the PSync library and build it according to the instructions available at
|
||||
https://github.com/named-data/PSync#build
|
||||
|
||||
https://github.com/named-data/ChronoSync#build
|
||||
- ChronoSync library [optional, deprecated]
|
||||
|
||||
For testing purposes, NLSR can be optionally built with ChronoSync support. Download
|
||||
the ChronoSync library and build it according to the instructions available at
|
||||
https://github.com/named-data/ChronoSync#build
|
||||
|
||||
- SVS library [optional]
|
||||
|
||||
NLSR can be used with State Vector Sync as the underlying Sync protocol. Download
|
||||
the ndn-svs library and build it according to the instructions available at
|
||||
https://github.com/named-data/ndn-svs#installation
|
||||
|
||||
Note that at least one Sync library must be enabled.
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
Execute the following commands to build NLSR:
|
||||
|
||||
::
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure
|
||||
./waf
|
||||
sudo ./waf install
|
||||
|
||||
Refer to ``./waf –help`` for more options that can be used during the configure stage and
|
||||
Refer to ``./waf --help`` for more options that can be used during the configure stage and
|
||||
how to properly configure NLSR.
|
||||
|
||||
If your pkgconfig path is not set properly you can do the following before running ``./waf
|
||||
configure``
|
||||
If your pkgconfig path is not set properly, you can do the following before running ``./waf
|
||||
configure``:
|
||||
|
||||
::
|
||||
.. code-block:: sh
|
||||
|
||||
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
|
||||
or
|
||||
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
|
||||
# or
|
||||
export PKG_CONFIG_PATH=/path/to/pkgconfig/on/your/machine
|
||||
|
||||
If ChronoSync support is desired, NLSR needs to be configured with the following option:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure --with-chronosync
|
||||
@@ -1,4 +0,0 @@
|
||||
NLSR Release Notes
|
||||
==================
|
||||
|
||||
.. include:: release-notes-latest.rst
|
||||
+14
-3
@@ -35,6 +35,9 @@ The number represents the connecting face id. For example,
|
||||
We will walk through setting up the faces and creating the configuration file for
|
||||
``/ndn/edu/memphis/%C1.Router/router1``.
|
||||
|
||||
It is recommended to configure security as described at :doc:`SECURITY-CONFIG`, before
|
||||
starting router configuration.
|
||||
|
||||
Step 1. Ensuring nfd is running
|
||||
-------------------------------
|
||||
|
||||
@@ -46,7 +49,15 @@ Type the following in the terminal:
|
||||
|
||||
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.
|
||||
<https://docs.named-data.net/NFD/current/INSTALL.html>`_ to run nfd.
|
||||
|
||||
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.
|
||||
|
||||
To create faces it is now necessary to use the ``nfdc`` command. See ``man nfdc`` for
|
||||
its documentation (`online version <https://docs.named-data.net/NFD/current/manpages/nfdc.html>`__).
|
||||
|
||||
Step 2. Determining FaceUri
|
||||
---------------------------
|
||||
@@ -83,7 +94,7 @@ configuration commands follows:
|
||||
; InterestLifetime (in seconds) for LSA fetching
|
||||
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
|
||||
|
||||
seq-dir /var/lib/nlsr/
|
||||
state-dir /var/lib/nlsr/ ; state directory to store all dynamic changes to NLSR
|
||||
}
|
||||
|
||||
; the neighbors section contains the configuration for router's neighbors and hello's behavior
|
||||
@@ -197,7 +208,7 @@ To avoid this, the directory can be set in a user-owned directory. For example:
|
||||
{
|
||||
...
|
||||
|
||||
seq-dir /home/username/nlsr/log ; path for sequence directory (Absolute path)
|
||||
state-dir /home/username/nlsr/log ; path for sequence directory and other dynamic changes (Absolute path)
|
||||
|
||||
}
|
||||
...
|
||||
|
||||
@@ -35,12 +35,15 @@ router /\<network\>/\<site\>/%C1.Router/\<router-name\> /ndn/edu/ucla/%C
|
||||
NLSR /\<network\>/\<site\>/%C1.Router/\<router-name\>/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR /ndn/edu/ucla/%C1.Router/rt1/NLSR/KEY/5/%00/%01
|
||||
======== ===================================================== ================================= ===============================================
|
||||
|
||||
Users should create keys according to the naming and signing hierarchies above.
|
||||
Users should create keys according to the naming and signing hierarchies above. The
|
||||
``%C1.Operator`` and ``%C1.Router`` labels are NDN keywords that should not be modified
|
||||
by the user.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Detailed information about key setup is given in NLSR Developer's Guide.
|
||||
Detailed information about key setup is given in NLSR Developer's Guide and the
|
||||
:doc:`beginners-guide`.
|
||||
|
||||
Certificate Publishing
|
||||
----------------------
|
||||
|
||||
Whitespace-only changes.
@@ -0,0 +1,887 @@
|
||||
==========================================================
|
||||
A beginners guide to installing and testing NLSR on Fedora
|
||||
==========================================================
|
||||
|
||||
:Authors: David Arjona-Villicaña, Octavio Renteria-Vidales, Ashlesh Gawande
|
||||
:Date: November, 2018
|
||||
:Abstract: This is an easy to follow guide on how to install and test the NLSR routing protocol for NDN using two Fedora 28 machines. The commands and the paths used in this guide have been tested only in Fedora, although a similar procedure should be used for other linux systems. Specifically, the testing section (§ `5 <#test>`__) is platform independent. Therefore users who have NLSR already installed may skip to this section. Since neither NDN, NLSR nor Fedora are static software developments, it is expected that some commands and features in this guide will change over time. However, this guide is as accurate as it could be at the time it was published.
|
||||
|
||||
.. role:: raw-latex(raw)
|
||||
:format: latex
|
||||
|
||||
|
||||
.. _intro:
|
||||
|
||||
1. Introduction
|
||||
===============
|
||||
|
||||
The following instructions are based on the information provided at the
|
||||
Named Data Networking project web page [NDNmain]_.
|
||||
Before installing NLSR it is necessary to install different libraries and
|
||||
programs: ndn-cxx, NFD, ChronoSync [optional], ndn-svs [optional] and PSync.
|
||||
This document describes the necessary steps to correctly install these
|
||||
programs (§ `2 <#ndncxx>`__, `3 <#nfd>`__ and `4 <#nlsr>`__) and a brief
|
||||
guide on how to configure and test NLSR using a simple two-node
|
||||
network (§ `5 <#test>`__).
|
||||
|
||||
Many of the commands in this guide need to be executed as *root*.
|
||||
Starting from Fedora 28, there is no need to set a root user
|
||||
[Kolman2018]_. However it is possible to define it,
|
||||
using the following command:
|
||||
|
||||
::
|
||||
|
||||
$ sudo -i
|
||||
|
||||
And then using the ``passwd`` command to set up a password. After setting
|
||||
up the root user, it is possible to become root by employing the
|
||||
following command and providing the root password when prompted:
|
||||
|
||||
::
|
||||
|
||||
$ su -
|
||||
|
||||
Fedora employs the ``dnf`` command to install and verify installed
|
||||
packages. The following commands may become useful during the
|
||||
installation process and should be executed as root:
|
||||
|
||||
- To verify that all installed packages are up to date
|
||||
|
||||
::
|
||||
|
||||
$ dnf update
|
||||
|
||||
- To verify if a package is already installed in the system
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed <package-name>
|
||||
|
||||
- To search for information about a package or family of packages (not
|
||||
necessarily installed in the system).
|
||||
|
||||
::
|
||||
|
||||
$ dnf info <package-name>
|
||||
|
||||
- To install a package in the system.
|
||||
|
||||
::
|
||||
|
||||
$ dnf install <package-name>
|
||||
|
||||
It is also a good installation practice to download and install all the
|
||||
NDN programs in a common directory. Therefore, it is recommended to
|
||||
create a directory at the home directory where all the following
|
||||
programs may get installed. The name of this directory is not important.
|
||||
However, the following are provided as suggestions: project, NDNproject,
|
||||
NDNprograms. Each of the programs in the following sections should be
|
||||
downloaded to their own directory using the ``git`` command, and then
|
||||
compiled in this directory.
|
||||
|
||||
.. _ndncxx:
|
||||
|
||||
2. Installing ndn-cxx
|
||||
=====================
|
||||
|
||||
2.1 Before installing ndn-cxx
|
||||
-----------------------------
|
||||
|
||||
An updated list of the packages and programs that need to be installed
|
||||
before installing ndn-cxx, is provided at [NDN-cxx]_.
|
||||
This list is also reproduced below with the commands to verify that all
|
||||
the packages have been installed in the system. The following commands
|
||||
should be run as root:
|
||||
|
||||
#. gcc and gcc-c++
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed gcc
|
||||
$ dnf list --installed gcc-c++
|
||||
|
||||
#. Python version 3.8 or later
|
||||
|
||||
::
|
||||
|
||||
$ python3 -V
|
||||
|
||||
#. SQLite 3.x
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed sqlite-devel
|
||||
|
||||
#. OpenSSL version 1.1.1 or later
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed openssl-devel
|
||||
|
||||
#. pkgconf that replaces pkg-config
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed pkgconf*
|
||||
|
||||
#. Boost libraries version 1.71.0 or later
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed boost-devel
|
||||
|
||||
#. git
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed git
|
||||
|
||||
#. doxygen (optional)
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed doxygen
|
||||
|
||||
#. graphviz (optional)
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed graphviz
|
||||
|
||||
#. python3-pip (optional)
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed python3-pip
|
||||
|
||||
#. After verifying that the python3-pip package has been installed, it
|
||||
is necessary to run the following command:
|
||||
|
||||
::
|
||||
|
||||
$ pip install sphinx sphinxcontrib-doxylink
|
||||
|
||||
2.2 Downloading and installing ndn-cxx
|
||||
--------------------------------------
|
||||
|
||||
The ``git`` command allows to download the ndn-cxx library in its own
|
||||
folder, also called *ndn-cxx*. Therefore it is recommended to execute
|
||||
this command at the directory created at § `1 <#intro>`__:
|
||||
|
||||
::
|
||||
|
||||
$ git clone --depth 1 https://github.com/named-data/ndn-cxx.git
|
||||
|
||||
Move to the ndn-cxx directory:
|
||||
|
||||
::
|
||||
|
||||
$ cd ndn-cxx
|
||||
|
||||
Use the following command to verify that everything is ready to compile.
|
||||
If an error message displays, it is necessary to fix it before
|
||||
continuing:
|
||||
|
||||
::
|
||||
|
||||
$ ./waf configure --with-examples
|
||||
|
||||
Compile the ndn-cxx library and install the compiled files at the
|
||||
system's directories:
|
||||
|
||||
::
|
||||
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
|
||||
2.3 Configuring ndn-cxx
|
||||
-----------------------
|
||||
|
||||
The commands in this subsection need to be run as root. First, it is
|
||||
necessary to create file *local.conf*, which contains a line with the
|
||||
location for the ndn-cxx library:
|
||||
|
||||
::
|
||||
|
||||
$ echo /usr/local/lib64 >> /etc/ld.so.conf.d/local.conf
|
||||
|
||||
The following command configures the libraries:
|
||||
|
||||
::
|
||||
|
||||
$ ldconfig -v | grep ndn
|
||||
|
||||
This command should display a line similar to the following:
|
||||
|
||||
::
|
||||
|
||||
libndn-cxx.so.0.6.1 -> libndn-cxx.so.0.6.1
|
||||
|
||||
Configure the NDN path:
|
||||
|
||||
::
|
||||
|
||||
$ echo export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig >> /etc/profile.d/ndn.sh
|
||||
|
||||
After this command has been executed, it is necessary to apply the
|
||||
changes by either logging out and back in, and then running the
|
||||
following command:
|
||||
|
||||
::
|
||||
|
||||
$ printenv | grep PKG
|
||||
|
||||
Or by executing the following command:
|
||||
|
||||
::
|
||||
|
||||
$ ./etc/profile.d/ndn.sh
|
||||
|
||||
For more information and examples about how to compile and configure
|
||||
this library, users should read the ndn-cxx guide at
|
||||
[NDN-cxx]_.
|
||||
|
||||
.. _nfd:
|
||||
|
||||
3. Installing NFD
|
||||
=================
|
||||
|
||||
3.1 Before installing NFD
|
||||
-------------------------
|
||||
|
||||
An updated list of the packages and programs that need to be installed
|
||||
before NFD is provided at [NDNNFD]_. Before installing
|
||||
NFD it is necessary to verify that the following packages are installed:
|
||||
|
||||
#. pcap library
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed libpcap-devel
|
||||
|
||||
3.2 Downloading and installing NFD
|
||||
----------------------------------
|
||||
|
||||
This software is downloaded and installed in a folder called *NFD*, which
|
||||
should be created at the directory defined at § `1 <#intro>`__. The
|
||||
following commands need to be run as a regular user:
|
||||
|
||||
::
|
||||
|
||||
$ git clone --depth 1 https://github.com/named-data/NFD.git
|
||||
$ cd NFD
|
||||
$ ./waf configure
|
||||
|
||||
If the previous command prints an error message saying that waf cannot
|
||||
find WebSocket, it is necessary to follow the instructions provided by
|
||||
this same output, which tells the user to run the following command:
|
||||
|
||||
::
|
||||
|
||||
$ git submodule update --init
|
||||
|
||||
After executing these instructions, complete the configuration by running
|
||||
``./waf configure`` again. Then complete the installation by means of the
|
||||
following commands:
|
||||
|
||||
::
|
||||
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
|
||||
3.3 Configuring NFD
|
||||
-------------------
|
||||
|
||||
Create a configuration file by running the following command as root:
|
||||
|
||||
::
|
||||
|
||||
$ cp /usr/local/etc/ndn/nfd.conf.sample /usr/local/etc/ndn/nfd.conf
|
||||
|
||||
After the configuration file has been created, NFD's behavior may be
|
||||
changed by modifying this file. Once the configuration file has been
|
||||
created, it is recommended to start NFD by using the following command:
|
||||
|
||||
::
|
||||
|
||||
$ nfd-start
|
||||
|
||||
This command does not properly allow to employ the command window to
|
||||
enter new commands; however it displays the NFD logs. Therefore, it is
|
||||
recommended to open a new command window. This second window may be used
|
||||
to verify NDF's status and then stop NFD by using the following
|
||||
commands:
|
||||
|
||||
::
|
||||
|
||||
$ nfd-status
|
||||
$ nfd-stop
|
||||
|
||||
.. _nlsr:
|
||||
|
||||
4. Installing NLSR
|
||||
==================
|
||||
|
||||
4.1 Installing PSync
|
||||
--------------------
|
||||
|
||||
Before installing NLSR, it is also necessary to download and install
|
||||
PSync. PSync is a synchronization library which allows NLSR to synchronize LSAs
|
||||
similar to ChronoSync. More information about PSync may be found at [PSync]_.
|
||||
This library may be installed by running the following commands as a regular
|
||||
user and at the directory defined at § `1 <#intro>`__:
|
||||
|
||||
::
|
||||
|
||||
$ git clone --depth 1 https://github.com/named-data/PSync.git
|
||||
$ cd PSync
|
||||
$ ./waf configure
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
|
||||
The following command needs to be used again to configure the libraries:
|
||||
|
||||
::
|
||||
|
||||
$ sudo ldconfig -v | grep -i psync
|
||||
|
||||
This command should display a line similar to the following:
|
||||
|
||||
::
|
||||
|
||||
libPSync.so.0.1.0 -> libPSync.so.0.1.0
|
||||
|
||||
4.2 [Optional] Installing ChronoSync
|
||||
------------------------------------
|
||||
|
||||
By default NLSR no longer builds with ChronoSync support.
|
||||
Since ChronoSync is deprecated, only install it for testing purposes.
|
||||
|
||||
Before installing NLSR, it is necessary to first download and install
|
||||
ChronoSync, which is a synchronization library which allows NLSR routers
|
||||
to synchronize Link State Advertisements (LSAs). More information about
|
||||
ChronoSync may be found at [Chronosync]_. This library may be
|
||||
installed by running the following commands as a regular user and at the
|
||||
directory defined at § `1 <#intro>`__:
|
||||
|
||||
::
|
||||
|
||||
$ git clone --depth 1 https://github.com/named-data/ChronoSync.git
|
||||
$ cd ChronoSync
|
||||
$ ./waf configure
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
|
||||
The following command needs to be used again to configure the libraries:
|
||||
|
||||
::
|
||||
|
||||
$ sudo ldconfig -v | grep -i chronosync
|
||||
|
||||
This command should display a line similar to the following:
|
||||
|
||||
::
|
||||
|
||||
libChronoSync.so.0.5.0 -> libChronoSync.so.0.5.0
|
||||
|
||||
4.3 [Optional] Installing SVS
|
||||
-----------------------------
|
||||
|
||||
NLSR can also use State Vector Sync as the underlying Sync protocol,
|
||||
using the ndn-svs library.
|
||||
|
||||
This library may be installed by running the following commands as a
|
||||
regular user and at the directory defined at § `1 <#intro>`__:
|
||||
|
||||
::
|
||||
|
||||
$ git clone --depth 1 https://github.com/named-data/ndn-svs.git
|
||||
$ cd ndn-svs
|
||||
$ ./waf configure
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
|
||||
The following command needs to be used again to configure the libraries:
|
||||
|
||||
::
|
||||
|
||||
$ sudo ldconfig -v | grep ndn-svs
|
||||
|
||||
This command should display a line similar to the following:
|
||||
|
||||
::
|
||||
|
||||
libndn-svs.so.0.0.1 -> libndn-svs.so.0.0.1
|
||||
|
||||
4.4 Downloading and installing NLSR
|
||||
-----------------------------------
|
||||
|
||||
NLSR is downloaded and installed in a folder called *NLSR* which should
|
||||
be created at the directory defined at § `1 <#intro>`__. The following
|
||||
commands need to be run as a regular user:
|
||||
|
||||
::
|
||||
|
||||
$ git clone --depth 1 https://github.com/named-data/NLSR.git
|
||||
$ cd NLSR
|
||||
$ ./waf configure
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
|
||||
If ChronoSync support is needed for testing, please configure NLSR with:
|
||||
|
||||
::
|
||||
|
||||
$ ./waf configure --with-chronosync
|
||||
|
||||
4.5 Configuring NLSR
|
||||
--------------------
|
||||
|
||||
Create and configure the following directory by running the following
|
||||
commands as root:
|
||||
|
||||
::
|
||||
|
||||
$ mkdir /var/lib/nlsr
|
||||
$ chmod 777 /var/lib/nlsr
|
||||
|
||||
.. _test:
|
||||
|
||||
5. Configuring and Testing NLSR
|
||||
===============================
|
||||
|
||||
To test NLSR, the first step is to configure the keys and certificates
|
||||
that implement a secure communication between the routers. Then it is
|
||||
necessary to verify that the computers in the test network are
|
||||
connected, that NFD is running and the faces between the computers are
|
||||
configured. Finally, the NLSR configuration file has to be edited before
|
||||
running NLSR. The following subsections are provided as a guide to
|
||||
define and configure a simple computer network between two computers:
|
||||
router1 and router2.
|
||||
|
||||
.. _security:
|
||||
|
||||
5.1 Setting up the security
|
||||
---------------------------
|
||||
|
||||
Configuring security in an NDN network requires to generate, exchange
|
||||
and install, keys and certificates between the root, site, operator and
|
||||
router computers that form the network
|
||||
[NLSRsecconf]_, [NLSRdevguide]_, although in practice, it
|
||||
is possible to keep more than one of these entities in a single machine.
|
||||
The following example and *Figure 1* show how to configure security
|
||||
for a single router, called Router X. In this example, the root, site,
|
||||
operator and Router X are in different computers:
|
||||
|
||||
.. figure:: security_comp.png
|
||||
:alt: Security configuration example for Router X.
|
||||
:width: 19cm
|
||||
:align: center
|
||||
|
||||
Fig. 1. Security configuration example for Router X.
|
||||
|
||||
|
||||
#. At the root server, generate the root key:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-key-gen /ndn/ > root.key
|
||||
|
||||
#. Generate the certificate for the root key at the root server:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-dump -i /ndn/ > root.cert
|
||||
|
||||
#. Install the root certificate at the root server:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-install -f root.cert
|
||||
|
||||
#. At the site server, generate the site key:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-key-gen /ndn/edu/uaslp > site.key
|
||||
|
||||
#. Copy the site key to the root server and generate the certificate for
|
||||
the site server:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-gen -s /ndn/ site.key > site.cert
|
||||
|
||||
#. Copy the site certificate to the site server and install it:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-install -f site.cert
|
||||
|
||||
#. At the operator server, generate the operator key:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-key-gen /ndn/edu/uaslp/%C1.Operator/op > op.key
|
||||
|
||||
#. Copy the operator key to the site server and generate the certificate
|
||||
for the operator server:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-gen -s /ndn/edu/uaslp op.key > op.cert
|
||||
|
||||
#. Copy the operator certificate to the operator server and install it:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-install -f op.cert
|
||||
|
||||
#. At the router, generate the router key:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-key-gen /ndn/edu/uaslp/%C1.Router/routerX > routerX.key
|
||||
|
||||
#. Copy the router key to the operator server and generate the
|
||||
certificate for the router:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-gen -s /ndn/edu/uaslp/%C1.Operator/op routerX.key >
|
||||
routerX.cert
|
||||
|
||||
#. Copy the router certificate to the router and install it:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-install -f routerX.cert
|
||||
|
||||
In the previous steps, the *%C1.Router* and *%C1.Operator* labels are
|
||||
NDN keywords and should not be changed. These labels will be also used
|
||||
by the configuration file (§ `5.4 <#configfile>`__)
|
||||
|
||||
The following command may be used to verify that the certificates have
|
||||
been installed in a computer:
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-list
|
||||
|
||||
This guide recommends that one machine functions as the root, site,
|
||||
operator and router1, while a different computer only functions as
|
||||
router2. *Figure 2* shows this
|
||||
configuration. For router1, the twelve steps described before need to be
|
||||
executed except for exchanging files between computers. For the router2,
|
||||
only steps 10 to 12 are needed to generate this router's certificate.
|
||||
|
||||
Additionally, the following command may be used to print a list and a
|
||||
brief description of all the ``ndnsec`` commands:
|
||||
|
||||
::
|
||||
|
||||
$ man ndnsec
|
||||
|
||||
|
||||
.. figure:: netwk1.png
|
||||
:alt: Example network.
|
||||
:width: 19cm
|
||||
:align: center
|
||||
|
||||
Fig. 2. Example network.
|
||||
|
||||
|
||||
5.2 Configuring the network
|
||||
---------------------------
|
||||
|
||||
The first step is to configure the physical network. If two computers
|
||||
are going to get connected using a single Ethernet cable, it is
|
||||
necessary to verify that this cable is a crossover. The other option is
|
||||
to employ a switch between two computers that are then connected using
|
||||
two regular Ethernet cables.
|
||||
|
||||
After the physical network has been assembled, it is necessary to
|
||||
configure the network addresses and cards for all the computers in the
|
||||
network. It is important to remember that computers that are connected
|
||||
to each other should use the same subnetwork address. It is possible to
|
||||
verify the network configuration in a Linux computer by means of the
|
||||
``ip addr`` command.
|
||||
|
||||
Once the physical network and network cards have been configured, it is
|
||||
necessary to verify that the computers can communicate with each other.
|
||||
The simplest way to do this is by using the ``ping`` command:
|
||||
|
||||
::
|
||||
|
||||
$ ping <remote-ip-address>
|
||||
|
||||
5.3 Starting and configuring NFD
|
||||
--------------------------------
|
||||
|
||||
To start and configure NFD it is necessary to open two terminal windows.
|
||||
The first one will be used to start NFD by means of the ``nfd-start``
|
||||
command. This terminal will also display the logs that NFD generates. By
|
||||
default, NFD only generates informational logs (INFO). However, it is
|
||||
possible to obtain different levels of verbosity for these logs. These
|
||||
levels can be set before NFD starts by editing the
|
||||
*/usr/local/etc/ndn/nfd.conf* file. Open this file using a regular text
|
||||
editor, read the information provided about logging and then modify the
|
||||
*default-level* variable at the *log* section according to the
|
||||
instructions provided in the file. Additional information about NFD
|
||||
configuration may be found at [NDNNFDusage]_.
|
||||
|
||||
The second terminal will be used to monitor the NFD status:
|
||||
|
||||
::
|
||||
|
||||
$ nfd-status
|
||||
|
||||
Employ the following command to configure each face that a computer uses
|
||||
to connect to a neighboring computer:
|
||||
|
||||
::
|
||||
|
||||
$ nfdc face create udp4://<remote-ip-address>
|
||||
|
||||
The face id may be displayed by running:
|
||||
|
||||
::
|
||||
|
||||
$ nfdc face list
|
||||
|
||||
The status of the face may be verified by using the following command:
|
||||
|
||||
::
|
||||
|
||||
$ nfdc face show id <face-id>
|
||||
|
||||
After finishing NLSR testing, it is necessary to destroy the face before
|
||||
stopping NFD. This operation is described at § `5.6 <#turn_off>`__. For
|
||||
the two computer network provided as an example (*Figure 2*), it is necessary that both
|
||||
machines run NFD and that each one configures a face that connects to
|
||||
the other machine.
|
||||
|
||||
.. _configfile:
|
||||
|
||||
5.4 Setting up the configuration file
|
||||
-------------------------------------
|
||||
|
||||
Instructions on how to use the configuration file are already provided
|
||||
at the NLSR's Router Configuration page [NLSRrtrconf]_.
|
||||
Read the information in this page to understand NLSR router
|
||||
configuration. The following text describes the instructions that have
|
||||
been modified at the default nlsr.conf file for router1:
|
||||
|
||||
::
|
||||
|
||||
; AT general SECTION:
|
||||
{
|
||||
network /ndn/ ; name of the network
|
||||
site /edu/uaslp ; name of the site
|
||||
router /%C1.Router/router1 ; name of the router: router1
|
||||
}
|
||||
|
||||
;AT neighbors SECTION:
|
||||
neighbors
|
||||
{
|
||||
neighbor
|
||||
{
|
||||
name /ndn/edu/uaslp/%C1.Router/router2 ; Neighbor router: router2
|
||||
face-uri udp://140.220.80.124 ; face to the neighbor
|
||||
link-cost 30 ; cost of the link
|
||||
}
|
||||
}
|
||||
|
||||
; AT advertising SECTION:
|
||||
advertising
|
||||
{
|
||||
prefix /ndn/edu/uaslp/office/bldg1 ; Advertising destinations
|
||||
prefix /ndn/edu/uaslp/office/bldg2 ; for router1
|
||||
}
|
||||
|
||||
; AT security SECTION:
|
||||
security
|
||||
{
|
||||
validator
|
||||
{
|
||||
...
|
||||
trust-anchor
|
||||
{
|
||||
type file
|
||||
file-name "root.cert" ; root certificate file
|
||||
}
|
||||
}
|
||||
|
||||
prefix-update-validator
|
||||
{
|
||||
...
|
||||
trust-anchor
|
||||
{
|
||||
type file
|
||||
file-name "site.cert" ; site certificate file
|
||||
}
|
||||
}
|
||||
|
||||
cert-to-publish "root.cert" ; root certificate file
|
||||
|
||||
cert-to-publish "site.cert" ; site certificate file
|
||||
|
||||
cert-to-publish "op.cert" ; operator certificate file
|
||||
|
||||
cert-to-publish "router1.cert" ; router1 certificate file
|
||||
}
|
||||
|
||||
The following text shows the modified instructions for router2:
|
||||
|
||||
::
|
||||
|
||||
; AT general SECTION:
|
||||
{
|
||||
network /ndn/ ; name of the network
|
||||
site /edu/uaslp ; name of the site
|
||||
router /%C1.Router/router2 ; name of the router: router2
|
||||
}
|
||||
|
||||
;AT neighbors SECTION:
|
||||
neighbors
|
||||
{
|
||||
neighbor
|
||||
{
|
||||
name /ndn/edu/uaslp/%C1.Router/router1 ; Neighbor router: router1
|
||||
face-uri udp://140.220.80.121 ; face to the neighbor
|
||||
link-cost 30 ; cost of the link
|
||||
}
|
||||
}
|
||||
|
||||
; AT advertising SECTION:
|
||||
advertising
|
||||
{
|
||||
prefix /ndn/edu/uaslp/labs/networks ; Advertising destinations
|
||||
prefix /ndn/edu/uaslp/labs/hardware ; for router2
|
||||
}
|
||||
|
||||
; AT security SECTION:
|
||||
security
|
||||
{
|
||||
validator
|
||||
{
|
||||
...
|
||||
trust-anchor
|
||||
{
|
||||
type file
|
||||
file-name "root.cert" ; root certificate file
|
||||
} ; this file needs to be copied to
|
||||
} ; router2
|
||||
|
||||
prefix-update-validator
|
||||
{
|
||||
...
|
||||
trust-anchor
|
||||
{
|
||||
type file
|
||||
file-name "site.cert" ; site certificate file
|
||||
} ; this file needs to be copied to
|
||||
} ; router2
|
||||
|
||||
...
|
||||
cert-to-publish "router2.cert" ; router2 certificate file
|
||||
}
|
||||
|
||||
Notice that files *root.cert* and *site.cert*, which were generated at
|
||||
router1, need to be copied to router2. Also notice that the *%C1.Router*
|
||||
and *%C1.Operator* keywords employed at § `5.1 <#security>`__ are also
|
||||
referenced by these configuration files.
|
||||
|
||||
.. _starting_nlsr:
|
||||
|
||||
5.5 Starting NLSR
|
||||
-----------------
|
||||
|
||||
It is recommended to open a third command terminal and run NLSR in this
|
||||
window. After the NLSR configuration file has been edited and saved as
|
||||
*nlsr.conf*, it is possible to start NLSR by running either of the
|
||||
following two commands:
|
||||
|
||||
::
|
||||
|
||||
$ nlsr
|
||||
$ nlsr -f <configuration-file>
|
||||
|
||||
However, to verify what is NLSR doing, it becomes necessary to employ
|
||||
NLSR's logging facility [NLSRstarting]_. A brief
|
||||
description on how to use NDN's logging facility may be displayed by
|
||||
entering the ``man ndn-log`` command. This guide recommends using one
|
||||
of the following two instructions to start NLSR:
|
||||
|
||||
::
|
||||
|
||||
$ export NDN_LOG=nlsr.*=TRACE && nlsr
|
||||
$ export NDN_LOG=nlsr.*=TRACE && nlsr -f <configuration-file>
|
||||
|
||||
The second terminal window may be used to run ``nfd-status`` again and
|
||||
it should be possible to verify that the status has changed, specially
|
||||
at the FIB and RIB sections of the generated report.
|
||||
|
||||
.. _turn_off:
|
||||
|
||||
5.6 Turning everything off
|
||||
--------------------------
|
||||
|
||||
In order to stop NLSR and NFD, the following sequence of events is
|
||||
recommended:
|
||||
|
||||
#. Stop NLSR by pressing the Ctrl+C keys at the third terminal window.
|
||||
|
||||
#. Destroy the face to the remote computers using either of the
|
||||
following two commands at the second terminal window:
|
||||
|
||||
::
|
||||
|
||||
$ nfdc face destroy <face-id>
|
||||
$ nfdc face destroy udp4://<remote-ip-address>
|
||||
|
||||
#. Stop NFD by entering the following command at the second terminal
|
||||
window:
|
||||
|
||||
::
|
||||
|
||||
$ nfd-stop
|
||||
|
||||
#. The crossover Ethernet cable may be unplugged and the computers'
|
||||
network configuration restored to its original settings.
|
||||
|
||||
5.7 Where to go from here
|
||||
-------------------------
|
||||
|
||||
Users interested in building and configuring larger networks may want to
|
||||
take a look at the NDN Ansible repository
|
||||
[NDNAnsible]_. This repository uses Ansible, which is a
|
||||
configuration management tool, to manage the official NDN testbed
|
||||
deployment [NDNTestbed]_.
|
||||
|
||||
|
||||
.. [NDNmain] *Named Data Networking*, https://named-data.net/, March 2018.
|
||||
|
||||
.. [Kolman2018] M. Kolman. *Anaconda improvements in Fedora 28*, Fedora Magazine, June 2018.
|
||||
|
||||
.. [NDN-cxx] *Getting started with ndn-cxx*, https://docs.named-data.net/ndn-cxx/current/INSTALL.html, April 2018.
|
||||
|
||||
.. [NDNNFD] *Getting started with NFD*, https://docs.named-data.net/NFD/current/INSTALL.html, April 2018.
|
||||
|
||||
.. [NDNNFDusage] *NFD usage*, https://docs.named-data.net/NFD/current/manpages/nfd.html, May 2018.
|
||||
|
||||
.. [Chronosync] Z. Zhu and A. Afanasyev. *Let's ChronoSync: Decentralized dataset state synchronization in Named Data Networking*, in IEEE ICNP, October 2013.
|
||||
|
||||
.. [PSync] M. Zhang, V. Lehman, and L. Wang. *Scalable Name-based Data Synchronization for Named Data Networking*, in IEEE INFOCOM, May 2017.
|
||||
|
||||
.. [NLSRsecconf] *NLSR Security Configuration*, https://docs.named-data.net/NLSR/current/SECURITY-CONFIG.html June 2018.
|
||||
|
||||
.. [NLSRdevguide] V. Lehman, M. Chowdhury, N. Gordon, A. Gawande. *NLSR Developer's Guide*, University of Memphis, November 2017.
|
||||
|
||||
.. [NLSRrtrconf] *NLSR Router Configuration*, https://docs.named-data.net/NLSR/current/ROUTER-CONFIG.html, April 2018.
|
||||
|
||||
.. [NLSRstarting] *Getting Started with NLSR*, https://docs.named-data.net/NLSR/current/GETTING-STARTED.html, May 2018.
|
||||
|
||||
.. [NDNAnsible] *NDN Ansible repository*, https://github.com/WU-ARL/NDN_Ansible, October 2018.
|
||||
|
||||
.. [NDNTestbed] *NDN Testbed*, https://named-data.net/ndn-testbed/, October 2018.
|
||||
+58
-222
@@ -1,256 +1,92 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# NLSR - Named Data Link State Routing Protocol documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Apr 6 19:58:22 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
import datetime
|
||||
import importlib.util
|
||||
import sys
|
||||
import os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
project = 'Named Data Link State Routing Protocol (NLSR)'
|
||||
copyright = 'Copyright © 2014-2023 Named Data Networking Project.'
|
||||
author = 'Named Data Networking Project'
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# The short X.Y version.
|
||||
#version = ''
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.todo',
|
||||
'redmine_issue'
|
||||
]
|
||||
|
||||
def addExtensionIfExists(extension):
|
||||
try:
|
||||
__import__(extension)
|
||||
extensions.append(extension)
|
||||
except ImportError:
|
||||
sys.stderr.write("Extension '%s' in not available. "
|
||||
"Some documentation may not build correctly.\n" % extension)
|
||||
sys.stderr.write("To install, use \n"
|
||||
" sudo pip install %s\n" % extension.replace('.', '-'))
|
||||
|
||||
# sphinxcontrib.googleanalytics is currently not working with the latest version of sphinx
|
||||
# if os.getenv('GOOGLE_ANALYTICS', None):
|
||||
# addExtensionIfExists('sphinxcontrib.googleanalytics')
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'NLSR - Named Data Link State Routing Protocol'
|
||||
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
|
||||
# built documents.
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
#release = ''
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
today_fmt = '%Y-%m-%d'
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
needs_sphinx = '4.0'
|
||||
extensions = [
|
||||
'sphinx.ext.extlinks',
|
||||
'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
def addExtensionIfExists(extension: str):
|
||||
try:
|
||||
if importlib.util.find_spec(extension) is None:
|
||||
raise ModuleNotFoundError(extension)
|
||||
except (ImportError, ValueError):
|
||||
sys.stderr.write(f'WARNING: Extension {extension!r} not found. '
|
||||
'Some documentation may not build correctly.\n')
|
||||
else:
|
||||
extensions.append(extension)
|
||||
|
||||
addExtensionIfExists('sphinxcontrib.doxylink')
|
||||
|
||||
templates_path = ['_templates']
|
||||
exclude_patterns = ['Thumbs.db', '.DS_Store']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
# html_theme = 'default'
|
||||
html_theme = 'named_data_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
html_theme_path = ['./']
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
html_theme_path = ['.']
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
html_copy_source = False
|
||||
html_show_sourcelink = False
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
html_file_suffix = ".html"
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'nlsr-docs'
|
||||
# Disable syntax highlighting of code blocks by default.
|
||||
highlight_language = 'none'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'nlsr-docs.tex', u'NLSR - Named Data Link State Routing Protocol Documentation',
|
||||
u'Named Data Networking Project', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-manual-page-output
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('manpages/nlsr', 'nlsr', u'Named Data Link State Routing Protocol Daemon', None, 1),
|
||||
('manpages/nlsr.conf', 'nlsr.conf', u'Named Data Link State Routing Protocol Daemon config file', None, 5),
|
||||
('manpages/nlsrc', 'nlsrc', u'Command-line utility to interact with and collect statistics from NLSR', None, 1),
|
||||
('manpages/nlsr', 'nlsr', 'Named Data Link State Routing daemon', [], 1),
|
||||
('manpages/nlsr.conf', 'nlsr.conf', 'Named Data Link State Routing daemon configuration file', [], 5),
|
||||
('manpages/nlsrc', 'nlsrc', 'command-line utility to interact with and collect statistics from NLSR', [], 1),
|
||||
]
|
||||
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
# -- Misc options ------------------------------------------------------------
|
||||
|
||||
if os.getenv('GOOGLE_ANALYTICS', None):
|
||||
googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
|
||||
googleanalytics_enabled = True
|
||||
doxylink = {
|
||||
'nlsr': ('NLSR.tag', 'doxygen/'),
|
||||
}
|
||||
|
||||
redmine_project_url = "https://redmine.named-data.net/"
|
||||
extlinks = {
|
||||
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #%s'),
|
||||
}
|
||||
+16
-103
@@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
|
||||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = "NLSR - Named Data Link State Routing Protocol"
|
||||
PROJECT_NAME = "NLSR: Named Data Link State Routing Protocol"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = docs/doxygen
|
||||
# performance problems for the file system.
|
||||
# The default value is: NO.
|
||||
|
||||
CREATE_SUBDIRS = YES
|
||||
CREATE_SUBDIRS = NO
|
||||
|
||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
@@ -220,19 +220,13 @@ TAB_SIZE = 4
|
||||
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
# instance, some of the names that are used will be different. The list of all
|
||||
# members will be omitted, etc.
|
||||
# The default value is: NO.
|
||||
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
|
||||
# Python sources only. Doxygen will then generate output that is more tailored
|
||||
@@ -408,7 +402,7 @@ EXTRACT_PRIVATE = NO
|
||||
# scope will be included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_PACKAGE = YES
|
||||
EXTRACT_PACKAGE = NO
|
||||
|
||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
|
||||
# included in the documentation.
|
||||
@@ -422,7 +416,7 @@ EXTRACT_STATIC = YES
|
||||
# for Java sources.
|
||||
# The default value is: YES.
|
||||
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
|
||||
# This flag is only useful for Objective-C code. When set to YES local methods,
|
||||
# which are defined in the implementation section but not in the interface are
|
||||
@@ -485,7 +479,7 @@ INTERNAL_DOCS = NO
|
||||
# and Mac users are advised to set this option to NO.
|
||||
# The default value is: system dependent.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
CASE_SENSE_NAMES = NO
|
||||
|
||||
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
|
||||
# their full class and namespace scopes in the documentation. If set to YES the
|
||||
@@ -524,7 +518,7 @@ SORT_MEMBER_DOCS = YES
|
||||
# name. If set to NO the members will appear in declaration order.
|
||||
# The default value is: NO.
|
||||
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_BRIEF_DOCS = YES
|
||||
|
||||
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
|
||||
# (brief and detailed) documentation of class members so that constructors and
|
||||
@@ -536,7 +530,7 @@ SORT_BRIEF_DOCS = NO
|
||||
# detailed member documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_MEMBERS_CTORS_1ST = YES
|
||||
|
||||
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
|
||||
# of group names into alphabetical order. If set to NO the group names will
|
||||
@@ -968,13 +962,6 @@ VERBATIM_HEADERS = YES
|
||||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all classes will
|
||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||
@@ -1103,21 +1090,13 @@ HTML_COLORSTYLE_SAT = 0
|
||||
|
||||
HTML_COLORSTYLE_GAMMA = 91
|
||||
|
||||
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
|
||||
# page will contain the date and time when the page was generated. Setting this
|
||||
# to NO can help when comparing the output of multiple runs.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_TIMESTAMP = YES
|
||||
|
||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||
# documentation will contain sections that can be hidden and shown after the
|
||||
# page has loaded.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
HTML_DYNAMIC_SECTIONS = YES
|
||||
|
||||
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
|
||||
# shown in the various tree structured indices initially; the user can expand
|
||||
@@ -1355,7 +1334,7 @@ GENERATE_TREEVIEW = YES
|
||||
# Minimum value: 0, maximum value: 20, default value: 4.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
ENUM_VALUES_PER_LINE = 1
|
||||
|
||||
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
|
||||
# to set the initial width (in pixels) of the frame in which the tree is shown.
|
||||
@@ -1380,17 +1359,6 @@ EXT_LINKS_IN_WINDOW = NO
|
||||
|
||||
FORMULA_FONTSIZE = 10
|
||||
|
||||
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
|
||||
# generated for formulas are transparent PNGs. Transparent PNGs are not
|
||||
# supported properly for IE 6.0, but are supported on all modern browsers.
|
||||
#
|
||||
# Note that when changing this option you need to delete any form_*.png files in
|
||||
# the HTML output directory before the changes have effect.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
FORMULA_TRANSPARENT = YES
|
||||
|
||||
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
||||
# http://www.mathjax.org) which uses client side Javascript for the rendering
|
||||
# instead of using prerendered bitmaps. Use this if you do not have LaTeX
|
||||
@@ -1653,16 +1621,6 @@ LATEX_BATCHMODE = NO
|
||||
|
||||
LATEX_HIDE_INDICES = NO
|
||||
|
||||
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
|
||||
# code with syntax highlighting in the LaTeX output.
|
||||
#
|
||||
# Note that which sources are shown also depends on other settings such as
|
||||
# SOURCE_BROWSER.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_SOURCE_CODE = NO
|
||||
|
||||
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
||||
# bibliography, e.g. plainnat, or ieeetr. See
|
||||
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||
@@ -1916,18 +1874,14 @@ 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 = DOXYGEN=1 \
|
||||
PREDEFINED = DOXYGEN \
|
||||
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
|
||||
VIRTUAL_WITH_TESTS=
|
||||
|
||||
# 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
|
||||
@@ -1993,34 +1947,10 @@ EXTERNAL_GROUPS = YES
|
||||
|
||||
EXTERNAL_PAGES = YES
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of 'which perl').
|
||||
# The default file (with absolute path) is: /usr/bin/perl.
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
|
||||
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
|
||||
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
|
||||
# disabled, but it is recommended to install and use dot, since it yields more
|
||||
# powerful graphs.
|
||||
# The default value is: YES.
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# You can define message sequence charts within doxygen comments using the \msc
|
||||
# command. Doxygen will then run the mscgen tool (see:
|
||||
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
|
||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||
# default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
|
||||
# If set to YES, the inheritance and collaboration graphs will hide inheritance
|
||||
# and usage relations if the target is undocumented or is not a class.
|
||||
# The default value is: YES.
|
||||
@@ -2034,7 +1964,7 @@ HIDE_UNDOC_RELATIONS = NO
|
||||
# set to NO
|
||||
# The default value is: NO.
|
||||
|
||||
HAVE_DOT = YES
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||
@@ -2046,23 +1976,6 @@ HAVE_DOT = YES
|
||||
|
||||
DOT_NUM_THREADS = 0
|
||||
|
||||
# When you want a differently looking font n the dot files that doxygen
|
||||
# generates you can specify the font name using DOT_FONTNAME. You need to make
|
||||
# sure dot is able to find the font, which can be done by putting it in a
|
||||
# standard location or by setting the DOTFONTPATH environment variable or by
|
||||
# setting DOT_FONTPATH to the directory containing the font.
|
||||
# The default value is: Helvetica.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_FONTNAME = Helvetica
|
||||
|
||||
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
|
||||
# dot graphs.
|
||||
# Minimum value: 4, maximum value: 24, default value: 10.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_FONTSIZE = 10
|
||||
|
||||
# By default doxygen will tell dot to use the default font as specified with
|
||||
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
|
||||
# the path where dot can find it using this tag.
|
||||
@@ -2150,7 +2063,7 @@ INCLUDED_BY_GRAPH = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
CALL_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
|
||||
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
|
||||
# dependency graph for every global function or class method.
|
||||
@@ -2161,7 +2074,7 @@ CALL_GRAPH = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
CALLER_GRAPH = YES
|
||||
CALLER_GRAPH = NO
|
||||
|
||||
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
|
||||
# hierarchy of all classes instead of a textual one.
|
||||
@@ -2264,7 +2177,7 @@ DOT_TRANSPARENT = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_MULTI_TARGETS = NO
|
||||
DOT_MULTI_TARGETS = YES
|
||||
|
||||
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
|
||||
# explaining the meaning of the various boxes and arrows in the dot generated
|
||||
|
||||
+52
-45
@@ -1,19 +1,22 @@
|
||||
NLSR - Named Data Link State Routing Protocol
|
||||
=============================================
|
||||
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
|
||||
<https://named-data.net/doc/ndn-tlv/>`_.
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 2
|
||||
|
||||
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
|
||||
limitations, refer to `COPYING.md
|
||||
<https://github.com/named-data/NLSR/blob/master/COPYING.md>`_.
|
||||
GETTING-STARTED
|
||||
INSTALL
|
||||
SECURITY-CONFIG
|
||||
ROUTER-CONFIG
|
||||
beginners-guide
|
||||
manpages
|
||||
release-notes
|
||||
releases
|
||||
|
||||
NLSR is developed by the members of the `NSF-sponsored NDN project team
|
||||
<https://named-data.net/project/participants/>`_. For more details, please refer to
|
||||
`AUTHORS.md <https://github.com/named-data/NLSR/blob/master/AUTHORS.md>`_. Bug reports and
|
||||
feedback are highly appreciated and can be made through the `NLSR Wiki`_.
|
||||
**NLSR** is a routing protocol for Named Data Networking (NDN) that populates the Routing
|
||||
Information Base (RIB) of an NDN router, such as `NFD`_. NLSR continues to evolve alongside
|
||||
the core `NDN protocol`_.
|
||||
|
||||
The main design goal of NLSR is to provide a routing protocol to populate NDN's FIB. NLSR
|
||||
calculates the routing table using link-state or hyperbolic routing and produces multiple
|
||||
@@ -22,57 +25,61 @@ to evolve over time to include neighbor discovery and to become a full fledged
|
||||
inter-domain routing protocol for NDN. The protocol design is presented in full detail in
|
||||
the `NLSR Paper`_.
|
||||
|
||||
NLSR Documentation
|
||||
-------------------
|
||||
NLSR was mainly developed by members of the NSF-sponsored `NDN project team
|
||||
<https://named-data.net/project/participants/>`__. See `AUTHORS.md
|
||||
<https://github.com/named-data/NLSR/blob/master/AUTHORS.md>`__ for details.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 3
|
||||
Bug reports and feedback are highly appreciated and can be made through the `NLSR Redmine`_.
|
||||
|
||||
GETTING-STARTED
|
||||
INSTALL
|
||||
ROUTER-CONFIG
|
||||
SECURITY-CONFIG
|
||||
RELEASE-NOTES
|
||||
releases
|
||||
manpages
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
- :doc:`GETTING-STARTED`
|
||||
- :doc:`INSTALL`
|
||||
- :doc:`ROUTER-CONFIG`
|
||||
- :doc:`SECURITY-CONFIG`
|
||||
- :doc:`RELEASE-NOTES`
|
||||
- :doc:`releases`
|
||||
- :doc:`manpages`
|
||||
- :doc:`GETTING-STARTED`
|
||||
- :doc:`INSTALL`
|
||||
- :doc:`SECURITY-CONFIG`
|
||||
- :doc:`ROUTER-CONFIG`
|
||||
- :doc:`beginners-guide`
|
||||
- :doc:`manpages`
|
||||
- :doc:`release-notes`
|
||||
- :doc:`releases`
|
||||
|
||||
Downloading
|
||||
-----------
|
||||
|
||||
- `GitHub NLSR repository <https://github.com/named-data/NLSR>`_
|
||||
- `Source code git repository <https://github.com/named-data/NLSR>`__
|
||||
|
||||
NLSR mailing list
|
||||
-----------------
|
||||
|
||||
- `NLSR Mailing List`_
|
||||
|
||||
- `NLSR Mailing List Archives`_
|
||||
- `NLSR Mailing List`_
|
||||
- `NLSR Mailing List Archives`_
|
||||
|
||||
`Sign up`_ is needed to post to the list or access the archives.
|
||||
|
||||
Additional information
|
||||
----------------------
|
||||
Additional resources
|
||||
--------------------
|
||||
|
||||
- `NLSR Wiki`_
|
||||
- `NLSR Wiki`_
|
||||
|
||||
- `NLSR Redmine`_
|
||||
Feature requests and bug reports
|
||||
- `NLSR Redmine`_
|
||||
Feature requests and bug reports
|
||||
|
||||
- `NLSR Paper`_
|
||||
Detailed explanation of the NLSR design
|
||||
- `NLSR Paper`_
|
||||
Detailed explanation of NLSR's design
|
||||
|
||||
- `NLSR Developer's Guide`_
|
||||
For NLSR Development
|
||||
- `NLSR Developer's Guide`_
|
||||
For NLSR development
|
||||
|
||||
- `API documentation (doxygen) <doxygen/annotated.html>`__
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
NLSR is free software distributed under the GNU General Public License version 3.
|
||||
See `COPYING.md <https://github.com/named-data/NLSR/blob/master/COPYING.md>`__ for details.
|
||||
|
||||
.. _NDN protocol: https://docs.named-data.net/NDN-packet-spec/current/
|
||||
.. _NFD: https://github.com/named-data/NFD
|
||||
.. _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
|
||||
|
||||
+5
-7
@@ -1,10 +1,8 @@
|
||||
.. _Manpages:
|
||||
|
||||
Manpages
|
||||
========
|
||||
Man pages
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
manpages/nlsr
|
||||
manpages/nlsr.conf
|
||||
manpages/nlsrc
|
||||
:glob:
|
||||
:maxdepth: 1
|
||||
|
||||
manpages/*
|
||||
+29
-9
@@ -6,7 +6,8 @@ Usage
|
||||
|
||||
::
|
||||
|
||||
nlsrc [-h] [-V] COMMAND [<Command Options>]
|
||||
nlsrc [-h | -V]
|
||||
nlsrc [-R <router prefix> [-c <nlsr.conf path> | -k]] COMMAND [<Command Options>]
|
||||
|
||||
|
||||
Description
|
||||
@@ -24,6 +25,17 @@ Options
|
||||
``-V``
|
||||
Show NLSRC version information
|
||||
|
||||
``-R <router prefix>``
|
||||
Target a remote NLSR instance.
|
||||
The default is the local NLSR instance ``/localhost``.
|
||||
|
||||
``-c <nlsr.conf path>``
|
||||
Verify remote status information with the trust schema loaded from ``security.validator`` section of specified nlsr.conf config file.
|
||||
The default is loading from ``/etc/ndn/nlsr.conf``.
|
||||
|
||||
``-k``
|
||||
Insecure: do not verify signature on status information retrieved from remote router.
|
||||
|
||||
``COMMAND``
|
||||
|
||||
``lsdb``
|
||||
@@ -43,6 +55,11 @@ Options
|
||||
``name``
|
||||
The Name prefix to be advertised
|
||||
|
||||
``advertise <name> save``
|
||||
|
||||
``save``
|
||||
Advertise a prefix and also save it to the nlsr.conf file residing in the state-dir for the next start of NLSR that operator may copy and use for the next start of NLSR
|
||||
|
||||
``withdraw``
|
||||
Remove a Name prefix advertised through NLSR
|
||||
|
||||
@@ -51,24 +68,27 @@ Options
|
||||
``name``
|
||||
The Name prefix to be withdrawn
|
||||
|
||||
``withdraw <name> delete``
|
||||
|
||||
``delete``
|
||||
Withdraw a prefix and also delete it from the nlsr.conf file residing in the state-dir
|
||||
|
||||
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'.
|
||||
error message: "Name prefix update error (code: 403)". To remedy this
|
||||
issue, use the command ``ndnsec set-default``. Example::
|
||||
|
||||
Example:
|
||||
|
||||
ndnsec-set-default /ndn/a-site/%C1.Operator/op
|
||||
ndnsec set-default /ndn/a-site/%C1.Operator/op
|
||||
|
||||
Exit Status
|
||||
-----------
|
||||
|
||||
nlsrc exits with one of the following values:
|
||||
::
|
||||
nlsrc exits with one of the following values::
|
||||
|
||||
0 nlsrc exited successfully
|
||||
>0 An error occurred
|
||||
1 generic error
|
||||
2 bad command line
|
||||
@@ -40,9 +40,8 @@
|
||||
|
||||
<h3>{{ _('Developer documentation') }}</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference external" href="https://redmine.named-data.net/projects/nlsr/wiki">NLSR Wiki</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="doxygen/annotated.html">API documentation (doxygen)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="code-style.html">ndn-cxx Code Style and Coding Guidelines</a></li>
|
||||
<li class="toctree-l1"><a class="reference external" href="https://redmine.named-data.net/projects/nlsr/wiki">NLSR Wiki</a></li>
|
||||
</ul>
|
||||
{%- endblock %}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -1,70 +0,0 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
# Based on http://doughellmann.com/2010/05/09/defining-custom-roles-in-sphinx.html
|
||||
|
||||
"""Integration of Sphinx with Redmine.
|
||||
"""
|
||||
|
||||
from docutils import nodes, utils
|
||||
from docutils.parsers.rst.roles import set_classes
|
||||
|
||||
def redmine_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
"""Link to a Redmine issue.
|
||||
|
||||
Returns 2 part tuple containing list of nodes to insert into the
|
||||
document and a list of system messages. Both are allowed to be
|
||||
empty.
|
||||
|
||||
:param name: The role name used in the document.
|
||||
:param rawtext: The entire markup snippet, with role.
|
||||
:param text: The text marked with the role.
|
||||
:param lineno: The line number where rawtext appears in the input.
|
||||
:param inliner: The inliner instance that called us.
|
||||
:param options: Directive options for customization.
|
||||
:param content: The directive content for customization.
|
||||
"""
|
||||
try:
|
||||
issue_num = int(text)
|
||||
if issue_num <= 0:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
msg = inliner.reporter.error(
|
||||
'Redmine issue number must be a number greater than or equal to 1; '
|
||||
'"%s" is invalid.' % text, line=lineno)
|
||||
prb = inliner.problematic(rawtext, rawtext, msg)
|
||||
return [prb], [msg]
|
||||
app = inliner.document.settings.env.app
|
||||
node = make_link_node(rawtext, app, 'issues', str(issue_num), options)
|
||||
return [node], []
|
||||
|
||||
def make_link_node(rawtext, app, type, slug, options):
|
||||
"""Create a link to a Redmine resource.
|
||||
|
||||
:param rawtext: Text being replaced with link node.
|
||||
:param app: Sphinx application context
|
||||
:param type: Link type (issue, changeset, etc.)
|
||||
:param slug: ID of the thing to link to
|
||||
:param options: Options dictionary passed to role func.
|
||||
"""
|
||||
#
|
||||
try:
|
||||
base = app.config.redmine_project_url
|
||||
if not base:
|
||||
raise AttributeError
|
||||
except AttributeError:
|
||||
raise ValueError('redmine_project_url configuration value is not set')
|
||||
#
|
||||
slash = '/' if base[-1] != '/' else ''
|
||||
ref = base + slash + type + '/' + slug + '/'
|
||||
set_classes(options)
|
||||
node = nodes.reference(rawtext, 'Issue #' + utils.unescape(slug), refuri=ref,
|
||||
**options)
|
||||
return node
|
||||
|
||||
def setup(app):
|
||||
"""Install the plugin.
|
||||
|
||||
:param app: Sphinx application context.
|
||||
"""
|
||||
app.add_role('issue', redmine_role)
|
||||
app.add_config_value('redmine_project_url', None, 'env')
|
||||
return
|
||||
@@ -1 +0,0 @@
|
||||
release-notes/release-notes-0.4.3.rst
|
||||
@@ -0,0 +1,4 @@
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
.. include:: release-notes/release-notes-0.7.0.rst
|
||||
@@ -4,19 +4,20 @@ 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
|
||||
<https://named-data.net/doc/NFD/>`_ RIB. NLSR calculates the routing table using
|
||||
<https://github.com/named-data/NFD>`__ 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**:
|
||||
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
|
||||
- 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
|
||||
- Configure maximum number of faces per prefix in NFD's RIB
|
||||
|
||||
- Set up NFD tunnels to neighbors automatically and maintain the tunnels to neighbors
|
||||
|
||||
@@ -27,4 +28,4 @@ prefix in a single authoritative domain.
|
||||
|
||||
- Use a hierarchical trust model for routing within a single administrative domain
|
||||
|
||||
- Keep NFD’s RIB updated on failure and recovery
|
||||
- Keep NFD's RIB updated on failure and recovery
|
||||
@@ -0,0 +1,35 @@
|
||||
NLSR version 0.5.0
|
||||
++++++++++++++++++
|
||||
|
||||
**New Features**
|
||||
|
||||
- Set CanBePrefix to false on Hello Interest (:issue:`4581`)
|
||||
- Optionally write prefixes to a copy of config file via nlsrc advertise (:issue:`4303`)
|
||||
- Use SegmentPublisher utility from PSync to publish LSA data (:issue:`4760`)
|
||||
- Add PSync as a dependency and switch it as default in conf file. (:issue:`4082`)
|
||||
|
||||
**Changes**
|
||||
|
||||
- Decouple classes from Nlsr object for easier unit testing (:issue:`1952`)
|
||||
- Set sequence number file in SequencingManager constructor. (:issue:`4288`)
|
||||
- Read conf file in test prefix update processor instead of static string (:issue:`3960`)
|
||||
- Canonize FaceUri in conf file processor (:issue:`4817`)
|
||||
- Remove redundant function "calculateHypDryRoutingTable" (:issue:`4811`)
|
||||
- In dry run mode, print HR and LS routing table in nlsrc separately (:issue:`4452`)
|
||||
- Fix ASan memory leaks in unit tests (:issue:`4682`)
|
||||
- Systemd service files dependency corrections for Ubuntu 18.04 (:issue:`4594`)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix processing of interest w/ segments for segmented LSA data (:issue:`4784`)
|
||||
- Fib: don't refresh neighbor router's FIB entry (:issue:`4799`)
|
||||
- Disable Interest filter loopback where ever not needed (:issue:`4768`)
|
||||
- Avoid crash when ndn-cxx is compiled with tests by setting canBePrefix (:issue:`4691`)
|
||||
- Make sure NLSR is not using any deprecated API (:issue:`4679`)
|
||||
- Fix crash in equals operator of adjacency-list (:issue:`4705`)
|
||||
- Fix error handling and normalize exit codes
|
||||
|
||||
**Miscellaneous**
|
||||
|
||||
- Improving documentation for NLSR
|
||||
- A beginners' guide to installing and testing on Fedora
|
||||
@@ -0,0 +1,15 @@
|
||||
NLSR version 0.5.1
|
||||
++++++++++++++++++
|
||||
|
||||
**Changes**
|
||||
|
||||
- Set best-route strategy for certificate prefixes (:issue:`4881`)
|
||||
- Use ndn-cxx InMemoryStorage for LsaSegmentStorage (:issue:`4788`)
|
||||
- Switch from ndn::EventId to ndn::scheduler::EventId (:issue:`4883`)
|
||||
- Add FreshnessPeriod where MustBeFresh is used (:issue:`4913`)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix canonization by resetting io service after each neighbor (:issue:`4872`)
|
||||
- Disable network interest in while fetching NLSR certificate (:issue:`4879`)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
NLSR version 0.5.2
|
||||
++++++++++++++++++
|
||||
|
||||
**Breaking Changes**
|
||||
|
||||
The following breaking changes make this release incompatible with the previous version.
|
||||
|
||||
- Use PSync version 0.2.0, sync data compression in full sync is enabled by default (:issue:`5061`, :issue:`4917`)
|
||||
- Use the floating point encoding/decoding functions for hyperbolic coordinates (:issue:`4615`)
|
||||
|
||||
**New Features**
|
||||
|
||||
- Handle zero cost links in Link State Routing (:issue:`4978`)
|
||||
|
||||
**Improvements and Bug Fixes**
|
||||
|
||||
- Remove support for old combined seq no file (:issue:`4143`)
|
||||
- Sync common test infrastructure with ndn-cxx
|
||||
- Refactor Certificate Storage class (:issue:`5075`)
|
||||
- Avoid crashing NLSR if identity cannot be created
|
||||
- Change init order to register sync routes after hello data has been verified (:issue:`5009`)
|
||||
- Fix empty file creation if conf file is same as dynamic (:issue:`5071`)
|
||||
- On face event notification, only proceed if face id was zero or updated (:issue:`4394`)
|
||||
@@ -0,0 +1,12 @@
|
||||
NLSR version 0.6.0
|
||||
------------------
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- *(breaking change)* Major changes in the TLV structure and classes. Reduced codebase size and
|
||||
improved compilation times. LSA de/serialize functions are replaced by wireEncode/Decode.
|
||||
Updated LSA wire formats and TLV assignments. Updated nlsrc to print using the new encoding.
|
||||
(:issue:`4787`, :issue:`5116`)
|
||||
- LSDB refactor: switch to ``boost::multi_index`` to replace 3 LSA lists (:issue:`4127`)
|
||||
- Fix wrong reaction on hello Interest timeout (:issue:`5139`)
|
||||
@@ -0,0 +1,44 @@
|
||||
NLSR version 0.7.0
|
||||
------------------
|
||||
|
||||
Release date: August 18, 2023
|
||||
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Add experimental support for State Vector Sync (SVS) (:issue:`5248`)
|
||||
- ``nlsrc``: Add an option to query the status from remote routers (:issue:`4544`)
|
||||
|
||||
Notable changes and improvements
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- **Deprecate ChronoSync support**: ChronoSync support is now optional and excluded from the
|
||||
default build; it remains available mainly for testing purposes (:issue:`5147`)
|
||||
- Switched to the C++17 standard
|
||||
- The minimum build requirements have been increased as follows:
|
||||
|
||||
- Either GCC >= 7.4.0 or Clang >= 6.0 is required on Linux
|
||||
- On macOS, Xcode 11.3 or later is recommended; older versions may still work but are not
|
||||
officially supported
|
||||
- Boost >= 1.65.1 and ndn-cxx >= 0.8.1 are required on all platforms
|
||||
- Sphinx 4.0 or later is required to build the documentation
|
||||
|
||||
- Refactor LSDB for readability and add signals to notify of modifications (:issue:`4127`)
|
||||
- Retrieve LSA from the face that triggered the notification of LSA changes
|
||||
- Accommodate certificate name in ``KeyLocator`` (:issue:`5195`)
|
||||
- Change ``sig-type`` to ``ecdsa-sha256`` in ``nlsr.conf`` as ndn-cxx now has strict checking for it
|
||||
- Improve error handling and reporting
|
||||
- Stop using the ``gold`` linker on Linux; prefer instead linking with ``lld`` if installed
|
||||
- Update waf build system to version 2.0.24
|
||||
- Various test suite and documentation improvements
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
|
||||
- lsdb: Fix for issues involving incorrect retransmission behavior in segment fetcher
|
||||
- Prevent NLSR from unregistering route during update for router that advertised it initially
|
||||
(:issue:`5179`)
|
||||
- NameLsa: fix LSDB update bug by sorting the NPLs before difference
|
||||
- Fix recurring sync prefix registration on every hello data (:issue:`5157`)
|
||||
- Return the appropriate exit codes when executing ``nlsrc`` advertise/withdraw commands
|
||||
(:issue:`5271`)
|
||||
+56
-22
@@ -1,72 +1,106 @@
|
||||
NLSR Versions
|
||||
+++++++++++++
|
||||
All NLSR Releases
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:reversed:
|
||||
|
||||
release-notes/release-notes-0.4.3
|
||||
release-notes/release-notes-0.4.2
|
||||
release-notes/release-notes-0.4.1
|
||||
release-notes/release-notes-0.4.0
|
||||
release-notes/release-notes-0.3.2
|
||||
release-notes/release-notes-0.3.1
|
||||
release-notes/release-notes-0.3.0
|
||||
release-notes/release-notes-0.2.2
|
||||
release-notes/release-notes-0.2.1
|
||||
release-notes/release-notes-0.2.0
|
||||
release-notes/release-notes-0.1.0
|
||||
release-notes/*
|
||||
|
||||
* **NLSR version 0.7.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.7.0>`, `Documentation <https://docs.named-data.net/NLSR/0.7.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.7.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.7.0.tar.xz>`__ (`checksum <https://named-data.net/downloads/nlsr-0.7.0.tar.xz.sha256>`__)
|
||||
|
||||
* **NLSR version 0.6.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.0>`, `Documentation <https://docs.named-data.net/NLSR/0.6.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.6.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.6.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.6.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.5.2**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.5.2>`, `Documentation <https://docs.named-data.net/NLSR/0.5.2/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.5.2>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.5.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.5.2.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.5.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.5.1>`, `Documentation <https://docs.named-data.net/NLSR/0.5.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.5.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.5.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.5.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.5.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.5.0>`, `Documentation <https://docs.named-data.net/NLSR/0.5.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.5.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.5.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.5.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.4.3**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.3>`, `Documentation <https://docs.named-data.net/NLSR/0.4.3/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.3>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.3.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.4.2**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.2>`, `Documentation <https://docs.named-data.net/NLSR/0.4.2/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.2>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.2.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.4.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`, `Documentation <https://named-data.net/doc/NLSR/0.4.1/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`, `Documentation <https://docs.named-data.net/NLSR/0.4.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/NLSR/releases/tag/NLSR-0.4.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nlsr-0.4.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nlsr-0.4.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **NLSR version 0.4.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`, `Documentation <https://named-data.net/doc/NLSR/0.4.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`, `Documentation <https://docs.named-data.net/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/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-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/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-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/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-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/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-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/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-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/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-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/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-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>`__)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -4,7 +4,7 @@ general
|
||||
{
|
||||
; mandatory configuration command section network, site and router
|
||||
|
||||
network /ndn/ ; name of the network the router belongs to in ndn URI format
|
||||
network /ndn ; name of the network the router belongs to in ndn URI format
|
||||
site /edu/memphis ; name of the site the router belongs to in ndn URI format
|
||||
router /%C1.Router/cs/pollux ; name of the router in ndn URI format
|
||||
|
||||
@@ -19,13 +19,16 @@ general
|
||||
; InterestLifetime (in seconds) for LSA fetching
|
||||
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
|
||||
|
||||
; sync interest lifetime of ChronoSync in milliseconds
|
||||
; select sync protocol: chronosync / psync / svs
|
||||
sync-protocol psync
|
||||
|
||||
; sync interest lifetime of ChronoSync/PSync in milliseconds
|
||||
sync-interest-lifetime 60000 ; default value 60000. Valid values 1000-120,000
|
||||
|
||||
seq-dir /var/lib/nlsr ; path for sequence directory (Absolute path)
|
||||
state-dir /var/lib/nlsr ; path for intermediate state files including sequence directory (Absolute path)
|
||||
}
|
||||
|
||||
; the neighbor's section contains the configuration for router's neighbors and hellos behavior
|
||||
; the neighbors section contains the configuration for router's neighbors and hello protocol behavior
|
||||
|
||||
neighbors
|
||||
{
|
||||
@@ -35,7 +38,7 @@ neighbors
|
||||
hello-retries 3 ; interest retries number in integer. Default value 3
|
||||
; valid values 1-10
|
||||
|
||||
hello-timeout 1 ; interest time out value in integer. Default value 1
|
||||
hello-timeout 1 ; interest time out value in seconds. Default value 1
|
||||
; Valid values 1-15
|
||||
|
||||
hello-interval 60 ; interest sending interval in seconds. Default value 60
|
||||
@@ -44,12 +47,7 @@ neighbors
|
||||
; 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
|
||||
adj-lsa-build-interval 10 ; default value 10. Valid values 5-30.
|
||||
|
||||
face-dataset-fetch-tries 3 ; default is 3. Valid values 1-10. The FaceDataset is
|
||||
; gotten from NFD, and is needed to configure NLSR
|
||||
@@ -146,13 +144,13 @@ security
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>$
|
||||
k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>{1,3}$
|
||||
k-expand \\1
|
||||
h-relation equal
|
||||
p-regex ^([^<nlsr><INFO>]*)<nlsr><INFO><><>$
|
||||
@@ -174,13 +172,13 @@ security
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>$
|
||||
k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>{1,3}$
|
||||
k-expand \\1
|
||||
h-relation equal
|
||||
; the last four components in the prefix should be <lsaType><seqNo><version><segmentNo>
|
||||
@@ -191,6 +189,34 @@ security
|
||||
}
|
||||
}
|
||||
|
||||
rule
|
||||
{
|
||||
id "NLSR datasets"
|
||||
for data
|
||||
filter
|
||||
{
|
||||
type name
|
||||
regex ^[^<nlsr>]*<nlsr>[<lsdb><routing-table>]
|
||||
}
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^([^<KEY>]*)<KEY><>{1,3}$ ; router key or certificate
|
||||
k-expand \\1
|
||||
h-relation equal
|
||||
p-regex ^([^<nlsr>]*)<nlsr>[<lsdb><routing-table>]
|
||||
p-expand \\1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rule
|
||||
{
|
||||
id "NLSR Hierarchy Exception Rule"
|
||||
@@ -203,13 +229,13 @@ security
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
|
||||
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>{1,3}$
|
||||
k-expand \\1
|
||||
h-relation equal
|
||||
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><><><>$
|
||||
@@ -231,7 +257,7 @@ security
|
||||
checker
|
||||
{
|
||||
type hierarchical
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,11 +284,11 @@ security
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
|
||||
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>{1,3}$
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,7 +305,7 @@ security
|
||||
checker
|
||||
{
|
||||
type hierarchical
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+44
-99
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -20,9 +20,6 @@
|
||||
**/
|
||||
|
||||
#include "adjacency-list.hpp"
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "common.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -31,41 +28,24 @@ namespace nlsr {
|
||||
|
||||
INIT_LOGGER(AdjacencyList);
|
||||
|
||||
AdjacencyList::AdjacencyList()
|
||||
bool
|
||||
AdjacencyList::insert(const Adjacent& adjacent)
|
||||
{
|
||||
}
|
||||
|
||||
AdjacencyList::~AdjacencyList()
|
||||
{
|
||||
}
|
||||
|
||||
int32_t
|
||||
AdjacencyList::insert(Adjacent& adjacent)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(adjacent.getName());
|
||||
auto it = find(adjacent.getName());
|
||||
if (it != m_adjList.end()) {
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
m_adjList.push_back(adjacent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AdjacencyList::addAdjacents(AdjacencyList& adl)
|
||||
{
|
||||
for (std::list<Adjacent>::iterator it = adl.getAdjList().begin();
|
||||
it != adl.getAdjList().end(); ++it) {
|
||||
insert((*it));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Adjacent
|
||||
AdjacencyList::getAdjacent(const ndn::Name& adjName)
|
||||
{
|
||||
Adjacent adj(adjName);
|
||||
std::list<Adjacent>::iterator it = find(adjName);
|
||||
auto it = find(adjName);
|
||||
if (it != m_adjList.end()) {
|
||||
return (*it);
|
||||
return *it;
|
||||
}
|
||||
return adj;
|
||||
}
|
||||
@@ -73,62 +53,54 @@ AdjacencyList::getAdjacent(const ndn::Name& adjName)
|
||||
bool
|
||||
AdjacencyList::operator==(const AdjacencyList& adl) const
|
||||
{
|
||||
if (m_adjList.size() != adl.getAdjList().size()) {
|
||||
auto theirList = adl.getAdjList();
|
||||
if (m_adjList.size() != theirList.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<Adjacent> ourList(m_adjList.cbegin(), m_adjList.cend());
|
||||
std::set<Adjacent> theirList(adl.getAdjList().cbegin(), adl.getAdjList().cend());
|
||||
|
||||
return ourList == theirList;
|
||||
std::set<Adjacent> ourSet(m_adjList.cbegin(), m_adjList.cend());
|
||||
std::set<Adjacent> theirSet(theirList.cbegin(), theirList.cend());
|
||||
return ourSet == theirSet;
|
||||
}
|
||||
|
||||
bool
|
||||
AdjacencyList::isNeighbor(const ndn::Name& adjName) const
|
||||
{
|
||||
std::list<Adjacent>::const_iterator it = find(adjName);
|
||||
if (it == m_adjList.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return find(adjName) != m_adjList.end();
|
||||
}
|
||||
|
||||
void
|
||||
AdjacencyList::incrementTimedOutInterestCount(const ndn::Name& neighbor)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(neighbor);
|
||||
if (it == m_adjList.end()) {
|
||||
return ;
|
||||
auto it = find(neighbor);
|
||||
if (it != m_adjList.end()) {
|
||||
it->setInterestTimedOutNo(it->getInterestTimedOutNo() + 1);
|
||||
}
|
||||
(*it).setInterestTimedOutNo((*it).getInterestTimedOutNo() + 1);
|
||||
}
|
||||
|
||||
void
|
||||
AdjacencyList::setTimedOutInterestCount(const ndn::Name& neighbor,
|
||||
uint32_t count)
|
||||
AdjacencyList::setTimedOutInterestCount(const ndn::Name& neighbor, uint32_t count)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(neighbor);
|
||||
auto it = find(neighbor);
|
||||
if (it != m_adjList.end()) {
|
||||
(*it).setInterestTimedOutNo(count);
|
||||
it->setInterestTimedOutNo(count);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
AdjacencyList::getTimedOutInterestCount(const ndn::Name& neighbor) const
|
||||
{
|
||||
std::list<Adjacent>::const_iterator it = find(neighbor);
|
||||
auto it = find(neighbor);
|
||||
if (it == m_adjList.end()) {
|
||||
return -1;
|
||||
}
|
||||
return (*it).getInterestTimedOutNo();
|
||||
return it->getInterestTimedOutNo();
|
||||
}
|
||||
|
||||
Adjacent::Status
|
||||
AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor) const
|
||||
{
|
||||
std::list<Adjacent>::const_iterator it = find(neighbor);
|
||||
|
||||
auto it = find(neighbor);
|
||||
if (it == m_adjList.end()) {
|
||||
return Adjacent::STATUS_UNKNOWN;
|
||||
}
|
||||
@@ -140,7 +112,7 @@ AdjacencyList::getStatusOfNeighbor(const ndn::Name& neighbor) const
|
||||
void
|
||||
AdjacencyList::setStatusOfNeighbor(const ndn::Name& neighbor, Adjacent::Status status)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = find(neighbor);
|
||||
auto it = find(neighbor);
|
||||
if (it != m_adjList.end()) {
|
||||
it->setStatus(status);
|
||||
}
|
||||
@@ -163,8 +135,7 @@ AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
|
||||
{
|
||||
uint32_t nTimedOutNeighbors = 0;
|
||||
|
||||
for (const Adjacent& adjacency : m_adjList) {
|
||||
|
||||
for (const auto& adjacency : m_adjList) {
|
||||
if (adjacency.getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
return true;
|
||||
}
|
||||
@@ -173,21 +144,15 @@ AdjacencyList::isAdjLsaBuildable(const uint32_t interestRetryNo) const
|
||||
}
|
||||
}
|
||||
|
||||
if (nTimedOutNeighbors == m_adjList.size()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return nTimedOutNeighbors == m_adjList.size();
|
||||
}
|
||||
|
||||
int32_t
|
||||
AdjacencyList::getNumOfActiveNeighbor() const
|
||||
{
|
||||
int32_t actNbrCount = 0;
|
||||
for (std::list<Adjacent>::const_iterator it = m_adjList.begin(); it != m_adjList.end(); it++) {
|
||||
|
||||
if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
for (const auto& adjacent: m_adjList) {
|
||||
if (adjacent.getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
actNbrCount++;
|
||||
}
|
||||
}
|
||||
@@ -197,72 +162,52 @@ AdjacencyList::getNumOfActiveNeighbor() const
|
||||
std::list<Adjacent>::iterator
|
||||
AdjacencyList::find(const ndn::Name& adjName)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
return it;
|
||||
return std::find_if(m_adjList.begin(), m_adjList.end(),
|
||||
std::bind(&Adjacent::compare, _1, std::cref(adjName)));
|
||||
}
|
||||
|
||||
std::list<Adjacent>::const_iterator
|
||||
AdjacencyList::find(const ndn::Name& adjName) const
|
||||
{
|
||||
std::list<Adjacent>::const_iterator it = std::find_if(m_adjList.cbegin(),
|
||||
m_adjList.cend(),
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
return it;
|
||||
return std::find_if(m_adjList.cbegin(), m_adjList.cend(),
|
||||
std::bind(&Adjacent::compare, _1, std::cref(adjName)));
|
||||
}
|
||||
|
||||
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(const ndn::Name& adjName)
|
||||
{
|
||||
return std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compare,
|
||||
_1, std::cref(adjName)));
|
||||
return std::find_if(m_adjList.begin(), m_adjList.end(),
|
||||
std::bind(&Adjacent::compare, _1, std::cref(adjName)));
|
||||
}
|
||||
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(uint64_t faceId)
|
||||
{
|
||||
return std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceId,
|
||||
_1, faceId));
|
||||
return std::find_if(m_adjList.begin(), m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceId, _1, faceId));
|
||||
}
|
||||
|
||||
AdjacencyList::iterator
|
||||
AdjacencyList::findAdjacent(const ndn::FaceUri& faceUri)
|
||||
{
|
||||
return std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceUri,
|
||||
_1, faceUri));
|
||||
return std::find_if(m_adjList.begin(), m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceUri, _1, faceUri));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
AdjacencyList::getFaceId(const ndn::FaceUri& faceUri)
|
||||
{
|
||||
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
|
||||
m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceUri,
|
||||
_1, faceUri));
|
||||
if (it != m_adjList.end()) {
|
||||
return it->getFaceId();
|
||||
}
|
||||
|
||||
return 0;
|
||||
auto it = std::find_if(m_adjList.begin(), m_adjList.end(),
|
||||
std::bind(&Adjacent::compareFaceUri, _1, faceUri));
|
||||
return it != m_adjList.end() ? it->getFaceId() : 0;
|
||||
}
|
||||
|
||||
void
|
||||
AdjacencyList::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG("-------Adjacency List--------");
|
||||
for (std::list<Adjacent>::iterator it = m_adjList.begin();
|
||||
it != m_adjList.end(); it++) {
|
||||
(*it).writeLog();
|
||||
for (const auto& adjacent : m_adjList) {
|
||||
NLSR_LOG_DEBUG(adjacent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-46
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -26,31 +26,17 @@
|
||||
#include "common.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class AdjacencyList
|
||||
{
|
||||
public:
|
||||
typedef std::list<Adjacent>::const_iterator const_iterator;
|
||||
typedef std::list<Adjacent>::iterator iterator;
|
||||
using const_iterator = std::list<Adjacent>::const_iterator;
|
||||
using iterator = std::list<Adjacent>::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);
|
||||
bool
|
||||
insert(const Adjacent& adjacent);
|
||||
|
||||
std::list<Adjacent>&
|
||||
getAdjList();
|
||||
@@ -76,16 +62,6 @@ 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.
|
||||
@@ -122,9 +98,7 @@ public:
|
||||
void
|
||||
reset()
|
||||
{
|
||||
if (m_adjList.size() > 0) {
|
||||
m_adjList.clear();
|
||||
}
|
||||
m_adjList.clear();
|
||||
}
|
||||
|
||||
AdjacencyList::iterator
|
||||
@@ -136,19 +110,6 @@ public:
|
||||
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 ndn::FaceUri& faceUri);
|
||||
|
||||
|
||||
+132
-43
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,53 +16,145 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include "tlv-nlsr.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(Adjacent);
|
||||
|
||||
const float Adjacent::DEFAULT_LINK_COST = 10.0;
|
||||
|
||||
Adjacent::Adjacent()
|
||||
: m_name()
|
||||
, m_faceUri()
|
||||
, m_linkCost(DEFAULT_LINK_COST)
|
||||
, m_status(STATUS_INACTIVE)
|
||||
, m_interestTimedOutNo(0)
|
||||
, m_faceId(0)
|
||||
: m_name()
|
||||
, m_faceUri()
|
||||
, m_linkCost(DEFAULT_LINK_COST)
|
||||
, m_status(STATUS_INACTIVE)
|
||||
, m_interestTimedOutNo(0)
|
||||
, m_faceId(0)
|
||||
{
|
||||
}
|
||||
|
||||
Adjacent::Adjacent(const ndn::Block& block)
|
||||
{
|
||||
wireDecode(block);
|
||||
}
|
||||
|
||||
Adjacent::Adjacent(const ndn::Name& an)
|
||||
: m_name(an)
|
||||
, m_faceUri()
|
||||
, m_linkCost(DEFAULT_LINK_COST)
|
||||
, m_status(STATUS_INACTIVE)
|
||||
, m_interestTimedOutNo(0)
|
||||
, m_faceId(0)
|
||||
{
|
||||
: m_name(an)
|
||||
, m_faceUri()
|
||||
, m_linkCost(DEFAULT_LINK_COST)
|
||||
, m_status(STATUS_INACTIVE)
|
||||
, m_interestTimedOutNo(0)
|
||||
, m_faceId(0)
|
||||
{
|
||||
}
|
||||
|
||||
Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
|
||||
Status s, uint32_t iton, uint64_t faceId)
|
||||
: m_name(an)
|
||||
, m_faceUri(faceUri)
|
||||
, m_status(s)
|
||||
, m_interestTimedOutNo(iton)
|
||||
, m_faceId(faceId)
|
||||
{
|
||||
this->setLinkCost(lc);
|
||||
}
|
||||
|
||||
void
|
||||
Adjacent::setLinkCost(double lc)
|
||||
{
|
||||
// NON_ADJACENT_COST is a negative value and is used for nodes that aren't direct neighbors.
|
||||
// But for direct/active neighbors, the cost cannot be negative.
|
||||
if (lc < 0 && lc != NON_ADJACENT_COST) {
|
||||
NLSR_LOG_ERROR(" Neighbor's link-cost cannot be negative");
|
||||
NDN_THROW(ndn::tlv::Error("Neighbor's link-cost cannot be negative"));
|
||||
}
|
||||
|
||||
Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
|
||||
Status s, uint32_t iton, uint64_t faceId)
|
||||
: m_name(an)
|
||||
, m_faceUri(faceUri)
|
||||
, m_linkCost(lc)
|
||||
, m_status(s)
|
||||
, m_interestTimedOutNo(iton)
|
||||
, m_faceId(faceId)
|
||||
{
|
||||
m_linkCost = lc;
|
||||
}
|
||||
|
||||
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
Adjacent::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
totalLength += prependDoubleBlock(encoder, nlsr::tlv::Cost, m_linkCost);
|
||||
|
||||
totalLength += prependStringBlock(encoder, nlsr::tlv::Uri, m_faceUri.toString());
|
||||
|
||||
totalLength += m_name.wireEncode(encoder);
|
||||
|
||||
totalLength += encoder.prependVarNumber(totalLength);
|
||||
totalLength += encoder.prependVarNumber(nlsr::tlv::Adjacency);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
const ndn::Block&
|
||||
Adjacent::wireEncode() const
|
||||
{
|
||||
if (m_wire.hasWire()) {
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
ndn::EncodingEstimator estimator;
|
||||
size_t estimatedSize = wireEncode(estimator);
|
||||
|
||||
ndn::EncodingBuffer buffer(estimatedSize, 0);
|
||||
wireEncode(buffer);
|
||||
|
||||
m_wire = buffer.block();
|
||||
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
void
|
||||
Adjacent::wireDecode(const ndn::Block& wire)
|
||||
{
|
||||
m_name.clear();
|
||||
m_faceUri = ndn::FaceUri();
|
||||
m_linkCost = 0;
|
||||
|
||||
m_wire = wire;
|
||||
|
||||
if (m_wire.type() != nlsr::tlv::Adjacency) {
|
||||
NDN_THROW(Error("Adjacency", m_wire.type()));
|
||||
}
|
||||
|
||||
m_wire.parse();
|
||||
|
||||
auto val = m_wire.elements_begin();
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
|
||||
m_name.wireDecode(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Name field"));
|
||||
}
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Uri) {
|
||||
m_faceUri = ndn::FaceUri(readString(*val));
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Uri field"));
|
||||
}
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Cost) {
|
||||
m_linkCost = ndn::encoding::readDouble(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Cost field"));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Adjacent::operator==(const Adjacent& adjacent) const
|
||||
{
|
||||
@@ -75,23 +167,20 @@ Adjacent::operator==(const Adjacent& adjacent) const
|
||||
bool
|
||||
Adjacent::operator<(const Adjacent& adjacent) const
|
||||
{
|
||||
return (m_name < adjacent.getName()) ||
|
||||
(m_linkCost < adjacent.getLinkCost());
|
||||
auto linkCost = adjacent.getLinkCost();
|
||||
return std::tie(m_name, m_linkCost) <
|
||||
std::tie(adjacent.getName(), linkCost);
|
||||
}
|
||||
|
||||
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;
|
||||
os << "Adjacent: " << adjacent.m_name
|
||||
<< "\n\t\tConnecting FaceUri: " << adjacent.m_faceUri
|
||||
<< "\n\t\tLink cost: " << adjacent.m_linkCost
|
||||
<< "\n\t\tStatus: " << adjacent.m_status
|
||||
<< "\n\t\tInterest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
void
|
||||
Adjacent::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+52
-25
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
/*
|
||||
* Copyright (c) 2014-2022, 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,29 +17,41 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
|
||||
#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
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/net/face-uri.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.
|
||||
*
|
||||
* Data abstraction for Adjacent
|
||||
* Adjacent := ADJACENCY-TYPE TLV-LENGTH
|
||||
* Name
|
||||
* FaceUri
|
||||
* LinkCost
|
||||
* AdjacencyStatus
|
||||
* AdjacencyInterestTimedOutNo
|
||||
*/
|
||||
class Adjacent
|
||||
{
|
||||
|
||||
public:
|
||||
class Error : public ndn::tlv::Error
|
||||
{
|
||||
public:
|
||||
using ndn::tlv::Error::Error;
|
||||
};
|
||||
|
||||
enum Status
|
||||
{
|
||||
STATUS_UNKNOWN = -1,
|
||||
@@ -48,6 +61,8 @@ public:
|
||||
|
||||
Adjacent();
|
||||
|
||||
Adjacent(const ndn::Block& block);
|
||||
|
||||
Adjacent(const ndn::Name& an);
|
||||
|
||||
Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
|
||||
@@ -60,9 +75,10 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
setName(const ndn::Name& an)
|
||||
setName(const ndn::Name& name)
|
||||
{
|
||||
m_name = an;
|
||||
m_wire.reset();
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
const ndn::FaceUri&
|
||||
@@ -74,21 +90,18 @@ public:
|
||||
void
|
||||
setFaceUri(const ndn::FaceUri& faceUri)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_faceUri = faceUri;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
double
|
||||
getLinkCost() const
|
||||
{
|
||||
uint64_t linkCost = static_cast<uint64_t>(ceil(m_linkCost));
|
||||
return linkCost;
|
||||
return ceil(m_linkCost);
|
||||
}
|
||||
|
||||
void
|
||||
setLinkCost(double lc)
|
||||
{
|
||||
m_linkCost = lc;
|
||||
}
|
||||
setLinkCost(double lc);
|
||||
|
||||
Status
|
||||
getStatus() const
|
||||
@@ -99,6 +112,7 @@ public:
|
||||
void
|
||||
setStatus(Status s)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_status = s;
|
||||
}
|
||||
|
||||
@@ -111,6 +125,7 @@ public:
|
||||
void
|
||||
setInterestTimedOutNo(uint32_t iton)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_interestTimedOutNo = iton;
|
||||
}
|
||||
|
||||
@@ -157,11 +172,19 @@ public:
|
||||
return m_faceUri == faceUri;
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(ndn::EncodingImpl<TAG>& block) const;
|
||||
|
||||
const ndn::Block&
|
||||
wireEncode() const;
|
||||
|
||||
void
|
||||
writeLog();
|
||||
wireDecode(const ndn::Block& wire);
|
||||
|
||||
public:
|
||||
static const float DEFAULT_LINK_COST;
|
||||
static constexpr double DEFAULT_LINK_COST = 10.0;
|
||||
static constexpr double NON_ADJACENT_COST = -12345.0;
|
||||
|
||||
private:
|
||||
/*! m_name The NLSR-configured router name of the neighbor */
|
||||
@@ -171,17 +194,21 @@ private:
|
||||
/*! 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;
|
||||
Status m_status = STATUS_UNKNOWN;
|
||||
/*! m_interestTimedOutNo How many failed Hello interests we have sent since the last reply */
|
||||
uint32_t m_interestTimedOutNo;
|
||||
uint32_t m_interestTimedOutNo = 0;
|
||||
/*! m_faceId The NFD-assigned ID for the neighbor, used to
|
||||
* determine whether a Face is available */
|
||||
uint64_t m_faceId;
|
||||
|
||||
mutable ndn::Block m_wire;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Adjacent& adjacent);
|
||||
};
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Adjacent& adjacent);
|
||||
|
||||
|
||||
+18
-20
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,44 +16,42 @@
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
**/
|
||||
|
||||
/*! \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 <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <ndn-cxx/name.hpp>
|
||||
#include <ndn-cxx/util/exception.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
using std::bind;
|
||||
using std::make_shared;
|
||||
using std::shared_ptr;
|
||||
using std::function;
|
||||
using namespace ndn::time_literals;
|
||||
|
||||
const ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION = ndn::time::seconds(4);
|
||||
constexpr ndn::time::seconds TIME_ALLOWED_FOR_CANONIZATION = 4_s;
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_iterator
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
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>
|
||||
struct is_iterator<T, std::enable_if_t<!std::is_same_v<
|
||||
typename std::iterator_traits<T>::value_type, void>>>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,109 +17,69 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "sync-logic-handler.hpp"
|
||||
#include "common.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "hello-protocol.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(SyncLogicHandler);
|
||||
|
||||
const std::string NLSR_COMPONENT = "nlsr";
|
||||
const std::string LSA_COMPONENT = "LSA";
|
||||
const std::string LSA_COMPONENT{"LSA"};
|
||||
|
||||
template<class T>
|
||||
class NullDeleter
|
||||
{
|
||||
public:
|
||||
void
|
||||
operator()(T*)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
SyncLogicHandler::SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew,
|
||||
const ConfParameter& conf)
|
||||
: onNewLsa(ndn::make_unique<OnNewLsa>())
|
||||
, m_syncFace(face)
|
||||
, m_isLsaNew(isLsaNew)
|
||||
SyncLogicHandler::SyncLogicHandler(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
IsLsaNew isLsaNew, const ConfParameter& conf)
|
||||
: m_isLsaNew(std::move(isLsaNew))
|
||||
, m_confParam(conf)
|
||||
, m_nameLsaUserPrefix(ndn::Name(m_confParam.getSyncUserPrefix()).append(boost::lexical_cast<std::string>(Lsa::Type::NAME)))
|
||||
, m_syncLogic(face, keyChain, m_confParam.getSyncProtocol(), m_confParam.getSyncPrefix(),
|
||||
m_nameLsaUserPrefix, m_confParam.getSyncInterestLifetime(),
|
||||
std::bind(&SyncLogicHandler::processUpdate, this, _1, _2, _3))
|
||||
{
|
||||
m_adjLsaUserPrefix = ndn::Name(m_confParam.getSyncUserPrefix())
|
||||
.append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
|
||||
m_coorLsaUserPrefix = ndn::Name(m_confParam.getSyncUserPrefix())
|
||||
.append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
|
||||
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_ON) {
|
||||
m_syncLogic.addUserNode(m_adjLsaUserPrefix);
|
||||
}
|
||||
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
|
||||
m_syncLogic.addUserNode(m_coorLsaUserPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::createSyncSocket(const ndn::Name& syncPrefix, const ndn::time::milliseconds& syncInterestLifetime)
|
||||
SyncLogicHandler::processUpdate(const ndn::Name& updateName, uint64_t highSeq, uint64_t incomingFaceId)
|
||||
{
|
||||
if (m_syncSocket != nullptr) {
|
||||
NLSR_LOG_WARN("Trying to create Sync socket, but Sync socket already exists");
|
||||
NLSR_LOG_DEBUG("Update Name: " << updateName << " Seq no: " << highSeq);
|
||||
|
||||
int32_t nlsrPosition = util::getNameComponentPosition(updateName, HelloProtocol::NLSR_COMPONENT);
|
||||
int32_t lsaPosition = util::getNameComponentPosition(updateName, LSA_COMPONENT);
|
||||
|
||||
if (nlsrPosition < 0 || lsaPosition < 0) {
|
||||
NLSR_LOG_WARN("Received malformed sync update");
|
||||
return;
|
||||
}
|
||||
|
||||
m_syncPrefix = syncPrefix;
|
||||
ndn::Name networkName = updateName.getSubName(1, nlsrPosition - 1);
|
||||
ndn::Name routerName = updateName.getSubName(lsaPosition + 1).getPrefix(-1);
|
||||
ndn::Name originRouter = networkName;
|
||||
originRouter.append(routerName);
|
||||
|
||||
// Build LSA sync update prefix
|
||||
buildUpdatePrefix();
|
||||
|
||||
NLSR_LOG_DEBUG("Creating Sync socket. Sync Prefix: " << m_syncPrefix);
|
||||
|
||||
// The face's lifetime is managed in main.cpp; SyncSocket should not manage the memory
|
||||
// of the object
|
||||
std::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
|
||||
|
||||
const auto fixedSession = ndn::name::Component::fromNumber(0);
|
||||
m_syncSocket = std::make_shared<chronosync::Socket>(m_syncPrefix, m_nameLsaUserPrefix, *facePtr,
|
||||
std::bind(&SyncLogicHandler::onChronoSyncUpdate, this, _1),
|
||||
chronosync::Socket::DEFAULT_NAME, chronosync::Socket::DEFAULT_VALIDATOR,
|
||||
syncInterestLifetime, fixedSession);
|
||||
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
|
||||
m_syncSocket->addSyncNode(m_adjLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
}
|
||||
else if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_syncSocket->addSyncNode(m_coorLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
}
|
||||
else {
|
||||
m_syncSocket->addSyncNode(m_adjLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
m_syncSocket->addSyncNode(m_coorLsaUserPrefix, chronosync::Socket::DEFAULT_NAME, fixedSession);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Received ChronoSync update event");
|
||||
|
||||
for (size_t i = 0; i < v.size(); i++){
|
||||
ndn::Name updateName = v[i].session.getPrefix(-1);
|
||||
|
||||
NLSR_LOG_DEBUG("Update Name: " << updateName << " Seq no: " << v[i].high);
|
||||
|
||||
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);
|
||||
}
|
||||
processUpdateFromSync(originRouter, updateName, highSeq, incomingFaceId);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
const ndn::Name& updateName, const uint64_t& seqNo)
|
||||
const ndn::Name& updateName, uint64_t seqNo,
|
||||
uint64_t incomingFaceId)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Origin Router of update: " << originRouter);
|
||||
|
||||
@@ -129,24 +89,25 @@ SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
Lsa::Type lsaType;
|
||||
std::istringstream(updateName.get(updateName.size()-1).toUri()) >> lsaType;
|
||||
|
||||
NLSR_LOG_DEBUG("Received sync update with higher " << lsaType
|
||||
<< " sequence number than entry in LSDB");
|
||||
NLSR_LOG_DEBUG("Received sync update with higher " << lsaType <<
|
||||
" sequence number than entry in LSDB");
|
||||
|
||||
if (m_isLsaNew(originRouter, lsaType, seqNo)) {
|
||||
if (m_isLsaNew(originRouter, lsaType, seqNo, incomingFaceId)) {
|
||||
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.");
|
||||
NLSR_LOG_ERROR("Got an update for adjacency LSA when hyperbolic routing " <<
|
||||
"is enabled. Not going to fetch.");
|
||||
return;
|
||||
}
|
||||
|
||||
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.");
|
||||
NLSR_LOG_ERROR("Got an update for coordinate LSA when link-state " <<
|
||||
"is enabled. Not going to fetch.");
|
||||
return;
|
||||
}
|
||||
(*onNewLsa)(updateName, seqNo);
|
||||
|
||||
onNewLsa(updateName, seqNo, originRouter, incomingFaceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,54 +115,19 @@ SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
void
|
||||
SyncLogicHandler::publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo)
|
||||
{
|
||||
if (m_syncSocket == nullptr) {
|
||||
NLSR_LOG_FATAL("Cannot publish routing update; SyncSocket does not exist");
|
||||
|
||||
BOOST_THROW_EXCEPTION(SyncLogicHandler::Error("Cannot publish routing update; SyncSocket does not exist"));
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case Lsa::Type::ADJACENCY:
|
||||
publishSyncUpdate(m_adjLsaUserPrefix, seqNo);
|
||||
m_syncLogic.publishUpdate(m_adjLsaUserPrefix, seqNo);
|
||||
break;
|
||||
case Lsa::Type::COORDINATE:
|
||||
publishSyncUpdate(m_coorLsaUserPrefix, seqNo);
|
||||
m_syncLogic.publishUpdate(m_coorLsaUserPrefix, seqNo);
|
||||
break;
|
||||
case Lsa::Type::NAME:
|
||||
publishSyncUpdate(m_nameLsaUserPrefix, seqNo);
|
||||
m_syncLogic.publishUpdate(m_nameLsaUserPrefix, seqNo);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::buildUpdatePrefix()
|
||||
{
|
||||
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)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Publishing Sync Update. Prefix: " << updatePrefix << " Seq No: " << seqNo);
|
||||
|
||||
ndn::Name updateName(updatePrefix);
|
||||
std::string data("NoData");
|
||||
|
||||
m_syncSocket->publishData(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(),
|
||||
ndn::time::milliseconds(1000), seqNo, updateName);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,63 +17,40 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_SYNC_LOGIC_HANDLER_HPP
|
||||
#define NLSR_SYNC_LOGIC_HANDLER_HPP
|
||||
|
||||
#include "conf-parameter.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
#include "lsa/lsa.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;
|
||||
#include "sync-protocol-adapter.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class ConfParameter;
|
||||
|
||||
/*! \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:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew, const ConfParameter& conf);
|
||||
using IsLsaNew =
|
||||
std::function<bool(const ndn::Name&, const Lsa::Type& lsaType, const uint64_t&, uint64_t/*inFace*/)>;
|
||||
|
||||
/*! \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
|
||||
onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v);
|
||||
SyncLogicHandler(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
IsLsaNew isLsaNew, const ConfParameter& conf);
|
||||
|
||||
/*! \brief Instruct ChronoSync to publish an update.
|
||||
*
|
||||
@@ -87,25 +64,16 @@ public:
|
||||
void
|
||||
publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo);
|
||||
|
||||
/*! \brief Create and configure a socket to enable ChronoSync for this NLSR.
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Callback from Sync protocol
|
||||
*
|
||||
* In a typical situation this only needs to be called once, when NLSR starts.
|
||||
* \param syncPrefix The sync prefix you want this ChronoSync to use
|
||||
* \param syncInterestLifetime ChronoSync sends a periodic sync interest every \p syncInterestLifetime / 2 ms
|
||||
* \sa Nlsr::initialize
|
||||
* \param updateName The prefix for which sync reports an update
|
||||
* \param highSeq The latest sequence number of the update
|
||||
*/
|
||||
void
|
||||
createSyncSocket(const ndn::Name& syncPrefix,
|
||||
const ndn::time::milliseconds& syncInterestLifetime =
|
||||
ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT));
|
||||
processUpdate(const ndn::Name& updateName, uint64_t highSeq, uint64_t incomingFaceId);
|
||||
|
||||
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,
|
||||
@@ -116,24 +84,12 @@ private:
|
||||
*/
|
||||
void
|
||||
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);
|
||||
const ndn::Name& updateName, uint64_t seqNo, uint64_t incomingFaceId);
|
||||
|
||||
public:
|
||||
std::unique_ptr<OnNewLsa> onNewLsa;
|
||||
OnNewLsa onNewLsa;
|
||||
|
||||
private:
|
||||
ndn::Face& m_syncFace;
|
||||
std::shared_ptr<chronosync::Socket> m_syncSocket;
|
||||
ndn::Name m_syncPrefix;
|
||||
IsLsaNew m_isLsaNew;
|
||||
const ConfParameter& m_confParam;
|
||||
|
||||
@@ -142,10 +98,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
ndn::Name m_adjLsaUserPrefix;
|
||||
ndn::Name m_coorLsaUserPrefix;
|
||||
|
||||
private:
|
||||
static const std::string NLSR_COMPONENT;
|
||||
static const std::string LSA_COMPONENT;
|
||||
|
||||
SyncProtocolAdapter m_syncLogic;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sync-protocol-adapter.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(SyncProtocolAdapter);
|
||||
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
const auto FIXED_SESSION = ndn::name::Component::fromNumber(0);
|
||||
#endif
|
||||
|
||||
SyncProtocolAdapter::SyncProtocolAdapter(ndn::Face& face,
|
||||
ndn::KeyChain& keyChain,
|
||||
SyncProtocol syncProtocol,
|
||||
const ndn::Name& syncPrefix,
|
||||
const ndn::Name& userPrefix,
|
||||
ndn::time::milliseconds syncInterestLifetime,
|
||||
SyncUpdateCallback syncUpdateCallback)
|
||||
: m_syncProtocol(syncProtocol)
|
||||
, m_syncUpdateCallback(std::move(syncUpdateCallback))
|
||||
{
|
||||
switch (m_syncProtocol) {
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
case SyncProtocol::CHRONOSYNC:
|
||||
NDN_LOG_DEBUG("Using ChronoSync");
|
||||
m_chronoSyncLogic = std::make_shared<chronosync::Logic>(face,
|
||||
syncPrefix,
|
||||
userPrefix,
|
||||
[this] (auto&&... args) { onChronoSyncUpdate(std::forward<decltype(args)>(args)...); },
|
||||
chronosync::Logic::DEFAULT_NAME,
|
||||
chronosync::Logic::DEFAULT_VALIDATOR,
|
||||
chronosync::Logic::DEFAULT_RESET_TIMER,
|
||||
chronosync::Logic::DEFAULT_CANCEL_RESET_TIMER,
|
||||
chronosync::Logic::DEFAULT_RESET_INTEREST_LIFETIME,
|
||||
syncInterestLifetime,
|
||||
chronosync::Logic::DEFAULT_SYNC_REPLY_FRESHNESS,
|
||||
chronosync::Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME,
|
||||
FIXED_SESSION);
|
||||
break;
|
||||
#endif // HAVE_CHRONOSYNC
|
||||
#ifdef HAVE_PSYNC
|
||||
case SyncProtocol::PSYNC:
|
||||
NDN_LOG_DEBUG("Using PSync");
|
||||
m_psyncLogic = std::make_shared<psync::FullProducer>(face,
|
||||
keyChain,
|
||||
80,
|
||||
syncPrefix,
|
||||
userPrefix,
|
||||
[this] (auto&&... args) { onPSyncUpdate(std::forward<decltype(args)>(args)...); },
|
||||
syncInterestLifetime);
|
||||
break;
|
||||
#endif // HAVE_PSYNC
|
||||
#ifdef HAVE_SVS
|
||||
case SyncProtocol::SVS:
|
||||
NDN_LOG_DEBUG("Using SVS");
|
||||
m_svsCore = std::make_shared<ndn::svs::SVSyncCore>(face,
|
||||
syncPrefix,
|
||||
[this] (auto&&... args) { onSvsUpdate(std::forward<decltype(args)>(args)...); });
|
||||
break;
|
||||
#endif // HAVE_SVS
|
||||
default:
|
||||
NDN_CXX_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncProtocolAdapter::addUserNode(const ndn::Name& userPrefix)
|
||||
{
|
||||
switch (m_syncProtocol) {
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
case SyncProtocol::CHRONOSYNC:
|
||||
m_chronoSyncLogic->addUserNode(userPrefix, chronosync::Logic::DEFAULT_NAME, FIXED_SESSION);
|
||||
break;
|
||||
#endif // HAVE_CHRONOSYNC
|
||||
#ifdef HAVE_PSYNC
|
||||
case SyncProtocol::PSYNC:
|
||||
m_psyncLogic->addUserNode(userPrefix);
|
||||
break;
|
||||
#endif // HAVE_PSYNC
|
||||
#ifdef HAVE_SVS
|
||||
case SyncProtocol::SVS:
|
||||
break;
|
||||
#endif // HAVE_SVS
|
||||
default:
|
||||
NDN_CXX_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncProtocolAdapter::publishUpdate(const ndn::Name& userPrefix, uint64_t seq)
|
||||
{
|
||||
switch (m_syncProtocol) {
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
case SyncProtocol::CHRONOSYNC:
|
||||
m_chronoSyncLogic->updateSeqNo(seq, userPrefix);
|
||||
break;
|
||||
#endif // HAVE_CHRONOSYNC
|
||||
#ifdef HAVE_PSYNC
|
||||
case SyncProtocol::PSYNC:
|
||||
m_psyncLogic->publishName(userPrefix, seq);
|
||||
break;
|
||||
#endif // HAVE_PSYNC
|
||||
#ifdef HAVE_SVS
|
||||
case SyncProtocol::SVS:
|
||||
m_svsCore->updateSeqNo(seq, userPrefix);
|
||||
break;
|
||||
#endif // HAVE_SVS
|
||||
default:
|
||||
NDN_CXX_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
void
|
||||
SyncProtocolAdapter::onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
|
||||
{
|
||||
NLSR_LOG_TRACE("Received ChronoSync update event");
|
||||
|
||||
for (const auto& update : updates) {
|
||||
// Remove FIXED_SESSION
|
||||
m_syncUpdateCallback(update.session.getPrefix(-1), update.high, 0);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_CHRONOSYNC
|
||||
|
||||
#ifdef HAVE_PSYNC
|
||||
void
|
||||
SyncProtocolAdapter::onPSyncUpdate(const std::vector<psync::MissingDataInfo>& updates)
|
||||
{
|
||||
NLSR_LOG_TRACE("Received PSync update event");
|
||||
|
||||
for (const auto& update : updates) {
|
||||
m_syncUpdateCallback(update.prefix, update.highSeq, update.incomingFace);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_PSYNC
|
||||
|
||||
#ifdef HAVE_SVS
|
||||
void
|
||||
SyncProtocolAdapter::onSvsUpdate(const std::vector<ndn::svs::MissingDataInfo>& updates)
|
||||
{
|
||||
NLSR_LOG_TRACE("Received SVS update event");
|
||||
|
||||
for (const auto& update : updates) {
|
||||
m_syncUpdateCallback(update.nodeId, update.high, update.incomingFace);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_SVS
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -0,0 +1,128 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2022, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_SYNC_PROTOCOL_ADAPTER_HPP
|
||||
#define NLSR_SYNC_PROTOCOL_ADAPTER_HPP
|
||||
|
||||
#include "conf-parameter.hpp"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
#include <ChronoSync/logic.hpp>
|
||||
#endif
|
||||
#ifdef HAVE_PSYNC
|
||||
#include <PSync/full-producer.hpp>
|
||||
#endif
|
||||
#ifdef HAVE_SVS
|
||||
#include <ndn-svs/core.hpp>
|
||||
#endif
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
using SyncUpdateCallback = std::function<void(const ndn::Name& updateName,
|
||||
uint64_t seqNo, uint64_t incomingFaceId)>;
|
||||
|
||||
class SyncProtocolAdapter
|
||||
{
|
||||
public:
|
||||
SyncProtocolAdapter(ndn::Face& face,
|
||||
ndn::KeyChain& keyChain,
|
||||
SyncProtocol syncProtocol,
|
||||
const ndn::Name& syncPrefix,
|
||||
const ndn::Name& userPrefix,
|
||||
ndn::time::milliseconds syncInterestLifetime,
|
||||
SyncUpdateCallback syncUpdateCallback);
|
||||
|
||||
/*! \brief Add user node to Sync
|
||||
*
|
||||
* \param userPrefix the Name under which the application will publishData
|
||||
*/
|
||||
void
|
||||
addUserNode(const ndn::Name& userPrefix);
|
||||
|
||||
/*! \brief Publish update to Sync
|
||||
*
|
||||
* NLSR forces sequences number on the sync protocol
|
||||
* as it manages is its own sequence number by storing it in a file.
|
||||
*
|
||||
* \param userPrefix the Name to be updated
|
||||
* \param seq the sequence of userPrefix
|
||||
*/
|
||||
void
|
||||
publishUpdate(const ndn::Name& userPrefix, uint64_t seq);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
/*! \brief Hook function to call whenever ChronoSync detects new data.
|
||||
*
|
||||
* This function packages the sync information into discrete updates
|
||||
* and passes those off to another function, m_syncUpdateCallback.
|
||||
*
|
||||
* \param updates A container with the new information sync has received
|
||||
*/
|
||||
void
|
||||
onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates);
|
||||
#endif // HAVE_CHRONOSYNC
|
||||
|
||||
#ifdef HAVE_PSYNC
|
||||
/*! \brief Hook function to call whenever PSync detects new data.
|
||||
*
|
||||
* This function packages the sync information into discrete updates
|
||||
* and passes those off to another function, m_syncUpdateCallback.
|
||||
*
|
||||
* \param updates A container with the new information sync has received
|
||||
*/
|
||||
void
|
||||
onPSyncUpdate(const std::vector<psync::MissingDataInfo>& updates);
|
||||
#endif // HAVE_PSYNC
|
||||
|
||||
#ifdef HAVE_SVS
|
||||
/*! \brief Hook function to call whenever SVS detects new data.
|
||||
*
|
||||
* This function packages the sync information into discrete updates
|
||||
* and passes those off to another function, m_syncUpdateCallback.
|
||||
*
|
||||
* \param updates A container with the new information sync has received
|
||||
*/
|
||||
void
|
||||
onSvsUpdate(const std::vector<ndn::svs::MissingDataInfo>& updates);
|
||||
#endif // HAVE_SVS
|
||||
|
||||
private:
|
||||
SyncProtocol m_syncProtocol;
|
||||
SyncUpdateCallback m_syncUpdateCallback;
|
||||
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
std::shared_ptr<chronosync::Logic> m_chronoSyncLogic;
|
||||
#endif
|
||||
#ifdef HAVE_PSYNC
|
||||
std::shared_ptr<psync::FullProducer> m_psyncLogic;
|
||||
#endif
|
||||
#ifdef HAVE_SVS
|
||||
std::shared_ptr<ndn::svs::SVSyncCore> m_svsCore;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_SYNC_PROTOCOL_ADAPTER_HPP
|
||||
+210
-160
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,21 +17,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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "conf-file-processor.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "update/prefix-update-processor.hpp"
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "utility/name-helper.hpp"
|
||||
|
||||
#include <ndn-cxx/name.hpp>
|
||||
#include <ndn-cxx/net/face-uri.hpp>
|
||||
#include <ndn-cxx/util/io.hpp>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/property_tree/info_parser.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
@@ -40,7 +44,6 @@ class ConfigurationVariable
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(T)> ConfParameterCallback;
|
||||
typedef boost::property_tree::ptree ConfigSection;
|
||||
|
||||
ConfigurationVariable(const std::string& key, const ConfParameterCallback& setter)
|
||||
: m_key(key)
|
||||
@@ -125,8 +128,8 @@ private:
|
||||
private:
|
||||
const std::string m_key;
|
||||
const ConfParameterCallback m_setterCallback;
|
||||
T m_defaultValue;
|
||||
|
||||
T m_defaultValue;
|
||||
T m_minValue;
|
||||
T m_maxValue;
|
||||
|
||||
@@ -134,79 +137,75 @@ private:
|
||||
bool m_isRequired;
|
||||
};
|
||||
|
||||
ConfFileProcessor::ConfFileProcessor(ConfParameter& confParam)
|
||||
: m_confFileName(confParam.getConfFileName())
|
||||
, m_confParam(confParam)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ConfFileProcessor::processConfFile()
|
||||
{
|
||||
bool ret = true;
|
||||
std::ifstream inputFile;
|
||||
inputFile.open(m_confFileName.c_str());
|
||||
std::ifstream inputFile(m_confFileName);
|
||||
if (!inputFile.is_open()) {
|
||||
std::string msg = "Failed to read configuration file: ";
|
||||
msg += m_confFileName;
|
||||
std::cerr << msg << std::endl;
|
||||
std::cerr << "Failed to read configuration file: " << m_confFileName << std::endl;
|
||||
return false;
|
||||
}
|
||||
ret = load(inputFile);
|
||||
inputFile.close();
|
||||
return ret;
|
||||
|
||||
if (!load(inputFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_confParam.buildRouterAndSyncUserPrefix();
|
||||
m_confParam.writeLog();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfFileProcessor::load(std::istream& input)
|
||||
{
|
||||
ConfigSection pt;
|
||||
bool ret = true;
|
||||
try {
|
||||
boost::property_tree::read_info(input, pt);
|
||||
}
|
||||
catch (const boost::property_tree::info_parser_error& error) {
|
||||
std::stringstream msg;
|
||||
std::cerr << "Failed to parse configuration file " << std::endl;
|
||||
std::cerr << m_confFileName << std::endl;
|
||||
catch (const boost::property_tree::ptree_error& e) {
|
||||
std::cerr << "Failed to parse configuration file '" << m_confFileName
|
||||
<< "': " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ConfigSection::const_iterator tn = pt.begin();
|
||||
tn != pt.end(); ++tn) {
|
||||
ret = processSection(tn->first, tn->second);
|
||||
if (ret == false) {
|
||||
break;
|
||||
for (const auto& tn : pt) {
|
||||
if (!processSection(tn.first, tn.second)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSection& section)
|
||||
{
|
||||
bool ret = true;
|
||||
if (sectionName == "general")
|
||||
{
|
||||
if (sectionName == "general") {
|
||||
ret = processConfSectionGeneral(section);
|
||||
}
|
||||
else if (sectionName == "neighbors")
|
||||
{
|
||||
else if (sectionName == "neighbors") {
|
||||
ret = processConfSectionNeighbors(section);
|
||||
}
|
||||
else if (sectionName == "hyperbolic")
|
||||
{
|
||||
else if (sectionName == "hyperbolic") {
|
||||
ret = processConfSectionHyperbolic(section);
|
||||
}
|
||||
else if (sectionName == "fib")
|
||||
{
|
||||
else if (sectionName == "fib") {
|
||||
ret = processConfSectionFib(section);
|
||||
}
|
||||
else if (sectionName == "advertising")
|
||||
{
|
||||
else if (sectionName == "advertising") {
|
||||
ret = processConfSectionAdvertising(section);
|
||||
}
|
||||
else if (sectionName == "security")
|
||||
{
|
||||
else if (sectionName == "security") {
|
||||
ret = processConfSectionSecurity(section);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Wrong configuration section: " << sectionName << std::endl;
|
||||
else {
|
||||
std::cerr << "Unknown configuration section: " << sectionName << std::endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -214,32 +213,64 @@ ConfFileProcessor::processSection(const std::string& sectionName, const ConfigSe
|
||||
bool
|
||||
ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
{
|
||||
// sync-protocol
|
||||
std::string syncProtocol = section.get<std::string>("sync-protocol", "psync");
|
||||
if (syncProtocol == "chronosync") {
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
m_confParam.setSyncProtocol(SyncProtocol::CHRONOSYNC);
|
||||
#else
|
||||
std::cerr << "NLSR was compiled without ChronoSync support!\n";
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else if (syncProtocol == "psync") {
|
||||
#ifdef HAVE_PSYNC
|
||||
m_confParam.setSyncProtocol(SyncProtocol::PSYNC);
|
||||
#else
|
||||
std::cerr << "NLSR was compiled without PSync support!\n";
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else if (syncProtocol == "svs") {
|
||||
#ifdef HAVE_SVS
|
||||
m_confParam.setSyncProtocol(SyncProtocol::SVS);
|
||||
#else
|
||||
std::cerr << "NLSR was compiled without SVS support!\n";
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
std::cerr << "Sync protocol '" << syncProtocol << "' is not supported!\n"
|
||||
<< "Use 'chronosync' or 'psync' or 'svs'\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
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);
|
||||
m_confParam.setNetwork(networkName);
|
||||
}
|
||||
else {
|
||||
std::cerr << " Network can not be null or empty or in bad URI format :(!" << std::endl;
|
||||
std::cerr << "Network can not be null or empty or in bad URI format" << std::endl;
|
||||
return false;
|
||||
}
|
||||
ndn::Name siteName(site);
|
||||
if (!siteName.empty()) {
|
||||
m_nlsr.getConfParameter().setSiteName(siteName);
|
||||
m_confParam.setSiteName(siteName);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Site can not be null or empty or in bad URI format:( !" << std::endl;
|
||||
std::cerr << "Site can not be null or empty or in bad URI format" << std::endl;
|
||||
return false;
|
||||
}
|
||||
ndn::Name routerName(router);
|
||||
if (!routerName.empty()) {
|
||||
m_nlsr.getConfParameter().setRouterName(routerName);
|
||||
m_confParam.setRouterName(routerName);
|
||||
}
|
||||
else {
|
||||
std::cerr << " Router name can not be null or empty or in bad URI format:( !" << std::endl;
|
||||
std::cerr << "Router name can not be null or empty or in bad URI format" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -252,21 +283,20 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
uint32_t lsaRefreshTime = section.get<uint32_t>("lsa-refresh-time", LSA_REFRESH_TIME_DEFAULT);
|
||||
|
||||
if (lsaRefreshTime >= LSA_REFRESH_TIME_MIN && lsaRefreshTime <= LSA_REFRESH_TIME_MAX) {
|
||||
m_nlsr.getConfParameter().setLsaRefreshTime(lsaRefreshTime);
|
||||
m_confParam.setLsaRefreshTime(lsaRefreshTime);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong value for lsa-refresh-time ";
|
||||
std::cerr << "Allowed value: " << LSA_REFRESH_TIME_MIN << "-";;
|
||||
std::cerr << LSA_REFRESH_TIME_MAX << std::endl;
|
||||
|
||||
std::cerr << "Invalid value for lsa-refresh-time. "
|
||||
<< "Allowed range: " << LSA_REFRESH_TIME_MIN
|
||||
<< "-" << LSA_REFRESH_TIME_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// router-dead-interval
|
||||
uint32_t routerDeadInterval = section.get<uint32_t>("router-dead-interval", (2*lsaRefreshTime));
|
||||
uint32_t routerDeadInterval = section.get<uint32_t>("router-dead-interval", 2 * lsaRefreshTime);
|
||||
|
||||
if (routerDeadInterval > m_nlsr.getConfParameter().getLsaRefreshTime()) {
|
||||
m_nlsr.getConfParameter().setRouterDeadInterval(routerDeadInterval);
|
||||
if (routerDeadInterval > m_confParam.getLsaRefreshTime()) {
|
||||
m_confParam.setRouterDeadInterval(routerDeadInterval);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Value of router-dead-interval must be larger than lsa-refresh-time" << std::endl;
|
||||
@@ -277,59 +307,85 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
int lifetime = section.get<int>("lsa-interest-lifetime", LSA_INTEREST_LIFETIME_DEFAULT);
|
||||
|
||||
if (lifetime >= LSA_INTEREST_LIFETIME_MIN && lifetime <= LSA_INTEREST_LIFETIME_MAX) {
|
||||
m_nlsr.getConfParameter().setLsaInterestLifetime(ndn::time::seconds(lifetime));
|
||||
m_confParam.setLsaInterestLifetime(ndn::time::seconds(lifetime));
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong value for lsa-interest-timeout. "
|
||||
<< "Allowed value:" << LSA_INTEREST_LIFETIME_MIN << "-"
|
||||
<< LSA_INTEREST_LIFETIME_MAX << std::endl;
|
||||
|
||||
std::cerr << "Invalid value for lsa-interest-timeout. "
|
||||
<< "Allowed range: " << LSA_INTEREST_LIFETIME_MIN
|
||||
<< "-" << LSA_INTEREST_LIFETIME_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime", SYNC_INTEREST_LIFETIME_DEFAULT);
|
||||
// sync-interest-lifetime
|
||||
uint32_t syncInterestLifetime = section.get<uint32_t>("sync-interest-lifetime",
|
||||
SYNC_INTEREST_LIFETIME_DEFAULT);
|
||||
if (syncInterestLifetime >= SYNC_INTEREST_LIFETIME_MIN &&
|
||||
syncInterestLifetime <= SYNC_INTEREST_LIFETIME_MAX) {
|
||||
m_nlsr.getConfParameter().setSyncInterestLifetime(syncInterestLifetime);
|
||||
m_confParam.setSyncInterestLifetime(syncInterestLifetime);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong value for sync-interest-lifetime. "
|
||||
<< "Allowed value:" << SYNC_INTEREST_LIFETIME_MIN << "-"
|
||||
<< SYNC_INTEREST_LIFETIME_MAX << std::endl;
|
||||
|
||||
std::cerr << "Invalid value for sync-interest-lifetime. "
|
||||
<< "Allowed range: " << SYNC_INTEREST_LIFETIME_MIN
|
||||
<< "-" << SYNC_INTEREST_LIFETIME_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
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";
|
||||
std::ofstream testOutFile;
|
||||
testOutFile.open(testFileName.c_str());
|
||||
if (testOutFile.is_open() && testOutFile.good()) {
|
||||
m_nlsr.getConfParameter().setSeqFileDir(seqDir);
|
||||
std::string stateDir = section.get<std::string>("state-dir");
|
||||
if (bf::exists(stateDir)) {
|
||||
if (bf::is_directory(stateDir)) {
|
||||
// copying nlsr.conf file to a user-defined directory for possible modification
|
||||
std::string conFileDynamic = (bf::path(stateDir) / "nlsr.conf").string();
|
||||
|
||||
if (m_confFileName == conFileDynamic) {
|
||||
std::cerr << "Please use nlsr.conf stored at another location "
|
||||
<< "or change the state-dir in the configuration." << std::endl;
|
||||
std::cerr << "The file at " << conFileDynamic <<
|
||||
" is used as dynamic file for saving NLSR runtime changes." << std::endl;
|
||||
std::cerr << "The dynamic file can be used for next run "
|
||||
<< "after copying to another location." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_confParam.setConfFileNameDynamic(conFileDynamic);
|
||||
try {
|
||||
bf::copy_file(m_confFileName, conFileDynamic,
|
||||
#if BOOST_VERSION >= 107400
|
||||
bf::copy_options::overwrite_existing
|
||||
#else
|
||||
bf::copy_option::overwrite_if_exists
|
||||
#endif
|
||||
);
|
||||
}
|
||||
catch (const bf::filesystem_error& e) {
|
||||
std::cerr << "Error copying conf file to the state directory: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string testFileName = (bf::path(stateDir) / "test.seq").string();
|
||||
std::ofstream testOutFile(testFileName);
|
||||
if (testOutFile) {
|
||||
m_confParam.setStateFileDir(stateDir);
|
||||
}
|
||||
else {
|
||||
std::cerr << "User does not have read and write permission on the directory";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "NLSR does not have read/write permission on the state directory" << std::endl;
|
||||
return false;
|
||||
}
|
||||
testOutFile.close();
|
||||
remove(testFileName.c_str());
|
||||
}
|
||||
else {
|
||||
std::cerr << "Provided path is not a directory" << std::endl;
|
||||
std::cerr << "Provided path '" << stateDir << "' is not a directory" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Provided sequence directory <" << seqDir << "> does not exist" << std::endl;
|
||||
std::cerr << "Provided state directory '" << stateDir << "' does not exist" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
std::cerr << "You must configure sequence directory" << std::endl;
|
||||
std::cerr << "You must configure state directory" << std::endl;
|
||||
std::cerr << ex.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
@@ -344,13 +400,11 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
int retrials = section.get<int>("hello-retries", HELLO_RETRIES_DEFAULT);
|
||||
|
||||
if (retrials >= HELLO_RETRIES_MIN && retrials <= HELLO_RETRIES_MAX) {
|
||||
m_nlsr.getConfParameter().setInterestRetryNumber(retrials);
|
||||
m_confParam.setInterestRetryNumber(retrials);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong value for hello-retries." << std::endl;
|
||||
std::cerr << "Allowed value:" << HELLO_RETRIES_MIN << "-";
|
||||
std::cerr << HELLO_RETRIES_MAX << std::endl;
|
||||
|
||||
std::cerr << "Invalid value for hello-retries. "
|
||||
<< "Allowed range: " << HELLO_RETRIES_MIN << "-" << HELLO_RETRIES_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -358,13 +412,11 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
uint32_t timeOut = section.get<uint32_t>("hello-timeout", HELLO_TIMEOUT_DEFAULT);
|
||||
|
||||
if (timeOut >= HELLO_TIMEOUT_MIN && timeOut <= HELLO_TIMEOUT_MAX) {
|
||||
m_nlsr.getConfParameter().setInterestResendTime(timeOut);
|
||||
m_confParam.setInterestResendTime(timeOut);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong value for hello-timeout. ";
|
||||
std::cerr << "Allowed value:" << HELLO_TIMEOUT_MIN << "-";
|
||||
std::cerr << HELLO_TIMEOUT_MAX << std::endl;
|
||||
|
||||
std::cerr << "Invalid value for hello-timeout. "
|
||||
<< "Allowed range: " << HELLO_TIMEOUT_MIN << "-" << HELLO_TIMEOUT_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -372,13 +424,11 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
uint32_t interval = section.get<uint32_t>("hello-interval", HELLO_INTERVAL_DEFAULT);
|
||||
|
||||
if (interval >= HELLO_INTERVAL_MIN && interval <= HELLO_INTERVAL_MAX) {
|
||||
m_nlsr.getConfParameter().setInfoInterestInterval(interval);
|
||||
m_confParam.setInfoInterestInterval(interval);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong value for hello-interval. ";
|
||||
std::cerr << "Allowed value:" << HELLO_INTERVAL_MIN << "-";
|
||||
std::cerr << HELLO_INTERVAL_MAX << std::endl;
|
||||
|
||||
std::cerr << "Invalid value for hello-interval. "
|
||||
<< "Allowed range: " << HELLO_INTERVAL_MIN << "-" << HELLO_INTERVAL_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -386,7 +436,7 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
// adj-lsa-build-interval
|
||||
ConfigurationVariable<uint32_t> adjLsaBuildInterval("adj-lsa-build-interval",
|
||||
std::bind(&ConfParameter::setAdjLsaBuildInterval,
|
||||
&m_nlsr.getConfParameter(), _1));
|
||||
&m_confParam, _1));
|
||||
adjLsaBuildInterval.setMinAndMaxValue(ADJ_LSA_BUILD_INTERVAL_MIN, ADJ_LSA_BUILD_INTERVAL_MAX);
|
||||
adjLsaBuildInterval.setOptional(ADJ_LSA_BUILD_INTERVAL_DEFAULT);
|
||||
|
||||
@@ -396,8 +446,7 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
// 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));
|
||||
&m_confParam, _1));
|
||||
|
||||
faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
|
||||
FACE_DATASET_FETCH_TRIES_MAX);
|
||||
@@ -409,9 +458,8 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
|
||||
// Set the interval between FaceStatus dataset fetch attempts.
|
||||
ConfigurationVariable<uint32_t> faceDatasetFetchInterval("face-dataset-fetch-interval",
|
||||
bind(&ConfParameter::setFaceDatasetFetchInterval,
|
||||
&m_nlsr.getConfParameter(),
|
||||
_1));
|
||||
std::bind(&ConfParameter::setFaceDatasetFetchInterval,
|
||||
&m_confParam, _1));
|
||||
|
||||
faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
|
||||
FACE_DATASET_FETCH_INTERVAL_MAX);
|
||||
@@ -421,38 +469,42 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
return false;
|
||||
}
|
||||
|
||||
// first-hello-interval
|
||||
ConfigurationVariable<uint32_t> firstHelloInterval("first-hello-interval",
|
||||
std::bind(&ConfParameter::setFirstHelloInterval,
|
||||
&m_nlsr.getConfParameter(), _1));
|
||||
firstHelloInterval.setMinAndMaxValue(FIRST_HELLO_INTERVAL_MIN, FIRST_HELLO_INTERVAL_MAX);
|
||||
firstHelloInterval.setOptional(FIRST_HELLO_INTERVAL_DEFAULT);
|
||||
|
||||
if (!firstHelloInterval.parseFromConfigSection(section)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ConfigSection::const_iterator tn =
|
||||
section.begin(); tn != section.end(); ++tn) {
|
||||
|
||||
if (tn->first == "neighbor") {
|
||||
for (const auto& tn : section) {
|
||||
if (tn.first == "neighbor") {
|
||||
try {
|
||||
ConfigSection CommandAttriTree = tn->second;
|
||||
ConfigSection CommandAttriTree = tn.second;
|
||||
std::string name = CommandAttriTree.get<std::string>("name");
|
||||
std::string uriString = CommandAttriTree.get<std::string>("face-uri");
|
||||
|
||||
ndn::FaceUri faceUri;
|
||||
if (! faceUri.parse(uriString)) {
|
||||
std::cerr << "parsing failed!" << std::endl;
|
||||
if (!faceUri.parse(uriString)) {
|
||||
std::cerr << "face-uri parsing failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
double linkCost = CommandAttriTree.get<double>("link-cost",
|
||||
Adjacent::DEFAULT_LINK_COST);
|
||||
bool failedToCanonize = false;
|
||||
faceUri.canonize([&faceUri] (const auto& canonicalUri) {
|
||||
faceUri = canonicalUri;
|
||||
},
|
||||
[&faceUri, &failedToCanonize] (const auto& reason) {
|
||||
failedToCanonize = true;
|
||||
std::cerr << "Could not canonize URI: '" << faceUri
|
||||
<< "' because: " << reason << std::endl;
|
||||
},
|
||||
m_io,
|
||||
TIME_ALLOWED_FOR_CANONIZATION);
|
||||
m_io.run();
|
||||
m_io.restart();
|
||||
|
||||
if (failedToCanonize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double linkCost = CommandAttriTree.get<double>("link-cost", Adjacent::DEFAULT_LINK_COST);
|
||||
ndn::Name neighborName(name);
|
||||
if (!neighborName.empty()) {
|
||||
Adjacent adj(name, faceUri, linkCost, Adjacent::STATUS_INACTIVE, 0, 0);
|
||||
m_nlsr.getAdjacencyList().insert(adj);
|
||||
m_confParam.getAdjacencyList().insert(adj);
|
||||
}
|
||||
else {
|
||||
std::cerr << " Wrong command format ! [name /nbr/name/ \n face-uri /uri\n]";
|
||||
@@ -475,18 +527,17 @@ ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
|
||||
std::string state = section.get<std::string>("state", "off");
|
||||
|
||||
if (boost::iequals(state, "off")) {
|
||||
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_OFF);
|
||||
m_confParam.setHyperbolicState(HYPERBOLIC_STATE_OFF);
|
||||
}
|
||||
else if (boost::iequals(state, "on")) {
|
||||
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
|
||||
m_confParam.setHyperbolicState(HYPERBOLIC_STATE_ON);
|
||||
}
|
||||
else if (state == "dry-run") {
|
||||
m_nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
|
||||
else if (boost::iequals(state, "dry-run")) {
|
||||
m_confParam.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong format for hyperbolic state." << std::endl;
|
||||
std::cerr << "Allowed value: off, on, dry-run" << std::endl;
|
||||
|
||||
std::cerr << "Invalid setting for hyperbolic state. "
|
||||
<< "Allowed values: off, on, dry-run" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -510,10 +561,10 @@ ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_nlsr.getConfParameter().setCorR(radius)) {
|
||||
if (!m_confParam.setCorR(radius)) {
|
||||
return false;
|
||||
}
|
||||
m_nlsr.getConfParameter().setCorTheta(angles);
|
||||
m_confParam.setCorTheta(angles);
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
std::cerr << ex.what() << std::endl;
|
||||
@@ -532,21 +583,20 @@ ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
|
||||
int maxFacesPerPrefix = section.get<int>("max-faces-per-prefix", MAX_FACES_PER_PREFIX_DEFAULT);
|
||||
|
||||
if (maxFacesPerPrefix >= MAX_FACES_PER_PREFIX_MIN &&
|
||||
maxFacesPerPrefix <= MAX_FACES_PER_PREFIX_MAX)
|
||||
{
|
||||
m_nlsr.getConfParameter().setMaxFacesPerPrefix(maxFacesPerPrefix);
|
||||
maxFacesPerPrefix <= MAX_FACES_PER_PREFIX_MAX) {
|
||||
m_confParam.setMaxFacesPerPrefix(maxFacesPerPrefix);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong value for max-faces-per-prefix. ";
|
||||
std::cerr << MAX_FACES_PER_PREFIX_MIN << std::endl;
|
||||
|
||||
std::cerr << "Invalid value for max-faces-per-prefix. "
|
||||
<< "Allowed range: " << MAX_FACES_PER_PREFIX_MIN
|
||||
<< "-" << MAX_FACES_PER_PREFIX_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// routing-calc-interval
|
||||
ConfigurationVariable<uint32_t> routingCalcInterval("routing-calc-interval",
|
||||
std::bind(&ConfParameter::setRoutingCalcInterval,
|
||||
&m_nlsr.getConfParameter(), _1));
|
||||
&m_confParam, _1));
|
||||
routingCalcInterval.setMinAndMaxValue(ROUTING_CALC_INTERVAL_MIN, ROUTING_CALC_INTERVAL_MAX);
|
||||
routingCalcInterval.setOptional(ROUTING_CALC_INTERVAL_DEFAULT);
|
||||
|
||||
@@ -560,14 +610,12 @@ ConfFileProcessor::processConfSectionFib(const ConfigSection& section)
|
||||
bool
|
||||
ConfFileProcessor::processConfSectionAdvertising(const ConfigSection& section)
|
||||
{
|
||||
for (ConfigSection::const_iterator tn =
|
||||
section.begin(); tn != section.end(); ++tn) {
|
||||
if (tn->first == "prefix") {
|
||||
for (const auto& tn : section) {
|
||||
if (tn.first == "prefix") {
|
||||
try {
|
||||
std::string prefix = tn->second.data();
|
||||
ndn::Name namePrefix(prefix);
|
||||
ndn::Name namePrefix(tn.second.data());
|
||||
if (!namePrefix.empty()) {
|
||||
m_nlsr.getNamePrefixList().insert(namePrefix);
|
||||
m_confParam.getNamePrefixList().insert(namePrefix);
|
||||
}
|
||||
else {
|
||||
std::cerr << " Wrong command format ! [prefix /name/prefix] or bad URI" << std::endl;
|
||||
@@ -586,39 +634,41 @@ ConfFileProcessor::processConfSectionAdvertising(const ConfigSection& section)
|
||||
bool
|
||||
ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
|
||||
{
|
||||
ConfigSection::const_iterator it = section.begin();
|
||||
auto it = section.begin();
|
||||
|
||||
if (it == section.end() || it->first != "validator") {
|
||||
std::cerr << "Error: Expect validator section!" << std::endl;
|
||||
std::cerr << "Error: Expected validator section!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.loadValidator(it->second, m_confFileName);
|
||||
m_confParam.getValidator().load(it->second, m_confFileName);
|
||||
|
||||
it++;
|
||||
if (it != section.end() && it->first == "prefix-update-validator") {
|
||||
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
|
||||
m_confParam.getPrefixUpdateValidator().load(it->second, m_confFileName);
|
||||
|
||||
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;
|
||||
std::cerr << "Error: Expected cert-to-publish!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file = it->second.data();
|
||||
path certfilePath = absolute(file, path(m_confFileName).parent_path());
|
||||
std::shared_ptr<ndn::security::v2::Certificate> idCert =
|
||||
ndn::io::load<ndn::security::v2::Certificate>(certfilePath.string());
|
||||
bf::path certfilePath = absolute(file, bf::path(m_confFileName).parent_path());
|
||||
std::ifstream ifs(certfilePath.string());
|
||||
|
||||
if (idCert == nullptr) {
|
||||
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
|
||||
ndn::security::Certificate idCert;
|
||||
try {
|
||||
idCert = ndn::io::loadTlv<ndn::security::Certificate>(ifs);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error: Cannot load cert-to-publish '" << file << "': " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.loadCertToPublish(*idCert);
|
||||
m_confParam.addCertPath(certfilePath.string());
|
||||
m_confParam.loadCertToValidator(idCert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-22
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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,41 +17,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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
#define NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/property_tree/info_parser.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
using ConfigSection = boost::property_tree::ptree;
|
||||
|
||||
/*! \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:
|
||||
ConfFileProcessor(Nlsr& nlsr, const std::string& cfile)
|
||||
: m_confFileName(cfile)
|
||||
, m_nlsr(nlsr)
|
||||
{
|
||||
}
|
||||
ConfFileProcessor(ConfParameter& confParam);
|
||||
|
||||
/*! \brief Load and parse the configuration file, then populate NLSR.
|
||||
*
|
||||
@@ -63,8 +56,6 @@ public:
|
||||
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
|
||||
@@ -125,9 +116,12 @@ private:
|
||||
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;
|
||||
/*! m_confParam The ConfFileProcessor object to configure as parsing is done. */
|
||||
ConfParameter& m_confParam;
|
||||
/*! m_io For canonization of FaceUri. */
|
||||
boost::asio::io_context m_io;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
+109
-22
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,20 +16,48 @@
|
||||
*
|
||||
* 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 "conf-parameter.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <ndn-cxx/security/signing-helpers.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(ConfParameter);
|
||||
|
||||
// To be changed when breaking changes are made to sync
|
||||
const uint64_t ConfParameter::SYNC_VERSION = 5;
|
||||
static std::unique_ptr<ndn::security::CertificateFetcherDirectFetch>
|
||||
makeCertificateFetcher(ndn::Face& face)
|
||||
{
|
||||
auto fetcher = std::make_unique<ndn::security::CertificateFetcherDirectFetch>(face);
|
||||
fetcher->setSendDirectInterestOnly(true);
|
||||
return fetcher;
|
||||
}
|
||||
|
||||
ConfParameter::ConfParameter(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
const std::string& confFileName)
|
||||
: m_confFileName(confFileName)
|
||||
, m_lsaRefreshTime(LSA_REFRESH_TIME_DEFAULT)
|
||||
, m_adjLsaBuildInterval(ADJ_LSA_BUILD_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_interestRetryNumber(HELLO_RETRIES_DEFAULT)
|
||||
, m_interestResendTime(HELLO_TIMEOUT_DEFAULT)
|
||||
, m_infoInterestInterval(HELLO_INTERVAL_DEFAULT)
|
||||
, m_hyperbolicState(HYPERBOLIC_STATE_OFF)
|
||||
, m_corR(0)
|
||||
, m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
|
||||
, m_syncInterestLifetime(ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
|
||||
, m_adjl()
|
||||
, m_npl()
|
||||
, m_validator(makeCertificateFetcher(face))
|
||||
, m_prefixUpdateValidator(std::make_unique<ndn::security::CertificateFetcherDirectFetch>(face))
|
||||
, m_keyChain(keyChain)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConfParameter::writeLog()
|
||||
@@ -38,8 +66,8 @@ ConfParameter::writeLog()
|
||||
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("Sync Prefix: " << m_syncPrefix);
|
||||
NLSR_LOG_INFO("Sync 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);
|
||||
@@ -48,17 +76,18 @@ ConfParameter::writeLog()
|
||||
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);
|
||||
if (m_hyperbolicState == HYPERBOLIC_STATE_ON || m_hyperbolicState == HYPERBOLIC_STATE_DRY_RUN) {
|
||||
NLSR_LOG_INFO("Hyperbolic Routing: " << m_hyperbolicState);
|
||||
NLSR_LOG_INFO("Hyp R: " << m_corR);
|
||||
int i=0;
|
||||
for (auto const& value: m_corTheta) {
|
||||
NLSR_LOG_INFO("Hyp Angle " << i++ << ": "<< value);
|
||||
}
|
||||
}
|
||||
NLSR_LOG_INFO("Seq Directory: " << m_seqFileDir);
|
||||
NLSR_LOG_INFO("State Directory: " << m_stateFileDir);
|
||||
|
||||
// Event Intervals
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -67,11 +96,13 @@ ConfParameter::setNetwork(const ndn::Name& networkName)
|
||||
{
|
||||
m_network = networkName;
|
||||
|
||||
m_chronosyncPrefix.append("localhop");
|
||||
m_chronosyncPrefix.append(m_network);
|
||||
m_chronosyncPrefix.append("nlsr");
|
||||
m_chronosyncPrefix.append("sync");
|
||||
m_chronosyncPrefix.appendVersion(SYNC_VERSION);
|
||||
if (m_syncProtocol != SyncProtocol::SVS) {
|
||||
m_syncPrefix.append("localhop");
|
||||
}
|
||||
m_syncPrefix.append(m_network);
|
||||
m_syncPrefix.append("nlsr");
|
||||
m_syncPrefix.append("sync");
|
||||
m_syncPrefix.appendVersion(SYNC_VERSION);
|
||||
|
||||
m_lsaPrefix.append("localhop");
|
||||
m_lsaPrefix.append(m_network);
|
||||
@@ -79,4 +110,60 @@ ConfParameter::setNetwork(const ndn::Name& networkName)
|
||||
m_lsaPrefix.append("LSA");
|
||||
}
|
||||
|
||||
void
|
||||
ConfParameter::loadCertToValidator(const ndn::security::Certificate& cert)
|
||||
{
|
||||
NLSR_LOG_TRACE("Loading Certificate Name: " << cert.getName());
|
||||
m_validator.loadAnchor("Authoritative-Certificate", ndn::security::Certificate(cert));
|
||||
m_prefixUpdateValidator.loadAnchor("Authoritative-Certificate", ndn::security::Certificate(cert));
|
||||
}
|
||||
|
||||
std::optional<ndn::security::Certificate>
|
||||
ConfParameter::initializeKey()
|
||||
{
|
||||
using namespace ndn::security;
|
||||
NLSR_LOG_DEBUG("Initializing Key ...");
|
||||
|
||||
Identity routerIdentity;
|
||||
try {
|
||||
routerIdentity = m_keyChain.getPib().getIdentity(m_routerPrefix);
|
||||
}
|
||||
catch (const Pib::Error&) {
|
||||
NLSR_LOG_ERROR("Router identity " << m_routerPrefix << " not found. "
|
||||
"NLSR is running without security. "
|
||||
"If security is enabled in the configuration, NLSR will not converge.");
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
// This is (probably) needed for the dummy keychain patch.
|
||||
// https://github.com/named-data/mini-ndn/blob/master/util/patches/ndn-cxx-dummy-keychain.patch
|
||||
NLSR_LOG_DEBUG(e.what());
|
||||
}
|
||||
|
||||
auto instanceName = ndn::Name(m_routerPrefix).append("nlsr");
|
||||
try {
|
||||
m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(instanceName));
|
||||
}
|
||||
catch (const Pib::Error&) {
|
||||
// old instance identity does not exist
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
// This is needed for the dummy-keychain patch (ref above) to handle the error that it generates.
|
||||
const std::string exceptionText = e.what();
|
||||
if (exceptionText.find("does not match identity") == std::string::npos) {
|
||||
NLSR_LOG_ERROR(exceptionText);
|
||||
throw;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto key = m_keyChain.createIdentity(instanceName).getDefaultKey();
|
||||
auto cert = m_keyChain.makeCertificate(key, signingByIdentity(routerIdentity));
|
||||
m_keyChain.setDefaultCertificate(key, cert);
|
||||
|
||||
m_signingInfo = signingByCertificate(cert);
|
||||
loadCertToValidator(cert);
|
||||
return cert;
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+141
-59
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,22 +17,30 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_CONF_PARAMETER_HPP
|
||||
#define NLSR_CONF_PARAMETER_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
#include "adjacency-list.hpp"
|
||||
#include "name-prefix-list.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
#include <ndn-cxx/security/validator-config.hpp>
|
||||
#include <ndn-cxx/security/certificate-fetcher-direct-fetch.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
enum class SyncProtocol {
|
||||
CHRONOSYNC,
|
||||
PSYNC,
|
||||
SVS,
|
||||
};
|
||||
|
||||
enum {
|
||||
LSA_REFRESH_TIME_MIN = 240,
|
||||
LSA_REFRESH_TIME_DEFAULT = 1800,
|
||||
@@ -46,15 +54,9 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
ADJ_LSA_BUILD_INTERVAL_MIN = 0,
|
||||
ADJ_LSA_BUILD_INTERVAL_DEFAULT = 5,
|
||||
ADJ_LSA_BUILD_INTERVAL_MAX = 5
|
||||
};
|
||||
|
||||
enum {
|
||||
FIRST_HELLO_INTERVAL_MIN = 0,
|
||||
FIRST_HELLO_INTERVAL_DEFAULT = 10,
|
||||
FIRST_HELLO_INTERVAL_MAX = 10
|
||||
ADJ_LSA_BUILD_INTERVAL_MIN = 5,
|
||||
ADJ_LSA_BUILD_INTERVAL_DEFAULT = 10,
|
||||
ADJ_LSA_BUILD_INTERVAL_MAX = 30
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -84,7 +86,7 @@ enum {
|
||||
|
||||
enum {
|
||||
HELLO_TIMEOUT_MIN = 1,
|
||||
HELLO_TIMEOUT_DEFAULT = 3,
|
||||
HELLO_TIMEOUT_DEFAULT = 1,
|
||||
HELLO_TIMEOUT_MAX = 15
|
||||
};
|
||||
|
||||
@@ -126,25 +128,14 @@ enum {
|
||||
*/
|
||||
class ConfParameter
|
||||
{
|
||||
|
||||
public:
|
||||
ConfParameter()
|
||||
: m_lsaRefreshTime(LSA_REFRESH_TIME_DEFAULT)
|
||||
, 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")
|
||||
, m_interestRetryNumber(HELLO_RETRIES_DEFAULT)
|
||||
, m_interestResendTime(HELLO_TIMEOUT_DEFAULT)
|
||||
, m_infoInterestInterval(HELLO_INTERVAL_DEFAULT)
|
||||
, m_hyperbolicState(HYPERBOLIC_STATE_OFF)
|
||||
, m_corR(0)
|
||||
, m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
|
||||
, m_syncInterestLifetime(ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
|
||||
ConfParameter(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
const std::string& confFileName = "nlsr.conf");
|
||||
|
||||
const std::string&
|
||||
getConfFileName()
|
||||
{
|
||||
return m_confFileName;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -181,11 +172,15 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
buildRouterPrefix()
|
||||
buildRouterAndSyncUserPrefix()
|
||||
{
|
||||
m_routerPrefix = m_network;
|
||||
m_routerPrefix.append(m_siteName);
|
||||
m_routerPrefix.append(m_routerName);
|
||||
|
||||
m_syncUserPrefix = m_lsaPrefix;
|
||||
m_syncUserPrefix.append(m_siteName);
|
||||
m_syncUserPrefix.append(m_routerName);
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
@@ -194,11 +189,16 @@ public:
|
||||
return m_routerPrefix;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getSyncUserPrefix() const
|
||||
{
|
||||
return m_syncUserPrefix;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getChronosyncPrefix() const
|
||||
getSyncPrefix() const
|
||||
{
|
||||
return m_chronosyncPrefix;
|
||||
return m_syncPrefix;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
@@ -213,6 +213,18 @@ public:
|
||||
m_lsaRefreshTime = lrt;
|
||||
}
|
||||
|
||||
SyncProtocol
|
||||
getSyncProtocol() const
|
||||
{
|
||||
return m_syncProtocol;
|
||||
}
|
||||
|
||||
void
|
||||
setSyncProtocol(SyncProtocol syncProtocol)
|
||||
{
|
||||
m_syncProtocol = syncProtocol;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
getLsaRefreshTime() const
|
||||
{
|
||||
@@ -243,18 +255,6 @@ public:
|
||||
return m_adjLsaBuildInterval;
|
||||
}
|
||||
|
||||
void
|
||||
setFirstHelloInterval(uint32_t interval)
|
||||
{
|
||||
m_firstHelloInterval = interval;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
getFirstHelloInterval() const
|
||||
{
|
||||
return m_firstHelloInterval;
|
||||
}
|
||||
|
||||
void
|
||||
setRoutingCalcInterval(uint32_t interval)
|
||||
{
|
||||
@@ -392,15 +392,27 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
setSeqFileDir(const std::string& ssfd)
|
||||
setStateFileDir(const std::string& ssfd)
|
||||
{
|
||||
m_seqFileDir = ssfd;
|
||||
m_stateFileDir = ssfd;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getSeqFileDir() const
|
||||
getStateFileDir() const
|
||||
{
|
||||
return m_seqFileDir;
|
||||
return m_stateFileDir;
|
||||
}
|
||||
|
||||
void
|
||||
setConfFileNameDynamic(const std::string& confFileDynamic)
|
||||
{
|
||||
m_confFileNameDynamic = confFileDynamic;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getConfFileNameDynamic() const
|
||||
{
|
||||
return m_confFileNameDynamic;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -415,24 +427,83 @@ public:
|
||||
return m_syncInterestLifetime;
|
||||
}
|
||||
|
||||
AdjacencyList&
|
||||
getAdjacencyList()
|
||||
{
|
||||
return m_adjl;
|
||||
}
|
||||
|
||||
NamePrefixList&
|
||||
getNamePrefixList()
|
||||
{
|
||||
return m_npl;
|
||||
}
|
||||
|
||||
ndn::security::ValidatorConfig&
|
||||
getValidator()
|
||||
{
|
||||
return m_validator;
|
||||
}
|
||||
|
||||
ndn::security::ValidatorConfig&
|
||||
getPrefixUpdateValidator()
|
||||
{
|
||||
return m_prefixUpdateValidator;
|
||||
}
|
||||
|
||||
const ndn::security::SigningInfo&
|
||||
getSigningInfo() const
|
||||
{
|
||||
return m_signingInfo;
|
||||
}
|
||||
|
||||
void
|
||||
addCertPath(const std::string& certPath)
|
||||
{
|
||||
m_certs.insert(certPath);
|
||||
}
|
||||
|
||||
const std::unordered_set<std::string>&
|
||||
getIdCerts() const
|
||||
{
|
||||
return m_certs;
|
||||
}
|
||||
|
||||
const ndn::KeyChain&
|
||||
getKeyChain() const
|
||||
{
|
||||
return m_keyChain;
|
||||
}
|
||||
|
||||
std::optional<ndn::security::Certificate>
|
||||
initializeKey();
|
||||
|
||||
void
|
||||
loadCertToValidator(const ndn::security::Certificate& cert);
|
||||
|
||||
/*! \brief Dump the current state of all attributes to the log.
|
||||
*/
|
||||
void
|
||||
writeLog();
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
std::string m_confFileName;
|
||||
std::string m_confFileNameDynamic;
|
||||
|
||||
private:
|
||||
ndn::Name m_routerName;
|
||||
ndn::Name m_siteName;
|
||||
ndn::Name m_network;
|
||||
|
||||
ndn::Name m_routerPrefix;
|
||||
ndn::Name m_lsaRouterPrefix;
|
||||
ndn::Name m_syncUserPrefix;
|
||||
|
||||
ndn::Name m_chronosyncPrefix;
|
||||
ndn::Name m_syncPrefix;
|
||||
ndn::Name m_lsaPrefix;
|
||||
|
||||
uint32_t m_lsaRefreshTime;
|
||||
|
||||
uint32_t m_adjLsaBuildInterval;
|
||||
uint32_t m_firstHelloInterval;
|
||||
uint32_t m_routingCalcInterval;
|
||||
|
||||
uint32_t m_faceDatasetFetchTries;
|
||||
@@ -440,7 +511,6 @@ private:
|
||||
|
||||
ndn::time::seconds m_lsaInterestLifetime;
|
||||
uint32_t m_routerDeadInterval;
|
||||
std::string m_logLevel;
|
||||
|
||||
uint32_t m_interestRetryNumber;
|
||||
uint32_t m_interestResendTime;
|
||||
@@ -453,11 +523,23 @@ private:
|
||||
|
||||
uint32_t m_maxFacesPerPrefix;
|
||||
|
||||
std::string m_seqFileDir;
|
||||
std::string m_stateFileDir;
|
||||
|
||||
ndn::time::milliseconds m_syncInterestLifetime;
|
||||
|
||||
SyncProtocol m_syncProtocol = SyncProtocol::PSYNC;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
static const uint64_t SYNC_VERSION;
|
||||
// must be incremented when breaking changes are made to sync
|
||||
static constexpr uint64_t SYNC_VERSION = 11;
|
||||
|
||||
AdjacencyList m_adjl;
|
||||
NamePrefixList m_npl;
|
||||
ndn::security::ValidatorConfig m_validator;
|
||||
ndn::security::ValidatorConfig m_prefixUpdateValidator;
|
||||
ndn::security::SigningInfo m_signingInfo;
|
||||
std::unordered_set<std::string> m_certs;
|
||||
ndn::KeyChain& m_keyChain;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
+114
-94
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,76 +16,95 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
#include "hello-protocol.hpp"
|
||||
*/
|
||||
|
||||
#include "hello-protocol.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
|
||||
#include <ndn-cxx/encoding/nfd-constants.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
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)
|
||||
HelloProtocol::HelloProtocol(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
ConfParameter& confParam, RoutingTable& routingTable,
|
||||
Lsdb& lsdb)
|
||||
: m_face(face)
|
||||
, m_scheduler(m_face.getIoContext())
|
||||
, m_keyChain(keyChain)
|
||||
, m_signingInfo(confParam.getSigningInfo())
|
||||
, m_confParam(confParam)
|
||||
, m_routingTable(routingTable)
|
||||
, m_lsdb(lsdb)
|
||||
, m_adjacencyList(m_confParam.getAdjacencyList())
|
||||
{
|
||||
ndn::Name name(m_confParam.getRouterPrefix());
|
||||
name.append(NLSR_COMPONENT);
|
||||
name.append(INFO_COMPONENT);
|
||||
|
||||
NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
|
||||
|
||||
m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(false),
|
||||
[this] (const auto& name, const auto& interest) {
|
||||
processInterest(name, interest);
|
||||
},
|
||||
[] (const auto& name) {
|
||||
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
|
||||
},
|
||||
[] (const auto& name, const auto& resp) {
|
||||
NLSR_LOG_ERROR("Failed to register prefix " << name);
|
||||
NDN_THROW(std::runtime_error("Failed to register hello prefix: " + resp));
|
||||
},
|
||||
m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Expressing Interest :" << interestName);
|
||||
ndn::Interest i(interestName);
|
||||
i.setInterestLifetime(ndn::time::seconds(seconds));
|
||||
i.setMustBeFresh(true);
|
||||
m_nlsr.getNlsrFace().expressInterest(i,
|
||||
std::bind(&HelloProtocol::onContent,
|
||||
this,
|
||||
_1, _2),
|
||||
std::bind(&HelloProtocol::processInterestTimedOut, // Nack
|
||||
this, _1),
|
||||
std::bind(&HelloProtocol::processInterestTimedOut,
|
||||
this, _1));
|
||||
NLSR_LOG_DEBUG("Expressing Interest: " << interestName);
|
||||
ndn::Interest interest(interestName);
|
||||
interest.setInterestLifetime(ndn::time::seconds(seconds));
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setCanBePrefix(true);
|
||||
m_face.expressInterest(interest,
|
||||
std::bind(&HelloProtocol::onContent, this, _1, _2),
|
||||
[this, seconds] (const auto& interest, const auto& nack) {
|
||||
NDN_LOG_TRACE("Received Nack with reason: " << nack.getReason());
|
||||
NDN_LOG_TRACE("Will treat as timeout in " << 2 * seconds << " seconds");
|
||||
m_scheduler.schedule(ndn::time::seconds(2 * seconds),
|
||||
[this, interest] { processInterestTimedOut(interest); });
|
||||
},
|
||||
std::bind(&HelloProtocol::processInterestTimedOut, this, _1));
|
||||
|
||||
// increment SENT_HELLO_INTEREST
|
||||
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_INTEREST);
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::sendScheduledInterest(uint32_t seconds)
|
||||
HelloProtocol::sendHelloInterest(const ndn::Name& neighbor)
|
||||
{
|
||||
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>
|
||||
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());
|
||||
NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
|
||||
}
|
||||
auto adjacent = m_adjacencyList.findAdjacent(neighbor);
|
||||
if (adjacent == m_adjacencyList.end()) {
|
||||
return;
|
||||
}
|
||||
scheduleInterest(m_nlsr.getConfParameter().getInfoInterestInterval());
|
||||
}
|
||||
|
||||
void
|
||||
HelloProtocol::scheduleInterest(uint32_t seconds)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Scheduling HELLO Interests in " << ndn::time::seconds(seconds));
|
||||
// If this adjacency has a Face, just proceed as usual.
|
||||
if(adjacent->getFaceId() != 0) {
|
||||
// interest name: /<neighbor>/NLSR/INFO/<router>
|
||||
ndn::Name interestName = adjacent->getName() ;
|
||||
interestName.append(NLSR_COMPONENT);
|
||||
interestName.append(INFO_COMPONENT);
|
||||
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
|
||||
expressInterest(interestName, m_confParam.getInterestResendTime());
|
||||
NLSR_LOG_DEBUG("Sending HELLO interest: " << interestName);
|
||||
}
|
||||
|
||||
m_scheduler.scheduleEvent(ndn::time::seconds(seconds),
|
||||
std::bind(&HelloProtocol::sendScheduledInterest, this, seconds));
|
||||
m_scheduler.schedule(ndn::time::seconds(m_confParam.getInfoInterestInterval()),
|
||||
[this, neighbor] { sendHelloInterest(neighbor); });
|
||||
}
|
||||
|
||||
void
|
||||
@@ -98,32 +117,32 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
// increment RCV_HELLO_INTEREST
|
||||
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_INTEREST);
|
||||
|
||||
NLSR_LOG_DEBUG("Interest Received for Name: " << interestName);
|
||||
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");
|
||||
NLSR_LOG_DEBUG("INFO_COMPONENT not found or Interest Name " << interestName
|
||||
<< " does not match expression");
|
||||
return;
|
||||
}
|
||||
|
||||
ndn::Name neighbor;
|
||||
neighbor.wireDecode(interestName.get(-1).blockFromValue());
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
if (m_nlsr.getAdjacencyList().isNeighbor(neighbor)) {
|
||||
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
|
||||
if (m_adjacencyList.isNeighbor(neighbor)) {
|
||||
auto 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());
|
||||
data->setFreshnessPeriod(10_s);
|
||||
data->setContent(ndn::make_span(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.data()),
|
||||
INFO_COMPONENT.size()));
|
||||
|
||||
m_nlsr.getKeyChain().sign(*data, m_nlsr.getSigningInfo());
|
||||
m_keyChain.sign(*data, m_signingInfo);
|
||||
|
||||
NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
|
||||
|
||||
m_nlsr.getNlsrFace().put(*data);
|
||||
m_face.put(*data);
|
||||
// increment SENT_HELLO_DATA
|
||||
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
|
||||
|
||||
auto adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
|
||||
auto adjacent = m_adjacencyList.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.
|
||||
@@ -132,9 +151,8 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
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());
|
||||
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
|
||||
expressInterest(interestName, m_confParam.getInterestResendTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,50 +169,51 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
|
||||
}
|
||||
ndn::Name neighbor = interestName.getPrefix(-3);
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
m_nlsr.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
|
||||
m_adjacencyList.incrementTimedOutInterestCount(neighbor);
|
||||
|
||||
Adjacent::Status status = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
|
||||
Adjacent::Status status = m_adjacencyList.getStatusOfNeighbor(neighbor);
|
||||
|
||||
uint32_t infoIntTimedOutCount =
|
||||
m_nlsr.getAdjacencyList().getTimedOutInterestCount(neighbor);
|
||||
uint32_t infoIntTimedOutCount = m_adjacencyList.getTimedOutInterestCount(neighbor);
|
||||
NLSR_LOG_DEBUG("Status: " << status);
|
||||
NLSR_LOG_DEBUG("Info Interest Timed out: " << infoIntTimedOutCount);
|
||||
if (infoIntTimedOutCount < m_nlsr.getConfParameter().getInterestRetryNumber()) {
|
||||
if (infoIntTimedOutCount < m_confParam.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());
|
||||
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
|
||||
NLSR_LOG_DEBUG("Resending interest: " << interestName);
|
||||
expressInterest(interestName,
|
||||
m_nlsr.getConfParameter().getInterestResendTime());
|
||||
expressInterest(interestName, m_confParam.getInterestResendTime());
|
||||
}
|
||||
else if ((status == Adjacent::STATUS_ACTIVE) &&
|
||||
(infoIntTimedOutCount == m_nlsr.getConfParameter().getInterestRetryNumber())) {
|
||||
m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_INACTIVE);
|
||||
else if (status == Adjacent::STATUS_ACTIVE) {
|
||||
m_adjacencyList.setStatusOfNeighbor(neighbor, Adjacent::STATUS_INACTIVE);
|
||||
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor << " status changed to INACTIVE");
|
||||
|
||||
m_nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_routingTable.scheduleRoutingTableCalculation();
|
||||
}
|
||||
else {
|
||||
m_lsdb.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.
|
||||
// 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)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Received data for INFO(name): " << data.getName());
|
||||
if (data.getSignature().hasKeyLocator()) {
|
||||
if (data.getSignature().getKeyLocator().getType() == ndn::KeyLocator::KeyLocator_Name) {
|
||||
NLSR_LOG_DEBUG("Data signed with: " << data.getSignature().getKeyLocator().getName());
|
||||
}
|
||||
auto kl = data.getKeyLocator();
|
||||
if (kl && kl->getType() == ndn::tlv::Name) {
|
||||
NLSR_LOG_DEBUG("Data signed with: " << kl->getName());
|
||||
}
|
||||
m_nlsr.getValidator().validate(data,
|
||||
std::bind(&HelloProtocol::onContentValidated, this, _1),
|
||||
std::bind(&HelloProtocol::onContentValidationFailed,
|
||||
this, _1, _2));
|
||||
m_confParam.getValidator().validate(data,
|
||||
std::bind(&HelloProtocol::onContentValidated, this, _1),
|
||||
std::bind(&HelloProtocol::onContentValidationFailed,
|
||||
this, _1, _2));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -207,21 +226,22 @@ HelloProtocol::onContentValidated(const ndn::Data& data)
|
||||
if (dataName.get(-3).toUri() == INFO_COMPONENT) {
|
||||
ndn::Name neighbor = dataName.getPrefix(-4);
|
||||
|
||||
Adjacent::Status oldStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
|
||||
m_nlsr.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_ACTIVE);
|
||||
m_nlsr.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
|
||||
Adjacent::Status newStatus = m_nlsr.getAdjacencyList().getStatusOfNeighbor(neighbor);
|
||||
Adjacent::Status oldStatus = m_adjacencyList.getStatusOfNeighbor(neighbor);
|
||||
m_adjacencyList.setStatusOfNeighbor(neighbor, Adjacent::STATUS_ACTIVE);
|
||||
m_adjacencyList.setTimedOutInterestCount(neighbor, 0);
|
||||
Adjacent::Status newStatus = m_adjacencyList.getStatusOfNeighbor(neighbor);
|
||||
|
||||
NLSR_LOG_DEBUG("Neighbor : " << neighbor);
|
||||
NLSR_LOG_DEBUG("Old Status: " << oldStatus << " New Status: " << newStatus);
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
NLSR_LOG_DEBUG("Old Status: " << oldStatus << ", New Status: " << newStatus);
|
||||
// change in Adjacency list
|
||||
if ((oldStatus - newStatus) != 0) {
|
||||
if (m_nlsr.getConfParameter().getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_nlsr.getRoutingTable().scheduleRoutingTableCalculation(m_nlsr);
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_routingTable.scheduleRoutingTableCalculation();
|
||||
}
|
||||
else {
|
||||
m_nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
m_lsdb.scheduleAdjLsaBuild();
|
||||
}
|
||||
onInitialHelloDataValidated(neighbor);
|
||||
}
|
||||
}
|
||||
// increment RCV_HELLO_DATA
|
||||
@@ -230,9 +250,9 @@ HelloProtocol::onContentValidated(const ndn::Data& data)
|
||||
|
||||
void
|
||||
HelloProtocol::onContentValidationFailed(const ndn::Data& data,
|
||||
const ndn::security::v2::ValidationError& ve)
|
||||
const ndn::security::ValidationError& ve)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Validation Error: " << ve);
|
||||
NLSR_LOG_DEBUG("Validation error: " << ve);
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+28
-68
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,41 +17,29 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_HELLO_PROTOCOL_HPP
|
||||
#define NLSR_HELLO_PROTOCOL_HPP
|
||||
|
||||
#include "conf-parameter.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "route/routing-table.hpp"
|
||||
#include "statistics.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
|
||||
#include <ndn-cxx/security/validation-error.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
#include <ndn-cxx/security/v2/validation-error.hpp>
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class Nlsr;
|
||||
|
||||
class HelloProtocol
|
||||
{
|
||||
public:
|
||||
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);
|
||||
HelloProtocol(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam,
|
||||
RoutingTable& routingTable, Lsdb& lsdb);
|
||||
|
||||
/*! \brief Sends a Hello Interest packet.
|
||||
*
|
||||
@@ -68,19 +56,15 @@ public:
|
||||
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.
|
||||
* creates and sends a Hello Interest to the given adjacent.
|
||||
*
|
||||
* \param neighbor the name of the neighbor
|
||||
*/
|
||||
void
|
||||
sendScheduledInterest(uint32_t seconds);
|
||||
sendHelloInterest(const ndn::Name& neighbor);
|
||||
|
||||
/*! \brief Processes a Hello Interest from a neighbor.
|
||||
*
|
||||
@@ -99,7 +83,7 @@ public:
|
||||
void
|
||||
processInterest(const ndn::Name& name, const ndn::Interest& interest);
|
||||
|
||||
ndn::util::signal::Signal<HelloProtocol, Statistics::PacketType> hpIncrementSignal;
|
||||
ndn::signal::Signal<HelloProtocol, Statistics::PacketType> hpIncrementSignal;
|
||||
|
||||
private:
|
||||
/*! \brief Try to contact a neighbor via Hello protocol again
|
||||
@@ -136,47 +120,23 @@ private:
|
||||
*/
|
||||
void
|
||||
onContentValidationFailed(const ndn::Data& data,
|
||||
const ndn::security::v2::ValidationError& ve);
|
||||
const ndn::security::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);
|
||||
public:
|
||||
static inline const std::string INFO_COMPONENT{"INFO"};
|
||||
static inline const std::string NLSR_COMPONENT{"nlsr"};
|
||||
|
||||
/*! \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);
|
||||
ndn::signal::Signal<HelloProtocol, const ndn::Name&> onInitialHelloDataValidated;
|
||||
|
||||
/*! \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);
|
||||
private:
|
||||
Nlsr& m_nlsr;
|
||||
ndn::Scheduler& m_scheduler;
|
||||
|
||||
static const std::string INFO_COMPONENT;
|
||||
static const std::string NLSR_COMPONENT;
|
||||
ndn::Face& m_face;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ndn::security::KeyChain& m_keyChain;
|
||||
const ndn::security::SigningInfo& m_signingInfo;
|
||||
ConfParameter& m_confParam;
|
||||
RoutingTable& m_routingTable;
|
||||
Lsdb& m_lsdb;
|
||||
AdjacencyList& m_adjacencyList;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "lsa-segment-storage.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(LsaSegmentStorage);
|
||||
|
||||
LsaSegmentStorage::LsaSegmentStorage(ndn::Scheduler& scheduler)
|
||||
: m_scheduler(scheduler)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LsaSegmentStorage::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
|
||||
{
|
||||
fetcher.afterSegmentValidated.connect(std::bind(&LsaSegmentStorage::afterFetcherSignalEmitted,
|
||||
this, _1));
|
||||
}
|
||||
|
||||
const ndn::Data*
|
||||
LsaSegmentStorage::getLsaSegment(const ndn::Interest& interest)
|
||||
{
|
||||
ndn::Name lsaSegmentsKey = interest.getName();
|
||||
|
||||
// If this is the first interest then it does not contain the segment number,
|
||||
// so need to append zero segment component at the end to match with the data
|
||||
if (lsaSegmentsKey.size() > 0) {
|
||||
if (!lsaSegmentsKey.get(-1).isSegment()) {
|
||||
lsaSegmentsKey.appendSegment(0);
|
||||
}
|
||||
|
||||
auto it = m_lsaSegments.find(lsaSegmentsKey);
|
||||
if (it == m_lsaSegments.end()) {
|
||||
NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " cannot be found in the lsa storage");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " is in the storage.");
|
||||
return &(it->second);
|
||||
}
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_ERROR("Received interest has empty name.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LsaSegmentStorage::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
|
||||
{
|
||||
NLSR_LOG_TRACE("Received a LSA segment: " << lsaSegment.getName());
|
||||
|
||||
// lsaSegmentName is /<router-prefix>/<LS type>/<sequence no.>/<version no.>/<segment no.>
|
||||
auto lsaSegmentName = lsaSegment.getName();
|
||||
|
||||
if (lsaSegmentName.size() > 0) {
|
||||
// lsaSegmentsKey is /<router-prefix>/<LS type>/<sequence no.>/<segment no.>
|
||||
ndn::Name lsaSegmentsKey(lsaSegmentName.getPrefix(lsaSegmentName.size() - 2));
|
||||
lsaSegmentsKey.append(lsaSegmentName.get(-1));
|
||||
|
||||
// No need to store same LSA multiple time
|
||||
if (m_lsaSegments.find(lsaSegmentsKey) == m_lsaSegments.end()) {
|
||||
NLSR_LOG_TRACE("Received LSA segment is new. Storing it in the storage.\n"
|
||||
<< " LSA data name: " << lsaSegmentName);
|
||||
|
||||
// Delete the same LSA with lower sequence number
|
||||
deleteOldLsas(lsaSegmentName);
|
||||
|
||||
m_lsaSegments[lsaSegmentsKey] = lsaSegment;
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_TRACE("The received segment is already in the storage.");
|
||||
}
|
||||
|
||||
std::string content(reinterpret_cast<const char*>(lsaSegment.getContent().value()),
|
||||
lsaSegment.getContent().value_size());
|
||||
|
||||
ndn::time::seconds expirationTime(LSA_REFRESH_TIME_DEFAULT);
|
||||
|
||||
std::vector<std::string> options;
|
||||
boost::split(options, content, boost::is_any_of("|"));
|
||||
|
||||
try {
|
||||
expirationTime = ndn::time::duration_cast<ndn::time::seconds>
|
||||
(ndn::time::fromIsoString(options.at(3)) - ndn::time::system_clock::now());
|
||||
} catch (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Cannot extract expiration time from LSA content: " << e.what());
|
||||
}
|
||||
|
||||
// schedule the segment deletion
|
||||
scheduleLsaSegmentDeletion(lsaSegmentsKey, expirationTime);
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_ERROR("The received LSA segment has empty name.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LsaSegmentStorage::deleteOldLsas(const ndn::Name& newLsaName)
|
||||
{
|
||||
auto newLsaKey = newLsaName.getPrefix(newLsaName.size() - 3);
|
||||
auto newSeqNo = newLsaName.get(-3).toNumber();
|
||||
|
||||
std::vector<decltype(m_lsaSegments)::key_type> lsaToDelete;
|
||||
|
||||
for (const auto& segment : m_lsaSegments) {
|
||||
ndn::Name segmentKey = segment.first;
|
||||
auto oldSeqNo = segmentKey.get(-2).toNumber();
|
||||
auto existingLsaKey = segmentKey.getPrefix(segmentKey.size() - 2);
|
||||
|
||||
if (newLsaKey == existingLsaKey) {
|
||||
if (newSeqNo > oldSeqNo) { // in the key the second last component is the sequence number
|
||||
NLSR_LOG_TRACE("Outdated LSA: " << segmentKey << " with seq no: " <<
|
||||
oldSeqNo << " is deleted.");
|
||||
lsaToDelete.push_back(segmentKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& segmentKey : lsaToDelete) {
|
||||
m_lsaSegments.erase(segmentKey);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LsaSegmentStorage::scheduleLsaSegmentDeletion(const ndn::Name& lsaSegmentsKey,
|
||||
ndn::time::seconds expirationTime)
|
||||
{
|
||||
NLSR_LOG_TRACE("Scheduling LSA segment deletion for "
|
||||
<< lsaSegmentsKey << " in: " << expirationTime);
|
||||
m_scheduler.scheduleEvent(expirationTime,
|
||||
[lsaSegmentsKey, this] {
|
||||
m_lsaSegments.erase(lsaSegmentsKey);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,85 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef NLSR_LSA_SEGMENT_STORAGE_HPP
|
||||
#define NLSR_LSA_SEGMENT_STORAGE_HPP
|
||||
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <ndn-cxx/util/segment-fetcher.hpp>
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class LsaSegmentStorage
|
||||
{
|
||||
public:
|
||||
LsaSegmentStorage(ndn::Scheduler& scheduler);
|
||||
|
||||
/*! \brief Get connected to the signal emitted by SegmentFetcher
|
||||
* \param fetcher The SegmentFetcher to whose signal LsaSegmentStorage will subscribe to.
|
||||
*/
|
||||
void
|
||||
connectToFetcher(ndn::util::SegmentFetcher& fetcher);
|
||||
|
||||
/*! \brief Returns an LSA segment for an interest from LsaSegmentStorage
|
||||
* \param interest Interest corresponding to the returned LSA segment.
|
||||
*/
|
||||
const ndn::Data*
|
||||
getLsaSegment(const ndn::Interest& interest);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Callback when SegmentFetcher retrieves a segment.
|
||||
*/
|
||||
void
|
||||
afterFetcherSignalEmitted(const ndn::Data& lsaSegment);
|
||||
|
||||
private:
|
||||
/*! \brief Given an LSA name check whether Data for the same name exists in the
|
||||
* LsaSegmentStorage. If the matched LSA data are of a lower sequence number,
|
||||
* then remove them from LsaSegmentStorage.
|
||||
* \param newLsaName Name of the LSA that will be matched against
|
||||
*/
|
||||
void
|
||||
deleteOldLsas(const ndn::Name& newLsaName);
|
||||
|
||||
/*! \brief Schedules the deletion of a LSA data given the segmentKey
|
||||
*/
|
||||
void
|
||||
scheduleLsaSegmentDeletion(const ndn::Name& segmentKey, ndn::time::seconds expirationTime);
|
||||
|
||||
|
||||
private:
|
||||
ndn::Scheduler& m_scheduler;
|
||||
|
||||
// Key: /<router-prefix>/<LS type>/<sequence no.>/<segment no.>
|
||||
// Value: corresponding LSA data packet
|
||||
// Data name: /<router-prefix>/<LS type>/<sequence no.>/<version no.>/<segment no.>
|
||||
std::unordered_map<ndn::Name, ndn::Data> m_lsaSegments;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_LSA_SEGMENT_STORAGE_HPP
|
||||
-394
@@ -1,394 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#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/algorithm/string.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(Lsa);
|
||||
|
||||
std::string
|
||||
Lsa::getData() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
|
||||
<< ndn::time::toIsoString(m_expirationTimePoint) << "|";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
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_lsSeqNo = lsn;
|
||||
m_expirationTimePoint = lt;
|
||||
for (const auto& name : npl.getNames()) {
|
||||
addName(name);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
NameLsa::serialize() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << getData() << m_npl.size();
|
||||
for (const auto& name : m_npl.getNames()) {
|
||||
os << "|" << name;
|
||||
}
|
||||
os << "|";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
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();
|
||||
|
||||
try {
|
||||
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 (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NameLsa::isEqualContent(const NameLsa& other) const
|
||||
{
|
||||
return m_npl == other.getNpl();
|
||||
}
|
||||
|
||||
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, std::vector<double> theta)
|
||||
{
|
||||
m_origRouter = origR;
|
||||
m_lsSeqNo = lsn;
|
||||
m_expirationTimePoint = lt;
|
||||
m_corRad = r;
|
||||
m_angles = theta;
|
||||
}
|
||||
|
||||
bool
|
||||
CoordinateLsa::isEqualContent(const CoordinateLsa& clsa) const
|
||||
{
|
||||
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::string
|
||||
CoordinateLsa::serialize() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << getData() << m_corRad << "|" << m_angles.size() << "|";
|
||||
for (const auto& angle: m_angles) {
|
||||
os << angle << "|";
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
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();
|
||||
|
||||
try {
|
||||
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 (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CoordinateLsa::writeLog() const
|
||||
{
|
||||
NLSR_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
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_lsSeqNo = lsn;
|
||||
m_expirationTimePoint = lt;
|
||||
m_noLink = nl;
|
||||
std::list<Adjacent> al = adl.getAdjList();
|
||||
for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
|
||||
if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
addAdjacent((*it));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AdjLsa::isEqualContent(const AdjLsa& alsa) const
|
||||
{
|
||||
return m_adl == alsa.getAdl();
|
||||
}
|
||||
|
||||
std::string
|
||||
AdjLsa::serialize() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << getData() << m_adl.size();
|
||||
for (const auto& adjacent : m_adl.getAdjList()) {
|
||||
os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
|
||||
<< "|" << adjacent.getLinkCost();
|
||||
}
|
||||
os << "|";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
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();
|
||||
|
||||
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, ndn::FaceUri(connectingFaceUri), linkCost,
|
||||
Adjacent::STATUS_INACTIVE, 0, 0);
|
||||
addAdjacent(adjacent);
|
||||
}
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdjLsa::removeNptEntries(Nlsr& pnlsr)
|
||||
{
|
||||
if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
|
||||
pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AdjLsa::writeLog() const
|
||||
{
|
||||
NLSR_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
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
|
||||
-430
@@ -1,430 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2018, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_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 <boost/tokenizer.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class Nlsr;
|
||||
|
||||
class Lsa
|
||||
{
|
||||
public:
|
||||
enum class Type {
|
||||
ADJACENCY,
|
||||
COORDINATE,
|
||||
NAME,
|
||||
BASE,
|
||||
MOCK
|
||||
};
|
||||
|
||||
Lsa()
|
||||
: m_origRouter()
|
||||
, m_lsSeqNo()
|
||||
, m_expirationTimePoint()
|
||||
, m_expiringEventId()
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~Lsa() = default;
|
||||
|
||||
virtual Type
|
||||
getType() const
|
||||
{
|
||||
return Type::BASE;
|
||||
}
|
||||
|
||||
void
|
||||
setLsSeqNo(uint32_t lsn)
|
||||
{
|
||||
m_lsSeqNo = lsn;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
getLsSeqNo() const
|
||||
{
|
||||
return m_lsSeqNo;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getOrigRouter() const
|
||||
{
|
||||
return m_origRouter;
|
||||
}
|
||||
|
||||
void
|
||||
setOrigRouter(const ndn::Name& org)
|
||||
{
|
||||
m_origRouter = org;
|
||||
}
|
||||
|
||||
const ndn::time::system_clock::TimePoint&
|
||||
getExpirationTimePoint() const
|
||||
{
|
||||
return m_expirationTimePoint;
|
||||
}
|
||||
|
||||
void
|
||||
setExpirationTimePoint(const ndn::time::system_clock::TimePoint& lt)
|
||||
{
|
||||
m_expirationTimePoint = lt;
|
||||
}
|
||||
|
||||
void
|
||||
setExpiringEventId(const ndn::EventId leei)
|
||||
{
|
||||
m_expiringEventId = leei;
|
||||
}
|
||||
|
||||
ndn::EventId
|
||||
getExpiringEventId() const
|
||||
{
|
||||
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;
|
||||
uint32_t m_lsSeqNo;
|
||||
ndn::time::system_clock::TimePoint m_expirationTimePoint;
|
||||
ndn::EventId m_expiringEventId;
|
||||
};
|
||||
|
||||
class NameLsa : public Lsa
|
||||
{
|
||||
public:
|
||||
NameLsa()
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_npl.insert(name);
|
||||
}
|
||||
|
||||
void
|
||||
removeName(const ndn::Name& name)
|
||||
{
|
||||
m_npl.remove(name);
|
||||
}
|
||||
|
||||
/*! \brief Initializes this LSA object with content's data.
|
||||
|
||||
\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
|
||||
isEqualContent(const NameLsa& other) const;
|
||||
|
||||
void
|
||||
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;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const NameLsa& lsa);
|
||||
};
|
||||
|
||||
class AdjLsa : public Lsa
|
||||
{
|
||||
public:
|
||||
typedef AdjacencyList::const_iterator const_iterator;
|
||||
|
||||
AdjLsa()
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*! \brief Initializes this adj. LSA from the supplied content.
|
||||
|
||||
\param content The content that this LSA is to have, formatted
|
||||
according to getData().
|
||||
*/
|
||||
bool
|
||||
deserialize(const std::string& content) noexcept override;
|
||||
|
||||
uint32_t
|
||||
getNoLink()
|
||||
{
|
||||
return m_noLink;
|
||||
}
|
||||
|
||||
bool
|
||||
isEqualContent(const AdjLsa& alsa) const;
|
||||
|
||||
/*! \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);
|
||||
|
||||
void
|
||||
removeNptEntries(Nlsr& pnlsr);
|
||||
|
||||
void
|
||||
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;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& lsa);
|
||||
};
|
||||
|
||||
class CoordinateLsa : public Lsa
|
||||
{
|
||||
public:
|
||||
CoordinateLsa()
|
||||
: m_corRad(0)
|
||||
{
|
||||
}
|
||||
|
||||
CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
|
||||
const ndn::time::system_clock::TimePoint& lt,
|
||||
double r, std::vector<double> theta);
|
||||
|
||||
Lsa::Type
|
||||
getType() const override
|
||||
{
|
||||
return Lsa::Type::COORDINATE;
|
||||
}
|
||||
|
||||
/*! \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
|
||||
deserialize(const std::string& content) noexcept override;
|
||||
|
||||
double
|
||||
getCorRadius() const
|
||||
{
|
||||
return m_corRad;
|
||||
}
|
||||
|
||||
void
|
||||
setCorRadius(double cr)
|
||||
{
|
||||
m_corRad = cr;
|
||||
}
|
||||
|
||||
const std::vector<double>
|
||||
getCorTheta() const
|
||||
{
|
||||
return m_angles;
|
||||
}
|
||||
|
||||
void
|
||||
setCorTheta(std::vector<double> ct)
|
||||
{
|
||||
m_angles = ct;
|
||||
}
|
||||
|
||||
bool
|
||||
isEqualContent(const CoordinateLsa& clsa) const;
|
||||
|
||||
void
|
||||
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;
|
||||
std::vector<double> m_angles;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const CoordinateLsa& lsa);
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& lsa);
|
||||
|
||||
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
|
||||
@@ -0,0 +1,162 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "adj-lsa.hpp"
|
||||
#include "tlv-nlsr.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
AdjLsa::AdjLsa(const ndn::Name& originRouter, uint64_t seqNo,
|
||||
const ndn::time::system_clock::time_point& timepoint,
|
||||
uint32_t noLink, AdjacencyList& adl)
|
||||
: Lsa(originRouter, seqNo, timepoint)
|
||||
, m_noLink(noLink)
|
||||
{
|
||||
for (const auto& adjacent : adl.getAdjList()) {
|
||||
if (adjacent.getStatus() == Adjacent::STATUS_ACTIVE) {
|
||||
addAdjacent(adjacent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AdjLsa::AdjLsa(const ndn::Block& block)
|
||||
{
|
||||
wireDecode(block);
|
||||
}
|
||||
|
||||
bool
|
||||
AdjLsa::isEqualContent(const AdjLsa& alsa) const
|
||||
{
|
||||
return m_adl == alsa.getAdl();
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
AdjLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
auto list = m_adl.getAdjList();
|
||||
for (auto it = list.rbegin(); it != list.rend(); ++it) {
|
||||
totalLength += it->wireEncode(block);
|
||||
}
|
||||
|
||||
totalLength += Lsa::wireEncode(block);
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(nlsr::tlv::AdjacencyLsa);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
|
||||
|
||||
const ndn::Block&
|
||||
AdjLsa::wireEncode() const
|
||||
{
|
||||
if (m_wire.hasWire()) {
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
ndn::EncodingEstimator estimator;
|
||||
size_t estimatedSize = wireEncode(estimator);
|
||||
|
||||
ndn::EncodingBuffer buffer(estimatedSize, 0);
|
||||
wireEncode(buffer);
|
||||
|
||||
m_wire = buffer.block();
|
||||
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
void
|
||||
AdjLsa::wireDecode(const ndn::Block& wire)
|
||||
{
|
||||
m_wire = wire;
|
||||
|
||||
if (m_wire.type() != nlsr::tlv::AdjacencyLsa) {
|
||||
NDN_THROW(Error("AdjacencyLsa", m_wire.type()));
|
||||
}
|
||||
|
||||
m_wire.parse();
|
||||
|
||||
auto val = m_wire.elements_begin();
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
|
||||
Lsa::wireDecode(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Lsa field"));
|
||||
}
|
||||
|
||||
AdjacencyList adl;
|
||||
for (; val != m_wire.elements_end(); ++val) {
|
||||
if (val->type() == nlsr::tlv::Adjacency) {
|
||||
adl.insert(Adjacent(*val));
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Adjacency", val->type()));
|
||||
}
|
||||
}
|
||||
m_adl = adl;
|
||||
}
|
||||
|
||||
std::string
|
||||
AdjLsa::toString() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << getString();
|
||||
os << " Adjacent(s):\n";
|
||||
|
||||
int adjacencyIndex = 0;
|
||||
|
||||
for (const auto& adjacency : m_adl) {
|
||||
os << " Adjacent " << adjacencyIndex++
|
||||
<< ": (name=" << adjacency.getName()
|
||||
<< ", uri=" << adjacency.getFaceUri()
|
||||
<< ", cost=" << adjacency.getLinkCost() << ")\n";
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
|
||||
AdjLsa::update(const std::shared_ptr<Lsa>& lsa)
|
||||
{
|
||||
auto alsa = std::static_pointer_cast<AdjLsa>(lsa);
|
||||
if (!isEqualContent(*alsa)) {
|
||||
resetAdl();
|
||||
for (const auto& adjacent : alsa->getAdl()) {
|
||||
addAdjacent(adjacent);
|
||||
}
|
||||
return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
|
||||
}
|
||||
return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& lsa)
|
||||
{
|
||||
return os << lsa.toString();
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_LSA_ADJ_LSA_HPP
|
||||
#define NLSR_LSA_ADJ_LSA_HPP
|
||||
|
||||
#include "lsa.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "adjacency-list.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*!
|
||||
\brief Data abstraction for AdjLsa
|
||||
AdjacencyLsa := ADJACENCY-LSA-TYPE TLV-LENGTH
|
||||
Lsa
|
||||
Adjacency*
|
||||
|
||||
*/
|
||||
class AdjLsa : public Lsa
|
||||
{
|
||||
public:
|
||||
typedef AdjacencyList::const_iterator const_iterator;
|
||||
|
||||
AdjLsa() = default;
|
||||
|
||||
AdjLsa(const ndn::Name& originR, uint64_t seqNo,
|
||||
const ndn::time::system_clock::time_point& timepoint,
|
||||
uint32_t noLink, AdjacencyList& adl);
|
||||
|
||||
AdjLsa(const ndn::Block& block);
|
||||
|
||||
Lsa::Type
|
||||
getType() const override
|
||||
{
|
||||
return type();
|
||||
}
|
||||
|
||||
static constexpr Lsa::Type
|
||||
type()
|
||||
{
|
||||
return Lsa::Type::ADJACENCY;
|
||||
}
|
||||
|
||||
const AdjacencyList&
|
||||
getAdl() const
|
||||
{
|
||||
return m_adl;
|
||||
}
|
||||
|
||||
void
|
||||
resetAdl()
|
||||
{
|
||||
m_wire.reset();
|
||||
m_adl.reset();
|
||||
}
|
||||
|
||||
void
|
||||
addAdjacent(Adjacent adj)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_adl.insert(adj);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
getNoLink()
|
||||
{
|
||||
return m_noLink;
|
||||
}
|
||||
|
||||
bool
|
||||
isEqualContent(const AdjLsa& alsa) const;
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return m_adl.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return m_adl.end();
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(ndn::EncodingImpl<TAG>& block) const;
|
||||
|
||||
const ndn::Block&
|
||||
wireEncode() const override;
|
||||
|
||||
void
|
||||
wireDecode(const ndn::Block& wire);
|
||||
|
||||
std::string
|
||||
toString() const override;
|
||||
|
||||
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
|
||||
update(const std::shared_ptr<Lsa>& lsa) override;
|
||||
|
||||
private:
|
||||
uint32_t m_noLink;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
AdjacencyList m_adl;
|
||||
};
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& lsa);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_LSA_ADJ_LSA_HPP
|
||||
@@ -0,0 +1,175 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "coordinate-lsa.hpp"
|
||||
#include "tlv-nlsr.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
|
||||
const ndn::time::system_clock::time_point& timepoint,
|
||||
double radius, std::vector<double> angles)
|
||||
: Lsa(originRouter, seqNo, timepoint)
|
||||
, m_hyperbolicRadius(radius)
|
||||
, m_hyperbolicAngles(angles)
|
||||
{
|
||||
}
|
||||
|
||||
CoordinateLsa::CoordinateLsa(const ndn::Block& block)
|
||||
{
|
||||
wireDecode(block);
|
||||
}
|
||||
|
||||
bool
|
||||
CoordinateLsa::isEqualContent(const CoordinateLsa& clsa) const
|
||||
{
|
||||
if (clsa.getCorTheta().size() != m_hyperbolicAngles.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double> m_angles2 = clsa.getCorTheta();
|
||||
for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
|
||||
if (std::abs(m_hyperbolicAngles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (std::abs(m_hyperbolicRadius - clsa.getCorRadius()) <
|
||||
std::numeric_limits<double>::epsilon());
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
CoordinateLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
for (auto it = m_hyperbolicAngles.rbegin(); it != m_hyperbolicAngles.rend(); ++it) {
|
||||
totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicAngle, *it);
|
||||
}
|
||||
|
||||
totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::HyperbolicRadius, m_hyperbolicRadius);
|
||||
|
||||
totalLength += Lsa::wireEncode(block);
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(nlsr::tlv::CoordinateLsa);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
|
||||
|
||||
const ndn::Block&
|
||||
CoordinateLsa::wireEncode() const
|
||||
{
|
||||
if (m_wire.hasWire()) {
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
ndn::EncodingEstimator estimator;
|
||||
size_t estimatedSize = wireEncode(estimator);
|
||||
|
||||
ndn::EncodingBuffer buffer(estimatedSize, 0);
|
||||
wireEncode(buffer);
|
||||
|
||||
m_wire = buffer.block();
|
||||
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
void
|
||||
CoordinateLsa::wireDecode(const ndn::Block& wire)
|
||||
{
|
||||
m_wire = wire;
|
||||
|
||||
if (m_wire.type() != nlsr::tlv::CoordinateLsa) {
|
||||
NDN_THROW(Error("CoordinateLsa", m_wire.type()));
|
||||
}
|
||||
|
||||
m_wire.parse();
|
||||
|
||||
auto val = m_wire.elements_begin();
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
|
||||
Lsa::wireDecode(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Lsa field"));
|
||||
}
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::HyperbolicRadius) {
|
||||
m_hyperbolicRadius = ndn::encoding::readDouble(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required HyperbolicRadius field"));
|
||||
}
|
||||
|
||||
std::vector<double> angles;
|
||||
for (; val != m_wire.elements_end(); ++val) {
|
||||
if (val->type() == nlsr::tlv::HyperbolicAngle) {
|
||||
angles.push_back(ndn::encoding::readDouble(*val));
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required HyperbolicAngle field"));
|
||||
}
|
||||
}
|
||||
m_hyperbolicAngles = angles;
|
||||
}
|
||||
|
||||
std::string
|
||||
CoordinateLsa::toString() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << getString();
|
||||
os << " Hyperbolic Radius : " << m_hyperbolicRadius << "\n";
|
||||
int i = 0;
|
||||
for (const auto& value : m_hyperbolicAngles) {
|
||||
os << " Hyperbolic Theta " << i++ << " : " << value << "\n";
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
|
||||
CoordinateLsa::update(const std::shared_ptr<Lsa>& lsa)
|
||||
{
|
||||
auto clsa = std::static_pointer_cast<CoordinateLsa>(lsa);
|
||||
if (!isEqualContent(*clsa)) {
|
||||
m_hyperbolicRadius = clsa->getCorRadius();
|
||||
m_hyperbolicAngles.clear();
|
||||
for (const auto& angle : clsa->getCorTheta()) {
|
||||
m_hyperbolicAngles.push_back(angle);
|
||||
}
|
||||
return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
|
||||
}
|
||||
return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const CoordinateLsa& lsa)
|
||||
{
|
||||
return os << lsa.toString();
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -0,0 +1,116 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_LSA_COORDINATE_LSA_HPP
|
||||
#define NLSR_LSA_COORDINATE_LSA_HPP
|
||||
|
||||
#include "lsa.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*!
|
||||
\brief Data abstraction for CoordinateLsa
|
||||
CoordinateLsa := COORDINATE-LSA-TYPE TLV-LENGTH
|
||||
Lsa
|
||||
HyperbolicRadius
|
||||
HyperbolicAngle+
|
||||
*/
|
||||
class CoordinateLsa : public Lsa
|
||||
{
|
||||
public:
|
||||
CoordinateLsa() = default;
|
||||
|
||||
CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
|
||||
const ndn::time::system_clock::time_point& timepoint,
|
||||
double radius, std::vector<double> angles);
|
||||
|
||||
CoordinateLsa(const ndn::Block& block);
|
||||
|
||||
Lsa::Type
|
||||
getType() const override
|
||||
{
|
||||
return type();
|
||||
}
|
||||
|
||||
static constexpr Lsa::Type
|
||||
type()
|
||||
{
|
||||
return Lsa::Type::COORDINATE;
|
||||
}
|
||||
|
||||
double
|
||||
getCorRadius() const
|
||||
{
|
||||
return m_hyperbolicRadius;
|
||||
}
|
||||
|
||||
void
|
||||
setCorRadius(double cr)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_hyperbolicRadius = cr;
|
||||
}
|
||||
|
||||
const std::vector<double>
|
||||
getCorTheta() const
|
||||
{
|
||||
return m_hyperbolicAngles;
|
||||
}
|
||||
|
||||
void
|
||||
setCorTheta(std::vector<double> ct)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_hyperbolicAngles = ct;
|
||||
}
|
||||
|
||||
bool
|
||||
isEqualContent(const CoordinateLsa& clsa) const;
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(ndn::EncodingImpl<TAG>& block) const;
|
||||
|
||||
const ndn::Block&
|
||||
wireEncode() const override;
|
||||
|
||||
void
|
||||
wireDecode(const ndn::Block& wire);
|
||||
|
||||
std::string
|
||||
toString() const override;
|
||||
|
||||
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
|
||||
update(const std::shared_ptr<Lsa>& lsa) override;
|
||||
|
||||
private:
|
||||
double m_hyperbolicRadius = 0.0;
|
||||
std::vector<double> m_hyperbolicAngles;
|
||||
};
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const CoordinateLsa& lsa);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_LSA_COORDINATE_LSA_HPP
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "lsa.hpp"
|
||||
#include "tlv-nlsr.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
Lsa::Lsa(const ndn::Name& originRouter, uint64_t seqNo,
|
||||
ndn::time::system_clock::time_point expirationTimePoint)
|
||||
: m_originRouter(originRouter)
|
||||
, m_seqNo(seqNo)
|
||||
, m_expirationTimePoint(expirationTimePoint)
|
||||
{
|
||||
}
|
||||
|
||||
Lsa::Lsa(const Lsa& lsa)
|
||||
: m_originRouter(lsa.getOriginRouter())
|
||||
, m_seqNo(lsa.getSeqNo())
|
||||
, m_expirationTimePoint(lsa.getExpirationTimePoint())
|
||||
{
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
totalLength += prependStringBlock(encoder,
|
||||
nlsr::tlv::ExpirationTime,
|
||||
ndn::time::toString(m_expirationTimePoint));
|
||||
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, nlsr::tlv::SequenceNumber, m_seqNo);
|
||||
|
||||
totalLength += m_originRouter.wireEncode(encoder);
|
||||
|
||||
totalLength += encoder.prependVarNumber(totalLength);
|
||||
totalLength += encoder.prependVarNumber(nlsr::tlv::Lsa);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
|
||||
|
||||
void
|
||||
Lsa::wireDecode(const ndn::Block& wire)
|
||||
{
|
||||
m_originRouter.clear();
|
||||
m_seqNo = 0;
|
||||
|
||||
ndn::Block baseWire = wire;
|
||||
baseWire.parse();
|
||||
|
||||
auto val = baseWire.elements_begin();
|
||||
|
||||
if (val != baseWire.elements_end() && val->type() == ndn::tlv::Name) {
|
||||
m_originRouter.wireDecode(*val);
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("OriginRouter: Missing required Name field"));
|
||||
}
|
||||
|
||||
++val;
|
||||
|
||||
if (val != baseWire.elements_end() && val->type() == nlsr::tlv::SequenceNumber) {
|
||||
m_seqNo = ndn::readNonNegativeInteger(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required SequenceNumber field"));
|
||||
}
|
||||
|
||||
if (val != baseWire.elements_end() && val->type() == nlsr::tlv::ExpirationTime) {
|
||||
m_expirationTimePoint = ndn::time::fromString(readString(*val));
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required ExpirationTime field"));
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Lsa::Type& type)
|
||||
{
|
||||
switch (type) {
|
||||
case Lsa::Type::ADJACENCY:
|
||||
os << "ADJACENCY";
|
||||
break;
|
||||
case Lsa::Type::COORDINATE:
|
||||
os << "COORDINATE";
|
||||
break;
|
||||
case Lsa::Type::NAME:
|
||||
os << "NAME";
|
||||
break;
|
||||
default:
|
||||
os << "BASE";
|
||||
break;
|
||||
}
|
||||
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::getString() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
auto duration = m_expirationTimePoint - ndn::time::system_clock::now();
|
||||
os << " " << getType() << " LSA:\n"
|
||||
<< " Origin Router : " << m_originRouter << "\n"
|
||||
<< " Sequence Number : " << m_seqNo << "\n"
|
||||
<< " Expires in : " << ndn::time::duration_cast<ndn::time::milliseconds>(duration)
|
||||
<< "\n";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_LSA_LSA_HPP
|
||||
#define NLSR_LSA_LSA_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*!
|
||||
\brief Data abstraction for Lsa
|
||||
Lsa := LSA-TYPE TLV-LENGTH
|
||||
Name
|
||||
SequenceNumber
|
||||
ExpirationTimePoint
|
||||
*/
|
||||
class Lsa
|
||||
{
|
||||
public:
|
||||
class Error : public ndn::tlv::Error
|
||||
{
|
||||
public:
|
||||
using ndn::tlv::Error::Error;
|
||||
};
|
||||
|
||||
enum class Type {
|
||||
ADJACENCY,
|
||||
COORDINATE,
|
||||
NAME,
|
||||
BASE
|
||||
};
|
||||
|
||||
protected:
|
||||
Lsa(const ndn::Name& originRouter, uint64_t seqNo,
|
||||
ndn::time::system_clock::time_point expirationTimePoint);
|
||||
|
||||
Lsa() = default;
|
||||
|
||||
Lsa(const Lsa& lsa);
|
||||
|
||||
public:
|
||||
virtual
|
||||
~Lsa() = default;
|
||||
|
||||
virtual Type
|
||||
getType() const = 0;
|
||||
|
||||
void
|
||||
setSeqNo(uint64_t seqNo)
|
||||
{
|
||||
m_seqNo = seqNo;
|
||||
m_wire.reset();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getSeqNo() const
|
||||
{
|
||||
return m_seqNo;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getOriginRouter() const
|
||||
{
|
||||
return m_originRouter;
|
||||
}
|
||||
|
||||
ndn::Name
|
||||
getOriginRouterCopy() const
|
||||
{
|
||||
return m_originRouter;
|
||||
}
|
||||
|
||||
const ndn::time::system_clock::time_point&
|
||||
getExpirationTimePoint() const
|
||||
{
|
||||
return m_expirationTimePoint;
|
||||
}
|
||||
|
||||
void
|
||||
setExpirationTimePoint(const ndn::time::system_clock::time_point& lt)
|
||||
{
|
||||
m_expirationTimePoint = lt;
|
||||
m_wire.reset();
|
||||
}
|
||||
|
||||
void
|
||||
setExpiringEventId(ndn::scheduler::EventId eid)
|
||||
{
|
||||
m_expiringEventId = eid;
|
||||
}
|
||||
|
||||
/*! Get data common to all LSA types for printing purposes.
|
||||
*/
|
||||
virtual std::string
|
||||
toString() const = 0;
|
||||
|
||||
virtual std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
|
||||
update(const std::shared_ptr<Lsa>& lsa) = 0;
|
||||
|
||||
virtual const ndn::Block&
|
||||
wireEncode() const = 0;
|
||||
|
||||
protected:
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(ndn::EncodingImpl<TAG>& block) const;
|
||||
|
||||
void
|
||||
wireDecode(const ndn::Block& wire);
|
||||
|
||||
std::string
|
||||
getString() const;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
ndn::Name m_originRouter;
|
||||
uint64_t m_seqNo = 0;
|
||||
ndn::time::system_clock::time_point m_expirationTimePoint;
|
||||
ndn::scheduler::ScopedEventId m_expiringEventId;
|
||||
|
||||
mutable ndn::Block m_wire;
|
||||
};
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Lsa::Type& type);
|
||||
|
||||
std::istream&
|
||||
operator>>(std::istream& is, Lsa::Type& type);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_LSA_LSA_HPP
|
||||
@@ -0,0 +1,165 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "name-lsa.hpp"
|
||||
#include "tlv-nlsr.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
NameLsa::NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
|
||||
const ndn::time::system_clock::time_point& timepoint,
|
||||
const NamePrefixList& npl)
|
||||
: Lsa(originRouter, seqNo, timepoint)
|
||||
{
|
||||
for (const auto& name : npl.getNames()) {
|
||||
addName(name);
|
||||
}
|
||||
}
|
||||
|
||||
NameLsa::NameLsa(const ndn::Block& block)
|
||||
{
|
||||
wireDecode(block);
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
NameLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
auto names = m_npl.getNames();
|
||||
|
||||
for (auto it = names.rbegin(); it != names.rend(); ++it) {
|
||||
totalLength += it->wireEncode(block);
|
||||
}
|
||||
|
||||
totalLength += Lsa::wireEncode(block);
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(nlsr::tlv::NameLsa);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
|
||||
|
||||
const ndn::Block&
|
||||
NameLsa::wireEncode() const
|
||||
{
|
||||
if (m_wire.hasWire()) {
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
ndn::EncodingEstimator estimator;
|
||||
size_t estimatedSize = wireEncode(estimator);
|
||||
|
||||
ndn::EncodingBuffer buffer(estimatedSize, 0);
|
||||
wireEncode(buffer);
|
||||
|
||||
m_wire = buffer.block();
|
||||
|
||||
return m_wire;
|
||||
}
|
||||
|
||||
void
|
||||
NameLsa::wireDecode(const ndn::Block& wire)
|
||||
{
|
||||
m_wire = wire;
|
||||
|
||||
if (m_wire.type() != nlsr::tlv::NameLsa) {
|
||||
NDN_THROW(Error("NameLsa", m_wire.type()));
|
||||
}
|
||||
|
||||
m_wire.parse();
|
||||
|
||||
auto val = m_wire.elements_begin();
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Lsa) {
|
||||
Lsa::wireDecode(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Lsa field"));
|
||||
}
|
||||
|
||||
NamePrefixList npl;
|
||||
for (; val != m_wire.elements_end(); ++val) {
|
||||
if (val->type() == ndn::tlv::Name) {
|
||||
npl.insert(ndn::Name(*val));
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Name", val->type()));
|
||||
}
|
||||
}
|
||||
m_npl = npl;
|
||||
}
|
||||
|
||||
std::string
|
||||
NameLsa::toString() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << getString();
|
||||
os << " Names:\n";
|
||||
int i = 0;
|
||||
for (const auto& name : m_npl.getNames()) {
|
||||
os << " Name " << i++ << ": " << name << "\n";
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
|
||||
NameLsa::update(const std::shared_ptr<Lsa>& lsa)
|
||||
{
|
||||
auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
|
||||
bool updated = false;
|
||||
|
||||
// Obtain the set difference of the current and the incoming
|
||||
// name prefix sets, and add those.
|
||||
std::list<ndn::Name> newNames = nlsa->getNpl().getNames();
|
||||
std::list<ndn::Name> oldNames = m_npl.getNames();
|
||||
std::list<ndn::Name> namesToAdd;
|
||||
std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
|
||||
std::inserter(namesToAdd, namesToAdd.begin()));
|
||||
for (const auto& name : namesToAdd) {
|
||||
addName(name);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Also remove any names that are no longer being advertised.
|
||||
std::list<ndn::Name> namesToRemove;
|
||||
std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
|
||||
std::inserter(namesToRemove, namesToRemove.begin()));
|
||||
for (const auto& name : namesToRemove) {
|
||||
removeName(name);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
return {updated, namesToAdd, namesToRemove};
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NameLsa& lsa)
|
||||
{
|
||||
return os << lsa.toString();
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -0,0 +1,125 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2023, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_LSA_NAME_LSA_HPP
|
||||
#define NLSR_LSA_NAME_LSA_HPP
|
||||
|
||||
#include "lsa.hpp"
|
||||
#include "name-prefix-list.hpp"
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*!
|
||||
\brief Data abstraction for NameLsa
|
||||
NameLsa := NAME-LSA-TYPE TLV-LENGTH
|
||||
Lsa
|
||||
Name+
|
||||
*/
|
||||
class NameLsa : public Lsa, private boost::equality_comparable<NameLsa>
|
||||
{
|
||||
public:
|
||||
NameLsa() = default;
|
||||
|
||||
NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
|
||||
const ndn::time::system_clock::time_point& timepoint,
|
||||
const NamePrefixList& npl);
|
||||
|
||||
NameLsa(const ndn::Block& block);
|
||||
|
||||
Lsa::Type
|
||||
getType() const override
|
||||
{
|
||||
return type();
|
||||
}
|
||||
|
||||
static constexpr Lsa::Type
|
||||
type()
|
||||
{
|
||||
return Lsa::Type::NAME;
|
||||
}
|
||||
|
||||
NamePrefixList&
|
||||
getNpl()
|
||||
{
|
||||
return m_npl;
|
||||
}
|
||||
|
||||
const NamePrefixList&
|
||||
getNpl() const
|
||||
{
|
||||
return m_npl;
|
||||
}
|
||||
|
||||
void
|
||||
addName(const ndn::Name& name)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_npl.insert(name);
|
||||
}
|
||||
|
||||
void
|
||||
removeName(const ndn::Name& name)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_npl.erase(name);
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(ndn::EncodingImpl<TAG>& block) const;
|
||||
|
||||
const ndn::Block&
|
||||
wireEncode() const override;
|
||||
|
||||
void
|
||||
wireDecode(const ndn::Block& wire);
|
||||
|
||||
std::string
|
||||
toString() const override;
|
||||
|
||||
std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
|
||||
update(const std::shared_ptr<Lsa>& lsa) override;
|
||||
|
||||
private: // non-member operators
|
||||
// NOTE: the following "hidden friend" operators are available via
|
||||
// argument-dependent lookup only and must be defined inline.
|
||||
// boost::equality_comparable provides != operator.
|
||||
|
||||
friend bool
|
||||
operator==(const NameLsa& lhs, const NameLsa& rhs)
|
||||
{
|
||||
return lhs.m_npl == rhs.m_npl;
|
||||
}
|
||||
|
||||
private:
|
||||
NamePrefixList m_npl;
|
||||
};
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NameLsa& lsa);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_LSA_NAME_LSA_HPP
|
||||
+372
-1178
File diff suppressed because it is too large.
Load diff
+245
-296
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,231 +17,232 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_LSDB_HPP
|
||||
#define NLSR_LSDB_HPP
|
||||
|
||||
#include "conf-parameter.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "lsa-segment-storage.hpp"
|
||||
#include "sequencing-manager.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
#include "communication/sync-logic-handler.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
#include "lsa/lsa.hpp"
|
||||
#include "lsa/name-lsa.hpp"
|
||||
#include "lsa/coordinate-lsa.hpp"
|
||||
#include "lsa/adj-lsa.hpp"
|
||||
#include "sequencing-manager.hpp"
|
||||
#include "statistics.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <ndn-cxx/ims/in-memory-storage-fifo.hpp>
|
||||
#include <ndn-cxx/ims/in-memory-storage-persistent.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
#include <ndn-cxx/util/segmenter.hpp>
|
||||
#include <ndn-cxx/util/segment-fetcher.hpp>
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
#include <utility>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/composite_key.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class Nlsr;
|
||||
namespace bmi = boost::multi_index;
|
||||
|
||||
inline constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
|
||||
|
||||
enum class LsdbUpdate {
|
||||
INSTALLED,
|
||||
UPDATED,
|
||||
REMOVED
|
||||
};
|
||||
|
||||
class Lsdb
|
||||
{
|
||||
public:
|
||||
Lsdb(Nlsr& nlsr, ndn::Scheduler& scheduler);
|
||||
Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam);
|
||||
|
||||
SyncLogicHandler&
|
||||
getSyncLogicHandler()
|
||||
~Lsdb();
|
||||
|
||||
/*! \brief Returns whether the LSDB contains some LSA.
|
||||
*/
|
||||
bool
|
||||
doesLsaExist(const ndn::Name& router, Lsa::Type lsaType)
|
||||
{
|
||||
return m_sync;
|
||||
return m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)) != m_lsdb.end();
|
||||
}
|
||||
|
||||
bool
|
||||
isLsaNew(const ndn::Name& routerName, const Lsa::Type& lsaType, const uint64_t& sequenceNumber);
|
||||
|
||||
bool
|
||||
doesLsaExist(const ndn::Name& key, const Lsa::Type& lsType);
|
||||
|
||||
/*! \brief Builds a name LSA for this router and then installs it
|
||||
into the LSDB.
|
||||
*/
|
||||
bool
|
||||
void
|
||||
buildAndInstallOwnNameLsa();
|
||||
|
||||
/*! \brief Returns the name LSA with the given key.
|
||||
\param key The name of the router that the desired LSA comes from.
|
||||
*/
|
||||
NameLsa*
|
||||
findNameLsa(const ndn::Name& key);
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Builds a cor. LSA for this router and installs it into the LSDB. */
|
||||
void
|
||||
buildAndInstallOwnCoordinateLsa();
|
||||
|
||||
/*! \brief Installs a name LSA into the LSDB
|
||||
\param nlsa The name LSA to install into the LSDB.
|
||||
public:
|
||||
/*! \brief Schedules a build of this router's LSA. */
|
||||
void
|
||||
scheduleAdjLsaBuild();
|
||||
|
||||
void
|
||||
writeLog() const;
|
||||
|
||||
/* \brief Process interest which can be either:
|
||||
* 1) Discovery interest from segment fetcher:
|
||||
* /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
|
||||
* 2) Interest containing segment number:
|
||||
* /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>/<version>/<segmentNo>
|
||||
*/
|
||||
void
|
||||
processInterest(const ndn::Name& name, const ndn::Interest& interest);
|
||||
|
||||
bool
|
||||
getIsBuildAdjLsaScheduled() const
|
||||
{
|
||||
return m_isBuildAdjLsaScheduled;
|
||||
}
|
||||
|
||||
SyncLogicHandler&
|
||||
getSync()
|
||||
{
|
||||
return m_sync;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<T>
|
||||
findLsa(const ndn::Name& router) const
|
||||
{
|
||||
return std::static_pointer_cast<T>(findLsa(router, T::type()));
|
||||
}
|
||||
|
||||
struct name_hash {
|
||||
int
|
||||
operator()(const ndn::Name& name) const {
|
||||
return std::hash<ndn::Name>{}(name);
|
||||
}
|
||||
};
|
||||
|
||||
struct enum_class_hash {
|
||||
template<typename T>
|
||||
int
|
||||
operator()(T t) const {
|
||||
return static_cast<int>(t);
|
||||
}
|
||||
};
|
||||
|
||||
struct byName{};
|
||||
struct byType{};
|
||||
|
||||
using LsaContainer = boost::multi_index_container<
|
||||
std::shared_ptr<Lsa>,
|
||||
bmi::indexed_by<
|
||||
bmi::hashed_unique<
|
||||
bmi::tag<byName>,
|
||||
bmi::composite_key<
|
||||
Lsa,
|
||||
bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
|
||||
bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
|
||||
>,
|
||||
bmi::composite_key_hash<name_hash, enum_class_hash>
|
||||
>,
|
||||
bmi::hashed_non_unique<
|
||||
bmi::tag<byType>,
|
||||
bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
|
||||
enum_class_hash
|
||||
>
|
||||
>
|
||||
>;
|
||||
|
||||
template<typename T>
|
||||
std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
|
||||
LsaContainer::index<Lsdb::byType>::type::iterator>
|
||||
getLsdbIterator() const
|
||||
{
|
||||
return m_lsdb.get<byType>().equal_range(T::type());
|
||||
}
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
std::shared_ptr<Lsa>
|
||||
findLsa(const ndn::Name& router, Lsa::Type lsaType) const
|
||||
{
|
||||
auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
|
||||
return it != m_lsdb.end() ? *it : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
incrementDataSentStats(Lsa::Type lsaType)
|
||||
{
|
||||
if (lsaType == Lsa::Type::NAME) {
|
||||
lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
|
||||
}
|
||||
else if (lsaType == Lsa::Type::ADJACENCY) {
|
||||
lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
|
||||
}
|
||||
else if (lsaType == Lsa::Type::COORDINATE) {
|
||||
lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
incrementInterestRcvdStats(Lsa::Type lsaType)
|
||||
{
|
||||
if (lsaType == Lsa::Type::NAME) {
|
||||
lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_INTEREST);
|
||||
}
|
||||
else if (lsaType == Lsa::Type::ADJACENCY) {
|
||||
lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_INTEREST);
|
||||
}
|
||||
else if (lsaType == Lsa::Type::COORDINATE) {
|
||||
lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_INTEREST);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
incrementInterestSentStats(Lsa::Type lsaType)
|
||||
{
|
||||
if (lsaType == Lsa::Type::NAME) {
|
||||
lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_INTEREST);
|
||||
}
|
||||
else if (lsaType == Lsa::Type::ADJACENCY) {
|
||||
lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
|
||||
}
|
||||
else if (lsaType == Lsa::Type::COORDINATE) {
|
||||
lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_INTEREST);
|
||||
}
|
||||
}
|
||||
|
||||
/*! Returns whether a seq. no. from a certain router signals a new LSA.
|
||||
\param originRouter The name of the originating router.
|
||||
\param lsaType The type of the LSA.
|
||||
\param seqNo The sequence number to check.
|
||||
*/
|
||||
bool
|
||||
installNameLsa(NameLsa& nlsa);
|
||||
isLsaNew(const ndn::Name& originRouter, const Lsa::Type& lsaType, uint64_t seqNo) const
|
||||
{
|
||||
// Is the name in the LSDB and the supplied seq no is the highest so far
|
||||
auto lsaPtr = findLsa(originRouter, lsaType);
|
||||
return lsaPtr ? lsaPtr->getSeqNo() < seqNo : true;
|
||||
}
|
||||
|
||||
void
|
||||
installLsa(std::shared_ptr<Lsa> lsa);
|
||||
|
||||
/*! \brief Remove a name LSA from the LSDB.
|
||||
\param key The name of the router that published the LSA to remove.
|
||||
\param router The name of the router that published the LSA to remove.
|
||||
\param lsaType The type of the LSA.
|
||||
|
||||
This function will remove a name LSA from the LSDB by finding an
|
||||
LSA whose name matches key. This removal also causes the NPT to
|
||||
remove those name prefixes if no more LSAs advertise them.
|
||||
*/
|
||||
bool
|
||||
removeNameLsa(const ndn::Name& key);
|
||||
|
||||
/*! Returns whether a seq. no. from a certain router signals a new LSA.
|
||||
\param key The name of the originating router.
|
||||
\param seqNo The sequence number to check.
|
||||
*/
|
||||
bool
|
||||
isNameLsaNew(const ndn::Name& key, uint64_t seqNo);
|
||||
void
|
||||
removeLsa(const ndn::Name& router, Lsa::Type lsaType);
|
||||
|
||||
void
|
||||
writeNameLsdbLog();
|
||||
|
||||
const std::list<NameLsa>&
|
||||
getNameLsdb() const;
|
||||
|
||||
/*! \brief Builds a cor. LSA for this router and installs it into the LSDB. */
|
||||
bool
|
||||
buildAndInstallOwnCoordinateLsa();
|
||||
|
||||
/*! \brief Finds a cor. LSA in the LSDB.
|
||||
\param key The name of the originating router that published the LSA.
|
||||
*/
|
||||
CoordinateLsa*
|
||||
findCoordinateLsa(const ndn::Name& key);
|
||||
|
||||
/*! \brief Installs a cor. LSA into the LSDB.
|
||||
\param clsa The cor. LSA to install.
|
||||
*/
|
||||
bool
|
||||
installCoordinateLsa(CoordinateLsa& clsa);
|
||||
|
||||
/*! \brief Removes a cor. LSA from the LSDB.
|
||||
\param key The name of the router that published the LSA to remove.
|
||||
|
||||
Removes the coordinate LSA whose origin router name matches that
|
||||
given by key. Additionally, ask the NPT to remove the prefix,
|
||||
which will occur if no other LSAs point there.
|
||||
*/
|
||||
bool
|
||||
removeCoordinateLsa(const ndn::Name& key);
|
||||
|
||||
/*! \brief Returns whether a cor. LSA from a router is new or not.
|
||||
\param key The name prefix of the originating router.
|
||||
\param seqNo The sequence number of the candidate LSA.
|
||||
*/
|
||||
bool
|
||||
isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo);
|
||||
|
||||
void
|
||||
writeCorLsdbLog();
|
||||
|
||||
const std::list<CoordinateLsa>&
|
||||
getCoordinateLsdb() const;
|
||||
|
||||
//function related to Adj LSDB
|
||||
|
||||
/*! \brief Schedules a build of this router's LSA. */
|
||||
void
|
||||
scheduleAdjLsaBuild();
|
||||
|
||||
/*! \brief Wrapper event to build and install an adj. LSA for this router. */
|
||||
bool
|
||||
buildAndInstallOwnAdjLsa();
|
||||
|
||||
/*! \brief Removes an adj. LSA from the LSDB.
|
||||
\param key The name of the publishing router whose LSA to remove.
|
||||
*/
|
||||
bool
|
||||
removeAdjLsa(const ndn::Name& key);
|
||||
|
||||
/*! \brief Returns whether an LSA is new.
|
||||
\param key The name of the publishing router.
|
||||
\param seqNo The seq. no. of the candidate LSA.
|
||||
|
||||
This function determines whether the LSA with the name key and
|
||||
seq. no. seqNo would be new to this LSDB.
|
||||
*/
|
||||
bool
|
||||
isAdjLsaNew(const ndn::Name& key, uint64_t seqNo);
|
||||
|
||||
/*! \brief Installs an adj. LSA into the LSDB.
|
||||
\param alsa The adj. LSA to add to the LSDB.
|
||||
*/
|
||||
bool
|
||||
installAdjLsa(AdjLsa& alsa);
|
||||
|
||||
/*! \brief Finds an adj. LSA in the LSDB.
|
||||
\param key The name of the publishing router whose LSA to find.
|
||||
*/
|
||||
AdjLsa*
|
||||
findAdjLsa(const ndn::Name& key);
|
||||
|
||||
const std::list<AdjLsa>&
|
||||
getAdjLsdb() const;
|
||||
|
||||
void
|
||||
setAdjLsaBuildInterval(uint32_t interval)
|
||||
{
|
||||
m_adjLsaBuildInterval = ndn::time::seconds(interval);
|
||||
}
|
||||
|
||||
const ndn::time::seconds&
|
||||
getAdjLsaBuildInterval() const
|
||||
{
|
||||
return m_adjLsaBuildInterval;
|
||||
}
|
||||
|
||||
SequencingManager&
|
||||
getSequencingManager()
|
||||
{
|
||||
return m_sequencingManager;
|
||||
}
|
||||
|
||||
LsaSegmentStorage&
|
||||
getLsaStorage()
|
||||
{
|
||||
return m_lsaStorage;
|
||||
}
|
||||
|
||||
void
|
||||
writeAdjLsdbLog();
|
||||
|
||||
void
|
||||
setLsaRefreshTime(const ndn::time::seconds& lsaRefreshTime);
|
||||
|
||||
void
|
||||
setThisRouterPrefix(std::string trp);
|
||||
|
||||
void
|
||||
expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
|
||||
ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
|
||||
|
||||
void
|
||||
processInterest(const ndn::Name& name, const ndn::Interest& interest);
|
||||
|
||||
private:
|
||||
/* \brief Add a name LSA to the LSDB if it isn't already there.
|
||||
\param nlsa The candidade name LSA.
|
||||
*/
|
||||
bool
|
||||
addNameLsa(NameLsa& nlsa);
|
||||
|
||||
/*! \brief Returns whether the LSDB contains some LSA.
|
||||
\param key The name of the publishing router whose LSA to check for.
|
||||
*/
|
||||
bool
|
||||
doesNameLsaExist(const ndn::Name& key);
|
||||
|
||||
/*! \brief Adds a cor. LSA to the LSDB if it isn't already there.
|
||||
\param clsa The candidate cor. LSA.
|
||||
*/
|
||||
bool
|
||||
addCoordinateLsa(CoordinateLsa& clsa);
|
||||
|
||||
/*! \brief Returns whether a cor. LSA is in the LSDB.
|
||||
\param key The name of the router that published the queried LSA.
|
||||
*/
|
||||
bool
|
||||
doesCoordinateLsaExist(const ndn::Name& key);
|
||||
removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt);
|
||||
|
||||
/*! \brief Attempts to construct an adj. LSA.
|
||||
|
||||
@@ -253,92 +254,31 @@ private:
|
||||
void
|
||||
buildAdjLsa();
|
||||
|
||||
/*! \brief Adds an adj. LSA to the LSDB if it isn't already there.
|
||||
\param alsa The candidate adj. LSA to add to the LSDB.
|
||||
*/
|
||||
bool
|
||||
addAdjLsa(AdjLsa& alsa);
|
||||
|
||||
/*! \brief Returns whether the LSDB contains an LSA.
|
||||
\param key The name of a router whose LSA to check for in the LSDB.
|
||||
*/
|
||||
bool
|
||||
doesAdjLsaExist(const ndn::Name& key);
|
||||
/*! \brief Wrapper event to build and install an adj. LSA for this router. */
|
||||
void
|
||||
buildAndInstallOwnAdjLsa();
|
||||
|
||||
/*! \brief Schedules a refresh/expire event in the scheduler.
|
||||
\param key The name of the router that published the LSA.
|
||||
\param seqNo The seq. no. associated with the LSA.
|
||||
\param lsa The LSA.
|
||||
\param expTime How many seconds to wait before triggering the event.
|
||||
*/
|
||||
ndn::EventId
|
||||
scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
|
||||
const ndn::time::seconds& expTime);
|
||||
ndn::scheduler::EventId
|
||||
scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime);
|
||||
|
||||
/*! \brief Either allow to expire, or refresh a name LSA.
|
||||
\param lsaKey The name of the router that published the LSA.
|
||||
\param seqNo The seq. no. of the LSA to check.
|
||||
\param lsa The LSA.
|
||||
*/
|
||||
void
|
||||
expireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo);
|
||||
expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Schedules an expire/refresh event in the LSA.
|
||||
\param key The name of the router whose LSA is in question.
|
||||
\param seqNo The sequence number of the LSA to check.
|
||||
\param expTime The number of seconds to wait before triggering the event.
|
||||
*/
|
||||
ndn::EventId
|
||||
scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
|
||||
const ndn::time::seconds& expTime);
|
||||
|
||||
private:
|
||||
bool
|
||||
processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
|
||||
Lsa::Type lsaType, uint64_t seqNo);
|
||||
|
||||
void
|
||||
expireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo);
|
||||
expressInterest(const ndn::Name& interestName, uint32_t timeoutCount, uint64_t incomingFaceId,
|
||||
ndn::time::steady_clock::time_point deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
|
||||
|
||||
ndn::EventId
|
||||
scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
|
||||
const ndn::time::seconds& expTime);
|
||||
|
||||
void
|
||||
expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
|
||||
uint64_t seqNo);
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
putLsaData(const ndn::Interest& interest, const std::string& content);
|
||||
|
||||
void
|
||||
processInterestForNameLsa(const ndn::Interest& interest,
|
||||
const ndn::Name& lsaKey,
|
||||
uint64_t seqNo);
|
||||
|
||||
void
|
||||
processInterestForAdjacencyLsa(const ndn::Interest& interest,
|
||||
const ndn::Name& lsaKey,
|
||||
uint64_t seqNo);
|
||||
|
||||
void
|
||||
processInterestForCoordinateLsa(const ndn::Interest& interest,
|
||||
const ndn::Name& lsaKey,
|
||||
uint64_t seqNo);
|
||||
void
|
||||
onContentValidated(const std::shared_ptr<const ndn::Data>& data);
|
||||
|
||||
void
|
||||
processContentNameLsa(const ndn::Name& lsaKey,
|
||||
uint64_t lsSeqNo, std::string& dataContent);
|
||||
|
||||
void
|
||||
processContentAdjacencyLsa(const ndn::Name& lsaKey,
|
||||
uint64_t lsSeqNo, std::string& dataContent);
|
||||
|
||||
void
|
||||
processContentCoordinateLsa(const ndn::Name& lsaKey,
|
||||
uint64_t lsSeqNo, std::string& dataContent);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*!
|
||||
\brief Error callback when SegmentFetcher fails to return an LSA
|
||||
|
||||
@@ -354,13 +294,10 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
is reached.
|
||||
*/
|
||||
void
|
||||
onFetchLsaError(uint32_t errorCode,
|
||||
const std::string& msg,
|
||||
ndn::Name& interestName,
|
||||
uint32_t retransmitNo,
|
||||
const ndn::time::steady_clock::TimePoint& deadline,
|
||||
ndn::Name lsaName,
|
||||
uint64_t seqNo);
|
||||
onFetchLsaError(uint32_t errorCode, const std::string& msg,
|
||||
const ndn::Name& interestName, uint32_t retransmitNo,
|
||||
const ndn::time::steady_clock::time_point& deadline,
|
||||
ndn::Name lsaName, uint64_t seqNo);
|
||||
|
||||
/*!
|
||||
\brief Success callback when SegmentFetcher returns a valid LSA
|
||||
@@ -369,48 +306,60 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/<network>/NLSR/LSA/<site>/%C1.Router/<router>/<lsa-type>/<seqNo>
|
||||
*/
|
||||
void
|
||||
afterFetchLsa(const ndn::ConstBufferPtr& data, ndn::Name& interestName);
|
||||
afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName);
|
||||
|
||||
private:
|
||||
ndn::time::system_clock::TimePoint
|
||||
getLsaExpirationTimePoint();
|
||||
|
||||
/*! \brief Cancels an event in the event scheduler. */
|
||||
void
|
||||
cancelScheduleLsaExpiringEvent(ndn::EventId eid);
|
||||
emitSegmentValidatedSignal(const ndn::Data& data)
|
||||
{
|
||||
afterSegmentValidatedSignal(data);
|
||||
}
|
||||
|
||||
ndn::time::system_clock::time_point
|
||||
getLsaExpirationTimePoint() const
|
||||
{
|
||||
return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
|
||||
}
|
||||
|
||||
public:
|
||||
static const ndn::Name::Component NAME_COMPONENT;
|
||||
ndn::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
|
||||
ndn::signal::Signal<Lsdb, ndn::Data> afterSegmentValidatedSignal;
|
||||
using AfterLsdbModified = ndn::signal::Signal<Lsdb, std::shared_ptr<Lsa>, LsdbUpdate,
|
||||
std::list<ndn::Name>, std::list<ndn::Name>>;
|
||||
AfterLsdbModified onLsdbModified;
|
||||
|
||||
ndn::util::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
ndn::Face& m_face;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ConfParameter& m_confParam;
|
||||
|
||||
private:
|
||||
Nlsr& m_nlsr;
|
||||
ndn::Scheduler& m_scheduler;
|
||||
SyncLogicHandler m_sync;
|
||||
LsaSegmentStorage m_lsaStorage;
|
||||
|
||||
std::list<NameLsa> m_nameLsdb;
|
||||
std::list<AdjLsa> m_adjLsdb;
|
||||
std::list<CoordinateLsa> m_corLsdb;
|
||||
LsaContainer m_lsdb;
|
||||
|
||||
ndn::time::seconds m_lsaRefreshTime;
|
||||
std::string m_thisRouterPrefix;
|
||||
|
||||
typedef std::map<ndn::Name, uint64_t> SequenceNumberMap;
|
||||
ndn::time::seconds m_adjLsaBuildInterval;
|
||||
const ndn::Name& m_thisRouterPrefix;
|
||||
|
||||
// Maps the name of an LSA to its highest known sequence number from sync;
|
||||
// Used to stop NLSR from trying to fetch outdated LSAs
|
||||
SequenceNumberMap m_highestSeqNo;
|
||||
|
||||
static const ndn::time::seconds GRACE_PERIOD;
|
||||
static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
|
||||
|
||||
ndn::time::seconds m_adjLsaBuildInterval;
|
||||
std::map<ndn::Name, uint64_t> m_highestSeqNo;
|
||||
|
||||
SequencingManager m_sequencingManager;
|
||||
|
||||
ndn::util::signal::ScopedConnection m_onNewLsaConnection;
|
||||
ndn::signal::ScopedConnection m_onNewLsaConnection;
|
||||
|
||||
std::set<std::shared_ptr<ndn::SegmentFetcher>> m_fetchers;
|
||||
ndn::Segmenter m_segmenter;
|
||||
ndn::InMemoryStorageFifo m_segmentFifo;
|
||||
|
||||
bool m_isBuildAdjLsaScheduled;
|
||||
int64_t m_adjBuildCount;
|
||||
ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;
|
||||
|
||||
ndn::InMemoryStoragePersistent m_lsaStorage;
|
||||
|
||||
static inline const ndn::time::steady_clock::time_point DEFAULT_LSA_RETRIEVAL_DEADLINE =
|
||||
ndn::time::steady_clock::time_point::min();
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
+57
-46
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -19,68 +19,79 @@
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "nlsr-runner.hpp"
|
||||
#include "conf-file-processor.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "security/certificate-store.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
#include <sstream>
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template<typename E>
|
||||
std::string
|
||||
getExtendedErrorMessage(const E& exception)
|
||||
static void
|
||||
printUsage(std::ostream& os, const std::string& programName)
|
||||
{
|
||||
std::ostringstream errorMessage;
|
||||
errorMessage << exception.what();
|
||||
|
||||
const char* const* file = boost::get_error_info<boost::throw_file>(exception);
|
||||
const int* line = boost::get_error_info<boost::throw_line>(exception);
|
||||
const char* const* func = boost::get_error_info<boost::throw_function>(exception);
|
||||
if (file && line) {
|
||||
errorMessage << " [from " << *file << ":" << *line;
|
||||
if (func) {
|
||||
errorMessage << " in " << *func;
|
||||
}
|
||||
errorMessage << "]";
|
||||
}
|
||||
|
||||
return errorMessage.str();
|
||||
os << "Usage: " << programName << " [OPTIONS...]\n"
|
||||
<< "\n"
|
||||
<< "Options:\n"
|
||||
<< " -f <FILE> Path to configuration file\n"
|
||||
<< " -h Display this help message\n"
|
||||
<< " -V Display version information\n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int
|
||||
main(int32_t argc, char** argv)
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
using namespace nlsr;
|
||||
|
||||
std::string programName(argv[0]);
|
||||
std::string configFileName("nlsr.conf");
|
||||
|
||||
std::string configFileName = "nlsr.conf";
|
||||
|
||||
int32_t opt;
|
||||
while ((opt = getopt(argc, argv, "df:hV")) != -1) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "hf:V")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
configFileName = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
std::cout << NLSR_VERSION_BUILD_STRING << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
NlsrRunner::printUsage(programName);
|
||||
return EXIT_FAILURE;
|
||||
case 'h':
|
||||
printUsage(std::cout, programName);
|
||||
return 0;
|
||||
case 'f':
|
||||
configFileName = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
std::cout << NLSR_VERSION_BUILD_STRING << std::endl;
|
||||
return 0;
|
||||
default:
|
||||
printUsage(std::cerr, programName);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
NlsrRunner runner(configFileName);
|
||||
ndn::KeyChain keyChain;
|
||||
ndn::Face face(nullptr, keyChain);
|
||||
|
||||
nlsr::ConfParameter confParam(face, keyChain, configFileName);
|
||||
nlsr::ConfFileProcessor configProcessor(confParam);
|
||||
if (!configProcessor.processConfFile()) {
|
||||
std::cerr << "Error in configuration file processing" << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Since confParam is already populated, key is initialized here before
|
||||
// and independent of the NLSR class
|
||||
auto certificate = confParam.initializeKey();
|
||||
|
||||
nlsr::Nlsr nlsr(face, keyChain, confParam);
|
||||
|
||||
nlsr::security::CertificateStore certStore(face, confParam, nlsr.getLsdb());
|
||||
if (certificate) {
|
||||
certStore.insert(*certificate);
|
||||
}
|
||||
|
||||
try {
|
||||
runner.run();
|
||||
face.processEvents();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << getExtendedErrorMessage(e) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
nlsr.getFib().clean();
|
||||
std::cerr << "FATAL: " << boost::diagnostic_information(e) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
+32
-102
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,144 +17,74 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "name-prefix-list.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
NamePrefixList::NamePrefixList() = default;
|
||||
|
||||
NamePrefixList::NamePrefixList(const std::initializer_list<ndn::Name>& names)
|
||||
NamePrefixList::NamePrefixList(std::initializer_list<ndn::Name> names)
|
||||
{
|
||||
std::vector<NamePrefixList::NamePair> namePairs;
|
||||
std::transform(names.begin(), names.end(), std::back_inserter(namePairs),
|
||||
[] (const ndn::Name& name) {
|
||||
return NamePrefixList::NamePair{name, {""}};
|
||||
});
|
||||
m_names = std::move(namePairs);
|
||||
}
|
||||
|
||||
NamePrefixList::NamePrefixList(const std::initializer_list<NamePrefixList::NamePair>& namesAndSources)
|
||||
: m_names(namesAndSources)
|
||||
{
|
||||
}
|
||||
|
||||
NamePrefixList::~NamePrefixList()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<NamePrefixList::NamePair>::iterator
|
||||
NamePrefixList::get(const ndn::Name& name)
|
||||
{
|
||||
return std::find_if(m_names.begin(), m_names.end(),
|
||||
[&] (const NamePrefixList::NamePair& pair) {
|
||||
return name == std::get<NamePrefixList::NamePairIndex::NAME>(pair);
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string>::iterator
|
||||
NamePrefixList::getSource(const std::string& source, std::vector<NamePair>::iterator& entry)
|
||||
{
|
||||
return std::find_if(std::get<NamePairIndex::SOURCES>(*entry).begin(),
|
||||
std::get<NamePairIndex::SOURCES>(*entry).end(),
|
||||
[&] (const std::string& containerSource) {
|
||||
return source == containerSource;
|
||||
});
|
||||
for (const auto& name : names) {
|
||||
insert(name);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NamePrefixList::insert(const ndn::Name& name, const std::string& source)
|
||||
{
|
||||
auto pairItr = get(name);
|
||||
if (pairItr == m_names.end()) {
|
||||
std::vector<std::string> sources{source};
|
||||
m_names.push_back(std::tie(name, sources));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
std::vector<std::string>& sources = std::get<NamePrefixList::NamePairIndex::SOURCES>(*pairItr);
|
||||
auto sourceItr = getSource(source, pairItr);
|
||||
if (sourceItr == sources.end()) {
|
||||
sources.push_back(source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
auto& sources = m_namesSources[name];
|
||||
return sources.insert(source).second;
|
||||
}
|
||||
|
||||
bool
|
||||
NamePrefixList::remove(const ndn::Name& name, const std::string& source)
|
||||
NamePrefixList::erase(const ndn::Name& name, const std::string& source)
|
||||
{
|
||||
auto pairItr = get(name);
|
||||
if (pairItr != m_names.end()) {
|
||||
std::vector<std::string>& sources = std::get<NamePrefixList::NamePairIndex::SOURCES>(*pairItr);
|
||||
auto sourceItr = getSource(source, pairItr);
|
||||
if (sourceItr != sources.end()) {
|
||||
sources.erase(sourceItr);
|
||||
if (sources.size() == 0) {
|
||||
m_names.erase(pairItr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
auto it = m_namesSources.find(name);
|
||||
if (it == m_namesSources.end()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
NamePrefixList::operator==(const NamePrefixList& other) const
|
||||
{
|
||||
return m_names == other.m_names;
|
||||
}
|
||||
|
||||
void
|
||||
NamePrefixList::sort()
|
||||
{
|
||||
std::sort(m_names.begin(), m_names.end());
|
||||
bool isRemoved = it->second.erase(source);
|
||||
if (it->second.empty()) {
|
||||
m_namesSources.erase(it);
|
||||
}
|
||||
return isRemoved;
|
||||
}
|
||||
|
||||
std::list<ndn::Name>
|
||||
NamePrefixList::getNames() const
|
||||
{
|
||||
std::list<ndn::Name> names;
|
||||
for (const auto& namePair : m_names) {
|
||||
names.push_back(std::get<NamePrefixList::NamePairIndex::NAME>(namePair));
|
||||
for (const auto& [name, sources] : m_namesSources) {
|
||||
names.push_back(name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
NamePrefixList::countSources(const ndn::Name& name) const
|
||||
{
|
||||
return getSources(name).size();
|
||||
}
|
||||
#ifdef WITH_TESTS
|
||||
|
||||
const std::vector<std::string>
|
||||
std::set<std::string>
|
||||
NamePrefixList::getSources(const ndn::Name& name) const
|
||||
{
|
||||
auto it = std::find_if(m_names.begin(), m_names.end(),
|
||||
[&] (const NamePrefixList::NamePair& pair) {
|
||||
return name == std::get<NamePrefixList::NamePairIndex::NAME>(pair);
|
||||
});
|
||||
if (it != m_names.end()) {
|
||||
return std::get<NamePrefixList::NamePairIndex::SOURCES>(*it);
|
||||
}
|
||||
else {
|
||||
return std::vector<std::string>{};
|
||||
if (auto it = m_namesSources.find(name); it != m_namesSources.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NamePrefixList& list) {
|
||||
operator<<(std::ostream& os, const NamePrefixList& list)
|
||||
{
|
||||
os << "Name prefix list: {\n";
|
||||
for (const auto& name : list.getNames()) {
|
||||
os << name << "\n"
|
||||
<< "Sources:\n";
|
||||
for (const auto& source : list.getSources(name)) {
|
||||
for (const auto& [name, sources] : list.m_namesSources) {
|
||||
os << name << "\nSources:\n";
|
||||
for (const auto& source : sources) {
|
||||
os << " " << source << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
+48
-67
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,107 +17,88 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NAME_PREFIX_LIST_HPP
|
||||
#define NLSR_NAME_PREFIX_LIST_HPP
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <ndn-cxx/name.hpp>
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace nlsr {
|
||||
class NamePrefixList
|
||||
|
||||
class NamePrefixList : private boost::equality_comparable<NamePrefixList>
|
||||
{
|
||||
public:
|
||||
using NamePair = std::tuple<ndn::Name, std::vector<std::string>>;
|
||||
enum NamePairIndex {
|
||||
NAME,
|
||||
SOURCES
|
||||
};
|
||||
|
||||
NamePrefixList();
|
||||
|
||||
NamePrefixList(const std::initializer_list<ndn::Name>& names);
|
||||
explicit
|
||||
NamePrefixList(std::initializer_list<ndn::Name> names);
|
||||
|
||||
NamePrefixList(const std::initializer_list<NamePrefixList::NamePair>& namesAndSources);
|
||||
|
||||
template<class ContainerType>
|
||||
NamePrefixList(const ContainerType& names)
|
||||
{
|
||||
for (const auto& elem : names) {
|
||||
m_names.push_back(NamePair{elem, {""}});
|
||||
}
|
||||
}
|
||||
|
||||
~NamePrefixList();
|
||||
|
||||
/*! \brief inserts name into NamePrefixList
|
||||
\retval true If the name was successfully inserted.
|
||||
\retval false If the name could not be inserted.
|
||||
/*! \brief Inserts name and source combination.
|
||||
\retval true Name and source combination is inserted.
|
||||
\retval false Name and source combination already exists.
|
||||
*/
|
||||
bool
|
||||
insert(const ndn::Name& name, const std::string& source = "");
|
||||
|
||||
/*! \brief removes name from NamePrefixList
|
||||
\retval true If the name is removed
|
||||
\retval false If the name failed to be removed.
|
||||
/*! \brief Deletes name and source combination
|
||||
\retval true Name and source combination is deleted.
|
||||
\retval false Name and source combination does not exist.
|
||||
*/
|
||||
bool
|
||||
remove(const ndn::Name& name, const std::string& source = "");
|
||||
|
||||
void
|
||||
sort();
|
||||
erase(const ndn::Name& name, const std::string& source = "");
|
||||
|
||||
size_t
|
||||
size() const
|
||||
{
|
||||
return m_names.size();
|
||||
return m_namesSources.size();
|
||||
}
|
||||
|
||||
std::list<ndn::Name>
|
||||
getNames() const;
|
||||
|
||||
bool
|
||||
operator==(const NamePrefixList& other) const;
|
||||
|
||||
/*! Returns how many unique sources this name has.
|
||||
|
||||
\retval 0 if the name is not in the list, else the number of sources.
|
||||
*/
|
||||
uint32_t
|
||||
countSources(const ndn::Name& name) const;
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
/*! Returns the sources that this name has.
|
||||
|
||||
\retval an empty vector if the name is not in the list, else a
|
||||
vector containing the sources.
|
||||
If the name does not exist, returns an empty container.
|
||||
*/
|
||||
const std::vector<std::string>
|
||||
std::set<std::string>
|
||||
getSources(const ndn::Name& name) const;
|
||||
#endif
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
m_namesSources.clear();
|
||||
}
|
||||
|
||||
private: // non-member operators
|
||||
// NOTE: the following "hidden friend" operators are available via
|
||||
// argument-dependent lookup only and must be defined inline.
|
||||
// boost::equality_comparable provides != operators.
|
||||
|
||||
friend bool
|
||||
operator==(const NamePrefixList& lhs, const NamePrefixList& rhs)
|
||||
{
|
||||
return lhs.getNames() == rhs.getNames();
|
||||
}
|
||||
|
||||
private:
|
||||
/*! Obtain an iterator to the entry matching name.
|
||||
std::map<ndn::Name, std::set<std::string>> m_namesSources;
|
||||
|
||||
\note We could do this quite easily inline with a lambda, but this
|
||||
is slightly more efficient.
|
||||
*/
|
||||
std::vector<NamePair>::iterator
|
||||
get(const ndn::Name& name);
|
||||
|
||||
/*! Obtain an iterator to a specific source in an entry
|
||||
*/
|
||||
std::vector<std::string>::iterator
|
||||
getSource(const std::string& source, std::vector<NamePair>::iterator& entry);
|
||||
|
||||
std::vector<NamePair> m_names;
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const NamePrefixList& list);
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NamePrefixList& list);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_NAME_PREFIX_LIST_HPP
|
||||
@@ -1,81 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "nlsr-runner.hpp"
|
||||
#include "conf-file-processor.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(NlsrRunner);
|
||||
|
||||
NlsrRunner::NlsrRunner(std::string& configFileName)
|
||||
: m_scheduler(m_ioService)
|
||||
, m_face(m_ioService)
|
||||
, m_nlsr(m_ioService, m_scheduler, m_face, m_keyChain)
|
||||
{
|
||||
m_nlsr.setConfFileName(configFileName);
|
||||
}
|
||||
|
||||
void
|
||||
NlsrRunner::run()
|
||||
{
|
||||
ConfFileProcessor configProcessor(m_nlsr, m_nlsr.getConfFileName());
|
||||
|
||||
if (!configProcessor.processConfFile()) {
|
||||
BOOST_THROW_EXCEPTION(Error("Error in configuration file processing! Exiting from NLSR"));
|
||||
}
|
||||
|
||||
/** Because URI canonization needs to occur before initialization,
|
||||
we have to pass initialize as the finally() in neighbor
|
||||
canonization.
|
||||
*/
|
||||
m_nlsr.canonizeNeighborUris(m_nlsr.getAdjacencyList().getAdjList().begin(),
|
||||
[this] (std::list<Adjacent>::iterator iterator) {
|
||||
m_nlsr.canonizeContinuation(iterator, [this] {
|
||||
m_nlsr.initialize();
|
||||
});
|
||||
},
|
||||
[this] {
|
||||
m_nlsr.initialize();
|
||||
});
|
||||
try {
|
||||
m_nlsr.startEventLoop();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
NLSR_LOG_FATAL("ERROR: " << e.what());
|
||||
std::cerr << "ERROR: " << e.what() << std::endl;
|
||||
|
||||
m_nlsr.getFib().clean();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NlsrRunner::printUsage(const std::string& programName)
|
||||
{
|
||||
std::cout << "Usage: " << programName << " [OPTIONS...]" << std::endl;
|
||||
std::cout << " NDN routing...." << std::endl;
|
||||
std::cout << " -f <FILE> Specify configuration file name" << std::endl;
|
||||
std::cout << " -V Display version information" << std::endl;
|
||||
std::cout << " -h Display this help message" << std::endl;
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,88 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef NLSR_NLSR_RUNNER_HPP
|
||||
#define NLSR_NLSR_RUNNER_HPP
|
||||
|
||||
#include "nlsr.hpp"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
// boost needs to be included after ndn-cxx, otherwise there will be conflict with _1, _2, ...
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*! \brief A wrapper class to instantiate and configure an NLSR object.
|
||||
*
|
||||
* As its name suggests, this class is responsible for running
|
||||
* NLSR. It creates an nlsr::ConfFileProcessor to read a configuration
|
||||
* file and uses that to configure and then start an NLSR process.
|
||||
* This class only exists to provide this functionality, and there is
|
||||
* no special reliance of NLSR on this class.
|
||||
*/
|
||||
|
||||
class NlsrRunner
|
||||
{
|
||||
public:
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
explicit
|
||||
NlsrRunner(std::string& configFileName);
|
||||
|
||||
/*! \brief Instantiate, configure, and start the NLSR process.
|
||||
*
|
||||
* Each NlsrRunner is uniquely paired to the Face it's instantiated
|
||||
* with. This is *not* a factory-type class, but a one-to-one
|
||||
* relationship. If one wants to create multiple NLSR classes,
|
||||
* multiple NLSR runners need to be created, too.
|
||||
*
|
||||
* \throws Error If the configuration file cannot be processed. NLSR
|
||||
* is not started.
|
||||
*
|
||||
* \sa Nlsr::canonizeNeighborUris
|
||||
*/
|
||||
void
|
||||
run();
|
||||
|
||||
static void
|
||||
printUsage(const std::string& programName);
|
||||
|
||||
private:
|
||||
boost::asio::io_service m_ioService;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ndn::Face m_face;
|
||||
ndn::KeyChain m_keyChain;
|
||||
Nlsr m_nlsr;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_NLSR_RUNNER_HPP
|
||||
+138
-465
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,460 +17,162 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "nlsr.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
|
||||
#include <ndn-cxx/net/face-uri.hpp>
|
||||
#include <ndn-cxx/signature.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(Nlsr);
|
||||
|
||||
const ndn::Name Nlsr::LOCALHOST_PREFIX = ndn::Name("/localhost/nlsr");
|
||||
|
||||
Nlsr::Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::Face& face, ndn::KeyChain& keyChain)
|
||||
: m_nlsrFace(face)
|
||||
, m_scheduler(scheduler)
|
||||
, m_keyChain(keyChain)
|
||||
, m_confParam()
|
||||
, m_adjacencyList()
|
||||
, m_namePrefixList()
|
||||
, m_configFileName("nlsr.conf")
|
||||
, m_nlsrLsdb(*this, scheduler)
|
||||
, m_adjBuildCount(0)
|
||||
, m_isBuildAdjLsaSheduled(false)
|
||||
, m_isRouteCalculationScheduled(false)
|
||||
, m_isRoutingTableCalculating(false)
|
||||
, m_routingTable(scheduler)
|
||||
, m_fib(m_nlsrFace, scheduler, m_adjacencyList, m_confParam, m_keyChain)
|
||||
, m_namePrefixTable(*this, m_routingTable.afterRoutingChange)
|
||||
, m_dispatcher(m_nlsrFace, m_keyChain)
|
||||
, m_datasetHandler(m_nlsrLsdb,
|
||||
m_routingTable,
|
||||
m_dispatcher,
|
||||
m_nlsrFace,
|
||||
m_keyChain)
|
||||
, m_helloProtocol(*this, scheduler)
|
||||
, m_validator(ndn::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(m_nlsrFace))
|
||||
, m_controller(m_nlsrFace, m_keyChain)
|
||||
, m_faceDatasetController(m_nlsrFace, m_keyChain)
|
||||
Nlsr::Nlsr(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam)
|
||||
: m_face(face)
|
||||
, m_scheduler(face.getIoContext())
|
||||
, m_confParam(confParam)
|
||||
, m_adjacencyList(confParam.getAdjacencyList())
|
||||
, m_namePrefixList(confParam.getNamePrefixList())
|
||||
, m_fib(m_face, m_scheduler, m_adjacencyList, m_confParam, keyChain)
|
||||
, m_lsdb(m_face, keyChain, m_confParam)
|
||||
, m_routingTable(m_scheduler, m_lsdb, m_confParam)
|
||||
, m_namePrefixTable(confParam.getRouterPrefix(), m_fib, m_routingTable,
|
||||
m_routingTable.afterRoutingChange, m_lsdb.onLsdbModified)
|
||||
, m_helloProtocol(m_face, keyChain, confParam, m_routingTable, m_lsdb)
|
||||
, m_onNewLsaConnection(m_lsdb.getSync().onNewLsa.connect(
|
||||
[this] (const ndn::Name& updateName, uint64_t sequenceNumber,
|
||||
const ndn::Name& originRouter, uint64_t incomingFaceId) {
|
||||
registerStrategyForCerts(originRouter);
|
||||
}))
|
||||
, m_onPrefixRegistrationSuccess(m_fib.onPrefixRegistrationSuccess.connect(
|
||||
[this] (const ndn::Name& name) {
|
||||
m_helloProtocol.sendHelloInterest(name);
|
||||
}))
|
||||
, m_onInitialHelloDataValidated(m_helloProtocol.onInitialHelloDataValidated.connect(
|
||||
[this] (const ndn::Name& neighbor) {
|
||||
auto it = m_adjacencyList.findAdjacent(neighbor);
|
||||
if (it != m_adjacencyList.end()) {
|
||||
m_fib.registerPrefix(m_confParam.getSyncPrefix(), it->getFaceUri(), it->getLinkCost(),
|
||||
ndn::time::milliseconds::max(), ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
}
|
||||
}))
|
||||
, m_dispatcher(m_face, keyChain)
|
||||
, m_datasetHandler(m_dispatcher, m_lsdb, m_routingTable)
|
||||
, m_controller(m_face, keyChain)
|
||||
, m_faceDatasetController(m_face, keyChain)
|
||||
, m_prefixUpdateProcessor(m_dispatcher,
|
||||
m_nlsrFace,
|
||||
m_namePrefixList,
|
||||
m_nlsrLsdb)
|
||||
m_confParam.getPrefixUpdateValidator(),
|
||||
m_namePrefixList,
|
||||
m_lsdb,
|
||||
m_confParam.getConfFileNameDynamic())
|
||||
, m_nfdRibCommandProcessor(m_dispatcher,
|
||||
m_namePrefixList,
|
||||
m_nlsrLsdb)
|
||||
, m_statsCollector(m_nlsrLsdb, m_helloProtocol)
|
||||
, m_faceMonitor(m_nlsrFace)
|
||||
, m_firstHelloInterval(FIRST_HELLO_INTERVAL_DEFAULT)
|
||||
{
|
||||
m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification, this, _1));
|
||||
m_faceMonitor.start();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registrationFailed(const ndn::Name& name)
|
||||
{
|
||||
NLSR_LOG_ERROR("ERROR: Failed to register prefix in local hub's daemon");
|
||||
BOOST_THROW_EXCEPTION(Error("Error: Prefix registration failed"));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::onRegistrationSuccess(const ndn::Name& name)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::setInfoInterestFilter()
|
||||
{
|
||||
ndn::Name name(m_confParam.getRouterPrefix());
|
||||
name.append("nlsr");
|
||||
name.append("INFO");
|
||||
|
||||
NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
|
||||
|
||||
m_nlsrFace.setInterestFilter(name,
|
||||
std::bind(&HelloProtocol::processInterest,
|
||||
&m_helloProtocol, _1, _2),
|
||||
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::setLsaInterestFilter()
|
||||
{
|
||||
ndn::Name name = m_confParam.getLsaPrefix();
|
||||
|
||||
NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);
|
||||
|
||||
m_nlsrFace.setInterestFilter(name,
|
||||
std::bind(&Lsdb::processInterest,
|
||||
&m_nlsrLsdb, _1, _2),
|
||||
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
|
||||
{
|
||||
try {
|
||||
// false since we want to have control over the registration process
|
||||
m_dispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::setStrategies()
|
||||
{
|
||||
const std::string strategy("ndn:/localhost/nfd/strategy/multicast");
|
||||
|
||||
m_fib.setStrategy(m_confParam.getLsaPrefix(), strategy, 0);
|
||||
m_fib.setStrategy(m_confParam.getChronosyncPrefix(), strategy, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::canonizeContinuation(std::list<Adjacent>::iterator iterator,
|
||||
std::function<void(void)> finally)
|
||||
{
|
||||
canonizeNeighborUris(iterator, [this, finally] (std::list<Adjacent>::iterator iterator) {
|
||||
canonizeContinuation(iterator, finally);
|
||||
},
|
||||
finally);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
|
||||
std::function<void(std::list<Adjacent>::iterator)> then,
|
||||
std::function<void(void)> finally)
|
||||
{
|
||||
if (currentNeighbor != m_adjacencyList.getAdjList().end()) {
|
||||
ndn::FaceUri uri(currentNeighbor->getFaceUri());
|
||||
uri.canonize([then, currentNeighbor] (ndn::FaceUri canonicalUri) {
|
||||
NLSR_LOG_DEBUG("Canonized URI: " << currentNeighbor->getFaceUri()
|
||||
<< " to: " << canonicalUri);
|
||||
currentNeighbor->setFaceUri(canonicalUri);
|
||||
then(std::next(currentNeighbor));
|
||||
},
|
||||
[then, currentNeighbor] (const std::string& reason) {
|
||||
NLSR_LOG_ERROR("Could not canonize URI: " << currentNeighbor->getFaceUri()
|
||||
<< " because: " << reason);
|
||||
then(std::next(currentNeighbor));
|
||||
},
|
||||
m_nlsrFace.getIoService(),
|
||||
TIME_ALLOWED_FOR_CANONIZATION);
|
||||
}
|
||||
// We have finished canonizing all neighbors, so call finally()
|
||||
else {
|
||||
finally();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::loadCertToPublish(const ndn::security::v2::Certificate& certificate)
|
||||
{
|
||||
NLSR_LOG_TRACE("Loading cert to publish.");
|
||||
m_certStore.insert(certificate);
|
||||
m_validator.loadAnchor("Authoritative-Certificate",
|
||||
ndn::security::v2::Certificate(certificate));
|
||||
m_prefixUpdateProcessor.getValidator().
|
||||
loadAnchor("Authoritative-Certificate",
|
||||
ndn::security::v2::Certificate(certificate));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
|
||||
{
|
||||
NLSR_LOG_TRACE("NLSR: Connect to SegmentFetcher.");
|
||||
|
||||
fetcher.afterSegmentValidated.connect(std::bind(&Nlsr::afterFetcherSignalEmitted,
|
||||
this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
|
||||
{
|
||||
NLSR_LOG_TRACE("SegmentFetcher fetched a data segment. Start inserting cert to own cert store.");
|
||||
ndn::Name keyName = lsaSegment.getSignature().getKeyLocator().getName();
|
||||
if (getCertificate(keyName) == nullptr) {
|
||||
publishCertFromCache(keyName);
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_TRACE("Certificate is already in the store: " << keyName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::publishCertFromCache(const ndn::Name& keyName)
|
||||
{
|
||||
const ndn::security::v2::Certificate* cert = m_validator.getUnverifiedCertCache()
|
||||
.find(keyName);
|
||||
if (cert != nullptr) {
|
||||
m_certStore.insert(*cert);
|
||||
NLSR_LOG_TRACE(*cert);
|
||||
NLSR_LOG_TRACE("Setting interest filter for: "
|
||||
<< ndn::security::v2::extractKeyNameFromCertName(cert->getName()));
|
||||
m_nlsrFace.setInterestFilter(ndn::security::v2::extractKeyNameFromCertName(cert->getName()),
|
||||
std::bind(&Nlsr::onKeyInterest,
|
||||
this, _1, _2),
|
||||
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
|
||||
if (!cert->getKeyName().equals(cert->getSignature().getKeyLocator().getName())) {
|
||||
publishCertFromCache(cert->getSignature().getKeyLocator().getName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_TRACE("Cert for " << keyName << " was not found in the Validator's cache. ");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::initialize()
|
||||
m_namePrefixList,
|
||||
m_lsdb)
|
||||
, m_statsCollector(m_lsdb, m_helloProtocol)
|
||||
, m_faceMonitor(m_face)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Initializing Nlsr");
|
||||
m_confParam.buildRouterPrefix();
|
||||
m_datasetHandler.setRouterNameCommandPrefix(m_confParam.getRouterPrefix());
|
||||
m_nlsrLsdb.setLsaRefreshTime(ndn::time::seconds(m_confParam.getLsaRefreshTime()));
|
||||
m_nlsrLsdb.setThisRouterPrefix(m_confParam.getRouterPrefix().toUri());
|
||||
m_fib.setEntryRefreshTime(2 * m_confParam.getLsaRefreshTime());
|
||||
|
||||
m_nlsrLsdb.getSequencingManager().setSeqFileDirectory(m_confParam.getSeqFileDir());
|
||||
m_nlsrLsdb.getSequencingManager().initiateSeqNoFromFile(m_confParam.getHyperbolicState());
|
||||
m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification, this, _1));
|
||||
m_faceMonitor.start();
|
||||
|
||||
m_nlsrLsdb.getSyncLogicHandler().createSyncSocket(m_confParam.getChronosyncPrefix(),
|
||||
m_confParam.getSyncInterestLifetime());
|
||||
m_fib.setStrategy(m_confParam.getLsaPrefix(), Fib::MULTICAST_STRATEGY, 0);
|
||||
m_fib.setStrategy(m_confParam.getSyncPrefix(), Fib::MULTICAST_STRATEGY, 0);
|
||||
|
||||
// Logging start
|
||||
m_confParam.writeLog();
|
||||
m_adjacencyList.writeLog();
|
||||
NLSR_LOG_DEBUG(m_namePrefixList);
|
||||
// Logging end
|
||||
NLSR_LOG_DEBUG("Default NLSR identity: " << m_confParam.getSigningInfo().getSignerName());
|
||||
|
||||
initializeKey();
|
||||
setStrategies();
|
||||
|
||||
NLSR_LOG_DEBUG("Default NLSR identity: " << m_signingInfo.getSignerName());
|
||||
|
||||
setInfoInterestFilter();
|
||||
setLsaInterestFilter();
|
||||
|
||||
// add top-level prefixes: router and localhost prefix
|
||||
// Add top-level prefixes: router and localhost prefix
|
||||
addDispatcherTopPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"));
|
||||
addDispatcherTopPrefix(LOCALHOST_PREFIX);
|
||||
|
||||
enableIncomingFaceIdIndication();
|
||||
|
||||
initializeFaces(std::bind(&Nlsr::processFaceDataset, this, _1),
|
||||
std::bind(&Nlsr::onFaceDatasetFetchTimeout, this, _1, _2, 0));
|
||||
|
||||
enableIncomingFaceIdIndication();
|
||||
|
||||
// Set event intervals
|
||||
setFirstHelloInterval(m_confParam.getFirstHelloInterval());
|
||||
m_nlsrLsdb.setAdjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval());
|
||||
m_routingTable.setRoutingCalcInterval(m_confParam.getRoutingCalcInterval());
|
||||
|
||||
m_nlsrLsdb.buildAndInstallOwnNameLsa();
|
||||
|
||||
// Install coordinate LSAs if using HR or dry-run HR.
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
|
||||
m_nlsrLsdb.buildAndInstallOwnCoordinateLsa();
|
||||
}
|
||||
|
||||
registerKeyPrefix();
|
||||
registerLocalhostPrefix();
|
||||
registerRouterPrefix();
|
||||
|
||||
m_helloProtocol.scheduleInterest(m_firstHelloInterval);
|
||||
m_adjacencyList.writeLog();
|
||||
NLSR_LOG_DEBUG(m_namePrefixList);
|
||||
|
||||
// Need to set direct neighbors' costs to 0 for hyperbolic routing
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
|
||||
std::list<Adjacent>& neighbors = m_adjacencyList.getAdjList();
|
||||
|
||||
for (std::list<Adjacent>::iterator it = neighbors.begin(); it != neighbors.end(); ++it) {
|
||||
it->setLinkCost(0);
|
||||
for (auto&& neighbor : m_adjacencyList.getAdjList()) {
|
||||
neighbor.setLinkCost(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::initializeKey()
|
||||
Nlsr::registerStrategyForCerts(const ndn::Name& originRouter)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Initializing Key ...");
|
||||
|
||||
ndn::Name nlsrInstanceName = m_confParam.getRouterPrefix();
|
||||
nlsrInstanceName.append("nlsr");
|
||||
|
||||
try {
|
||||
m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
|
||||
} catch (const std::exception& e) {
|
||||
NLSR_LOG_WARN(e.what());
|
||||
for (const ndn::Name& router : m_strategySetOnRouters) {
|
||||
if (router == originRouter) {
|
||||
// Have already set strategy for this router's certs once
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
|
||||
auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
|
||||
m_strategySetOnRouters.push_back(originRouter);
|
||||
|
||||
ndn::security::v2::Certificate certificate;
|
||||
ndn::Name routerKey(originRouter);
|
||||
routerKey.append(ndn::security::Certificate::KEY_COMPONENT);
|
||||
ndn::Name instanceKey(originRouter);
|
||||
instanceKey.append("nlsr").append(ndn::security::Certificate::KEY_COMPONENT);
|
||||
|
||||
ndn::Name certificateName = nlsrInstanceKey.getName();
|
||||
certificateName.append("NA");
|
||||
certificateName.appendVersion();
|
||||
certificate.setName(certificateName);
|
||||
m_fib.setStrategy(routerKey, Fib::BEST_ROUTE_STRATEGY, 0);
|
||||
m_fib.setStrategy(instanceKey, Fib::BEST_ROUTE_STRATEGY, 0);
|
||||
|
||||
// set metainfo
|
||||
certificate.setContentType(ndn::tlv::ContentType_Key);
|
||||
certificate.setFreshnessPeriod(ndn::time::days(365));
|
||||
ndn::Name siteKey;
|
||||
for (size_t i = 0; i < originRouter.size(); ++i) {
|
||||
if (originRouter[i].toUri() == "%C1.Router") {
|
||||
break;
|
||||
}
|
||||
siteKey.append(originRouter[i]);
|
||||
}
|
||||
ndn::Name opPrefix(siteKey);
|
||||
siteKey.append(ndn::security::Certificate::KEY_COMPONENT);
|
||||
m_fib.setStrategy(siteKey, Fib::BEST_ROUTE_STRATEGY, 0);
|
||||
|
||||
// set content
|
||||
certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
|
||||
opPrefix.append(std::string("%C1.Operator"));
|
||||
m_fib.setStrategy(opPrefix, Fib::BEST_ROUTE_STRATEGY, 0);
|
||||
}
|
||||
|
||||
// set signature-info
|
||||
ndn::SignatureInfo signatureInfo;
|
||||
signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
|
||||
ndn::time::system_clock::now()
|
||||
+ ndn::time::days(365)));
|
||||
void
|
||||
Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
|
||||
{
|
||||
registerPrefix(topPrefix);
|
||||
try {
|
||||
m_keyChain.sign(certificate,
|
||||
ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.getRouterPrefix()))
|
||||
.setSignatureInfo(signatureInfo));
|
||||
// false since we want to have control over the registration process
|
||||
m_dispatcher.addTopPrefix(topPrefix, false, m_confParam.getSigningInfo());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
NLSR_LOG_WARN("ERROR: Router's " << e.what()
|
||||
<< "NLSR is running without security."
|
||||
<< " If security is enabled NLSR will not converge.");
|
||||
|
||||
std::cerr << "Router's " << e.what() << ". NLSR is running without security "
|
||||
<< "(Only for testing, should not be used in production.)"
|
||||
<< " If security is enabled NLSR will not converge." << std::endl;
|
||||
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what());
|
||||
}
|
||||
|
||||
m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
|
||||
nlsrInstanceName);
|
||||
|
||||
loadCertToPublish(certificate);
|
||||
|
||||
m_defaultCertName = certificate.getName();
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registerKeyPrefix()
|
||||
Nlsr::registerPrefix(const ndn::Name& prefix)
|
||||
{
|
||||
// Start listening for the interest of this router's NLSR certificate
|
||||
ndn::Name nlsrKeyPrefix = getConfParameter().getRouterPrefix();
|
||||
nlsrKeyPrefix.append("nlsr");
|
||||
nlsrKeyPrefix.append("KEY");
|
||||
|
||||
m_nlsrFace.setInterestFilter(nlsrKeyPrefix,
|
||||
std::bind(&Nlsr::onKeyInterest,
|
||||
this, _1, _2),
|
||||
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
|
||||
// Start listening for the interest of this router's certificate
|
||||
ndn::Name routerKeyPrefix = getConfParameter().getRouterPrefix();
|
||||
routerKeyPrefix.append("KEY");
|
||||
|
||||
m_nlsrFace.setInterestFilter(routerKeyPrefix,
|
||||
std::bind(&Nlsr::onKeyInterest,
|
||||
this, _1, _2),
|
||||
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
|
||||
// Start listening for the interest of this router's operator's certificate
|
||||
ndn::Name operatorKeyPrefix = getConfParameter().getNetwork();
|
||||
operatorKeyPrefix.append(getConfParameter().getSiteName());
|
||||
operatorKeyPrefix.append(std::string("%C1.Operator"));
|
||||
|
||||
m_nlsrFace.setInterestFilter(operatorKeyPrefix,
|
||||
std::bind(&Nlsr::onKeyInterest,
|
||||
this, _1, _2),
|
||||
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
|
||||
// Start listening for the interest of this router's site's certificate
|
||||
ndn::Name siteKeyPrefix = getConfParameter().getNetwork();
|
||||
siteKeyPrefix.append(getConfParameter().getSiteName());
|
||||
siteKeyPrefix.append("KEY");
|
||||
|
||||
m_nlsrFace.setInterestFilter(siteKeyPrefix,
|
||||
std::bind(&Nlsr::onKeyInterest,
|
||||
this, _1, _2),
|
||||
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registerLocalhostPrefix()
|
||||
{
|
||||
m_nlsrFace.registerPrefix(LOCALHOST_PREFIX,
|
||||
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registerRouterPrefix()
|
||||
{
|
||||
m_nlsrFace.registerPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"),
|
||||
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Got interest for certificate. Interest: " << interest.getName());
|
||||
|
||||
const ndn::Name& interestName = interest.getName();
|
||||
const ndn::security::v2::Certificate* cert = getCertificate(interestName);
|
||||
|
||||
if (cert == nullptr) {
|
||||
NLSR_LOG_DEBUG("Certificate is not found for: " << interest);
|
||||
return; // cert is not found
|
||||
}
|
||||
|
||||
m_nlsrFace.put(*cert);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::onKeyPrefixRegSuccess(const ndn::Name& name)
|
||||
{
|
||||
NLSR_LOG_DEBUG("KEY prefix: " << name << " registration is successful.");
|
||||
m_face.registerPrefix(prefix,
|
||||
[] (const ndn::Name& name) {
|
||||
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
|
||||
},
|
||||
[] (const ndn::Name& name, const std::string& reason) {
|
||||
NLSR_LOG_ERROR("ERROR: Failed to register prefix " << name << " in local hub's daemon");
|
||||
NDN_THROW(Error("Error: Prefix registration failed: " + reason));
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNotification)
|
||||
{
|
||||
NLSR_LOG_TRACE("Nlsr::onFaceEventNotification called");
|
||||
NLSR_LOG_TRACE("onFaceEventNotification called");
|
||||
|
||||
switch (faceEventNotification.getKind()) {
|
||||
case ndn::nfd::FACE_EVENT_DESTROYED: {
|
||||
@@ -505,11 +207,13 @@ Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNo
|
||||
// has met the HELLO retry threshold
|
||||
adjacent->setInterestTimedOutNo(m_confParam.getInterestRetryNumber());
|
||||
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
|
||||
getRoutingTable().scheduleRoutingTableCalculation(*this);
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_routingTable.scheduleRoutingTableCalculation();
|
||||
}
|
||||
else {
|
||||
m_nlsrLsdb.scheduleAdjLsaBuild();
|
||||
// Will call scheduleRoutingTableCalculation internally
|
||||
// if needed in case of LS or DRY_RUN
|
||||
m_lsdb.scheduleAdjLsaBuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -526,23 +230,23 @@ Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNo
|
||||
return;
|
||||
}
|
||||
auto adjacent = m_adjacencyList.findAdjacent(faceUri);
|
||||
uint64_t faceId = faceEventNotification.getFaceId();
|
||||
|
||||
// If we have a neighbor by that FaceUri and it has no FaceId, we
|
||||
// have a match.
|
||||
if (adjacent != m_adjacencyList.end()) {
|
||||
// If we have a neighbor by that FaceUri and it has no FaceId or
|
||||
// the FaceId is different from ours, we have a match.
|
||||
if (adjacent != m_adjacencyList.end() &&
|
||||
(adjacent->getFaceId() == 0 || adjacent->getFaceId() != faceId))
|
||||
{
|
||||
NLSR_LOG_DEBUG("Face creation event matches neighbor: " << adjacent->getName()
|
||||
<< ". New Face ID: " << faceEventNotification.getFaceId()
|
||||
<< ". Registering prefixes.");
|
||||
adjacent->setFaceId(faceEventNotification.getFaceId());
|
||||
<< ". New Face ID: " << faceId << ". Registering prefixes.");
|
||||
adjacent->setFaceId(faceId);
|
||||
|
||||
registerAdjacencyPrefixes(*adjacent, ndn::time::milliseconds::max());
|
||||
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
|
||||
getRoutingTable().scheduleRoutingTableCalculation(*this);
|
||||
}
|
||||
else {
|
||||
m_nlsrLsdb.scheduleAdjLsaBuild();
|
||||
}
|
||||
// We should not do scheduleRoutingTableCalculation or scheduleAdjLsaBuild here
|
||||
// because once the prefixes are registered, we send a HelloInterest
|
||||
// to the prefix (see NLSR ctor). HelloProtocol will call these functions
|
||||
// once HelloData is received and validated.
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -555,10 +259,8 @@ void
|
||||
Nlsr::initializeFaces(const FetchDatasetCallback& onFetchSuccess,
|
||||
const FetchDatasetTimeoutCallback& onFetchFailure)
|
||||
{
|
||||
NLSR_LOG_TRACE("Initializing Faces...");
|
||||
|
||||
NLSR_LOG_TRACE("Initializing faces");
|
||||
m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(onFetchSuccess, onFetchFailure);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -567,11 +269,11 @@ Nlsr::processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces)
|
||||
NLSR_LOG_DEBUG("Processing face dataset");
|
||||
|
||||
// Iterate over each neighbor listed in nlsr.conf
|
||||
for (auto& adjacent : m_adjacencyList.getAdjList()) {
|
||||
for (auto&& adjacent : m_adjacencyList.getAdjList()) {
|
||||
|
||||
const std::string faceUriString = adjacent.getFaceUri().toString();
|
||||
const std::string& faceUriString = adjacent.getFaceUri().toString();
|
||||
// Check the list of FaceStatus objects we got for a match
|
||||
for (const ndn::nfd::FaceStatus& faceStatus : faces) {
|
||||
for (const auto& faceStatus : faces) {
|
||||
// Set the adjacency FaceID if we find a URI match and it was
|
||||
// previously unset. Change the boolean to true.
|
||||
if (adjacent.getFaceId() == 0 && faceUriString == faceStatus.getRemoteUri()) {
|
||||
@@ -596,8 +298,7 @@ Nlsr::processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces)
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
|
||||
const ndn::time::milliseconds& timeout)
|
||||
Nlsr::registerAdjacencyPrefixes(const Adjacent& adj, ndn::time::milliseconds timeout)
|
||||
{
|
||||
ndn::FaceUri faceUri = adj.getFaceUri();
|
||||
double linkCost = adj.getLinkCost();
|
||||
@@ -606,10 +307,6 @@ Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
|
||||
m_fib.registerPrefix(adjName, faceUri, linkCost,
|
||||
timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
|
||||
m_fib.registerPrefix(m_confParam.getChronosyncPrefix(),
|
||||
faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
|
||||
m_fib.registerPrefix(m_confParam.getLsaPrefix(),
|
||||
faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
@@ -620,14 +317,12 @@ Nlsr::onFaceDatasetFetchTimeout(uint32_t code,
|
||||
const std::string& msg,
|
||||
uint32_t nRetriesSoFar)
|
||||
{
|
||||
NLSR_LOG_DEBUG("onFaceDatasetFetchTimeout");
|
||||
// If we have exceeded the maximum attempt count, do not try again.
|
||||
if (nRetriesSoFar++ < m_confParam.getFaceDatasetFetchTries()) {
|
||||
NLSR_LOG_DEBUG("Failed to fetch dataset: " << msg << ". Attempting retry #" << nRetriesSoFar);
|
||||
m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(std::bind(&Nlsr::processFaceDataset,
|
||||
this, _1),
|
||||
std::bind(&Nlsr::onFaceDatasetFetchTimeout,
|
||||
this, _1, _2, nRetriesSoFar));
|
||||
m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(std::bind(&Nlsr::processFaceDataset, this, _1),
|
||||
std::bind(&Nlsr::onFaceDatasetFetchTimeout,
|
||||
this, _1, _2, nRetriesSoFar));
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_ERROR("Failed to fetch dataset: " << msg << ". Exceeded limit of " <<
|
||||
@@ -642,17 +337,12 @@ Nlsr::onFaceDatasetFetchTimeout(uint32_t code,
|
||||
void
|
||||
Nlsr::scheduleDatasetFetch()
|
||||
{
|
||||
NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval());
|
||||
NLSR_LOG_DEBUG("Scheduling dataset fetch in " << m_confParam.getFaceDatasetFetchInterval());
|
||||
|
||||
m_scheduler.scheduleEvent(m_confParam.getFaceDatasetFetchInterval(),
|
||||
[this] {
|
||||
this->initializeFaces(
|
||||
[this] (const std::vector<ndn::nfd::FaceStatus>& faces) {
|
||||
this->processFaceDataset(faces);
|
||||
},
|
||||
[this] (uint32_t code, const std::string& msg) {
|
||||
this->onFaceDatasetFetchTimeout(code, msg, 0);
|
||||
});
|
||||
m_scheduler.schedule(m_confParam.getFaceDatasetFetchInterval(), [this] {
|
||||
initializeFaces(
|
||||
[this] (const auto& faces) { processFaceDataset(faces); },
|
||||
[this] (uint32_t code, const std::string& msg) { onFaceDatasetFetchTimeout(code, msg, 0); });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -664,31 +354,14 @@ Nlsr::enableIncomingFaceIdIndication()
|
||||
m_controller.start<ndn::nfd::FaceUpdateCommand>(
|
||||
ndn::nfd::ControlParameters()
|
||||
.setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED, true),
|
||||
bind(&Nlsr::onFaceIdIndicationSuccess, this, _1),
|
||||
bind(&Nlsr::onFaceIdIndicationFailure, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
|
||||
<< "for face id " << cp.getFaceId());
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to enable incoming face id indication feature: " <<
|
||||
"(code: " << cr.getCode() << ", reason: " << cr.getText() << ")";
|
||||
|
||||
NLSR_LOG_DEBUG(os.str());
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::startEventLoop()
|
||||
{
|
||||
m_nlsrFace.processEvents();
|
||||
[] (const ndn::nfd::ControlParameters& cp) {
|
||||
NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
|
||||
<< "for face id " << cp.getFaceId());
|
||||
},
|
||||
[] (const ndn::nfd::ControlResponse& cr) {
|
||||
NLSR_LOG_WARN("Failed to enable incoming face id indication feature: " <<
|
||||
"(code: " << cr.getCode() << ", reason: " << cr.getText() << ")");
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+49
-389
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,13 +17,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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NLSR_HPP
|
||||
#define NLSR_NLSR_HPP
|
||||
|
||||
#include "adjacency-list.hpp"
|
||||
#include "common.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
#include "hello-protocol.hpp"
|
||||
#include "lsdb.hpp"
|
||||
@@ -33,37 +32,24 @@
|
||||
#include "route/fib.hpp"
|
||||
#include "route/name-prefix-table.hpp"
|
||||
#include "route/routing-table.hpp"
|
||||
#include "security/certificate-store.hpp"
|
||||
#include "update/prefix-update-processor.hpp"
|
||||
#include "update/nfd-rib-command-processor.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
#include "stats-collector.hpp"
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <stdexcept>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
#include <ndn-cxx/security/validator-config.hpp>
|
||||
#include <ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp>
|
||||
#include <ndn-cxx/security/signing-helpers.hpp>
|
||||
#include <ndn-cxx/security/signing-info.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
#include <ndn-cxx/encoding/nfd-constants.hpp>
|
||||
#include <ndn-cxx/mgmt/dispatcher.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
|
||||
#include <ndn-cxx/mgmt/dispatcher.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
|
||||
#include <ndn-cxx/data.hpp>
|
||||
#include <ndn-cxx/encoding/block.hpp>
|
||||
#include <ndn-cxx/encoding/nfd-constants.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
|
||||
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
static ndn::Name DEFAULT_BROADCAST_PREFIX("/ndn/broadcast");
|
||||
|
||||
class Nlsr
|
||||
{
|
||||
public:
|
||||
@@ -73,26 +59,26 @@ public:
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::Face& face, ndn::KeyChain& keyChain);
|
||||
Nlsr(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam);
|
||||
|
||||
void
|
||||
registrationFailed(const ndn::Name& name);
|
||||
Lsdb&
|
||||
getLsdb()
|
||||
{
|
||||
return m_lsdb;
|
||||
}
|
||||
|
||||
void
|
||||
onRegistrationSuccess(const ndn::Name& name);
|
||||
Fib&
|
||||
getFib()
|
||||
{
|
||||
return m_fib;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
setInfoInterestFilter();
|
||||
|
||||
void
|
||||
setLsaInterestFilter();
|
||||
registerStrategyForCerts(const ndn::Name& originRouter);
|
||||
|
||||
/*! \brief Add top level prefixes for Dispatcher
|
||||
*
|
||||
@@ -102,150 +88,7 @@ public:
|
||||
void
|
||||
addDispatcherTopPrefix(const ndn::Name& topPrefix);
|
||||
|
||||
void
|
||||
startEventLoop();
|
||||
|
||||
std::string
|
||||
getConfFileName() const
|
||||
{
|
||||
return m_configFileName;
|
||||
}
|
||||
|
||||
void
|
||||
setConfFileName(const std::string& fileName)
|
||||
{
|
||||
m_configFileName = fileName;
|
||||
}
|
||||
|
||||
ConfParameter&
|
||||
getConfParameter()
|
||||
{
|
||||
return m_confParam;
|
||||
}
|
||||
|
||||
const ConfParameter&
|
||||
getConfParameter() const
|
||||
{
|
||||
return m_confParam;
|
||||
}
|
||||
|
||||
AdjacencyList&
|
||||
getAdjacencyList()
|
||||
{
|
||||
return m_adjacencyList;
|
||||
}
|
||||
|
||||
const AdjacencyList&
|
||||
getAdjacencyList() const
|
||||
{
|
||||
return m_adjacencyList;
|
||||
}
|
||||
|
||||
NamePrefixList&
|
||||
getNamePrefixList()
|
||||
{
|
||||
return m_namePrefixList;
|
||||
}
|
||||
|
||||
const NamePrefixList&
|
||||
getNamePrefixList() const
|
||||
{
|
||||
return m_namePrefixList;
|
||||
}
|
||||
|
||||
ndn::Face&
|
||||
getNlsrFace()
|
||||
{
|
||||
return m_nlsrFace;
|
||||
}
|
||||
|
||||
Lsdb&
|
||||
getLsdb()
|
||||
{
|
||||
return m_nlsrLsdb;
|
||||
}
|
||||
|
||||
RoutingTable&
|
||||
getRoutingTable()
|
||||
{
|
||||
return m_routingTable;
|
||||
}
|
||||
|
||||
NamePrefixTable&
|
||||
getNamePrefixTable()
|
||||
{
|
||||
return m_namePrefixTable;
|
||||
}
|
||||
|
||||
Fib&
|
||||
getFib()
|
||||
{
|
||||
return m_fib;
|
||||
}
|
||||
|
||||
long int
|
||||
getAdjBuildCount()
|
||||
{
|
||||
return m_adjBuildCount;
|
||||
}
|
||||
|
||||
void
|
||||
incrementAdjBuildCount()
|
||||
{
|
||||
m_adjBuildCount++;
|
||||
}
|
||||
|
||||
void
|
||||
setAdjBuildCount(int64_t abc)
|
||||
{
|
||||
m_adjBuildCount = abc;
|
||||
}
|
||||
|
||||
bool
|
||||
getIsBuildAdjLsaSheduled()
|
||||
{
|
||||
return m_isBuildAdjLsaSheduled;
|
||||
}
|
||||
|
||||
void
|
||||
setIsBuildAdjLsaSheduled(bool iabls)
|
||||
{
|
||||
m_isBuildAdjLsaSheduled = iabls;
|
||||
}
|
||||
|
||||
bool
|
||||
getIsRoutingTableCalculating()
|
||||
{
|
||||
return m_isRoutingTableCalculating;
|
||||
}
|
||||
|
||||
void
|
||||
setIsRoutingTableCalculating(bool irtc)
|
||||
{
|
||||
m_isRoutingTableCalculating = irtc;
|
||||
}
|
||||
|
||||
bool
|
||||
getIsRouteCalculationScheduled()
|
||||
{
|
||||
return m_isRouteCalculationScheduled;
|
||||
}
|
||||
|
||||
void
|
||||
setIsRouteCalculationScheduled(bool ircs)
|
||||
{
|
||||
m_isRouteCalculationScheduled = ircs;
|
||||
}
|
||||
|
||||
DatasetInterestHandler&
|
||||
getDatasetHandler()
|
||||
{
|
||||
return m_datasetHandler;
|
||||
}
|
||||
|
||||
void
|
||||
initialize();
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Initializes neighbors' Faces using information from NFD.
|
||||
* \sa Nlsr::initialize()
|
||||
* \sa Nlsr::processFaceDataset()
|
||||
@@ -278,6 +121,7 @@ public:
|
||||
void
|
||||
processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces);
|
||||
|
||||
private:
|
||||
/*! \brief Registers NLSR-specific prefixes for a neighbor (Adjacent)
|
||||
* \sa Nlsr::initializeFaces
|
||||
* \param adj A reference to the neighbor to register prefixes for
|
||||
@@ -288,191 +132,18 @@ public:
|
||||
* *each* registration request that is made.
|
||||
*/
|
||||
void
|
||||
registerAdjacencyPrefixes(const Adjacent& adj,
|
||||
const ndn::time::milliseconds& timeout);
|
||||
registerAdjacencyPrefixes(const Adjacent& adj, ndn::time::milliseconds timeout);
|
||||
|
||||
/*! \brief Add a certificate NLSR claims to be authoritative for to the certificate store.
|
||||
*
|
||||
* \sa CertificateStore
|
||||
/*! \brief Registers the prefix
|
||||
*/
|
||||
void
|
||||
loadCertToPublish(const ndn::security::v2::Certificate& certificate);
|
||||
|
||||
void
|
||||
connectToFetcher(ndn::util::SegmentFetcher& fetcher);
|
||||
|
||||
/*! \brief Callback when SegmentFetcher retrieves a segment.
|
||||
*/
|
||||
void
|
||||
afterFetcherSignalEmitted(const ndn::Data& lsaSegment);
|
||||
|
||||
/*! \brief Retrieves the chain of certificates from Validator's cache and
|
||||
* store them in Nlsr's own CertificateStore.
|
||||
* \param keyName Name of the first key in the certificate chain.
|
||||
*/
|
||||
void
|
||||
publishCertFromCache(const ndn::Name& keyName);
|
||||
|
||||
void
|
||||
initializeKey();
|
||||
|
||||
void
|
||||
loadValidator(boost::property_tree::ptree section,
|
||||
const std::string& filename)
|
||||
{
|
||||
m_validator.load(section, filename);
|
||||
}
|
||||
|
||||
ndn::security::ValidatorConfig&
|
||||
getValidator()
|
||||
{
|
||||
return m_validator;
|
||||
}
|
||||
|
||||
/*! \brief Find a certificate
|
||||
*
|
||||
* Find a certificate that NLSR has. First it checks against the
|
||||
* certificates this NLSR claims to be authoritative for, usually
|
||||
* something like this specific router's certificate, and then
|
||||
* checks the cache of certficates it has already fetched. If none
|
||||
* can be found, it will return an empty pointer.
|
||||
*/
|
||||
const ndn::security::v2::Certificate*
|
||||
getCertificate(const ndn::Name& certificateKeyName)
|
||||
{
|
||||
const ndn::security::v2::Certificate* cert =
|
||||
m_certStore.find(certificateKeyName);
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
ndn::security::v2::KeyChain&
|
||||
getKeyChain()
|
||||
{
|
||||
return m_keyChain;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getDefaultCertName()
|
||||
{
|
||||
return m_defaultCertName;
|
||||
}
|
||||
|
||||
const ndn::security::SigningInfo&
|
||||
getSigningInfo()
|
||||
{
|
||||
return m_signingInfo;
|
||||
}
|
||||
|
||||
update::PrefixUpdateProcessor&
|
||||
getPrefixUpdateProcessor()
|
||||
{
|
||||
return m_prefixUpdateProcessor;
|
||||
}
|
||||
|
||||
update::NfdRibCommandProcessor&
|
||||
getNfdRibCommandProcessor()
|
||||
{
|
||||
return m_nfdRibCommandProcessor;
|
||||
}
|
||||
|
||||
ndn::mgmt::Dispatcher&
|
||||
getDispatcher()
|
||||
{
|
||||
return m_dispatcher;
|
||||
}
|
||||
|
||||
void
|
||||
setStrategies();
|
||||
|
||||
uint32_t
|
||||
getFirstHelloInterval() const
|
||||
{
|
||||
return m_firstHelloInterval;
|
||||
}
|
||||
|
||||
/*! \brief Canonize the URI for this and all proceeding neighbors in a list.
|
||||
*
|
||||
* This function canonizes the URI of the Adjacent object pointed to
|
||||
* by currentNeighbor. It then executes the then callback, providing
|
||||
* the next iterator in the list to the callback. A standard
|
||||
* invocation would be to pass the begin() iterator of NLSR's
|
||||
* adjacency list, and to provide Nlsr::canonizeContinuation as the
|
||||
* callback. Because every URI must be canonical before we begin
|
||||
* operations, the canonize function provides a finally() function
|
||||
* to resume whatever needs to occur.
|
||||
*
|
||||
* \sa Nlsr::canonizeContinuation
|
||||
* \sa Nlsr::initialize
|
||||
* \sa NlsrRunner::run
|
||||
*/
|
||||
void
|
||||
canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
|
||||
std::function<void(std::list<Adjacent>::iterator)> then,
|
||||
std::function<void(void)> finally);
|
||||
|
||||
StatsCollector&
|
||||
getStatsCollector()
|
||||
{
|
||||
return m_statsCollector;
|
||||
}
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
|
||||
security::CertificateStore&
|
||||
getCertificateStore()
|
||||
{
|
||||
return m_certStore;
|
||||
}
|
||||
|
||||
private:
|
||||
/*! \brief Registers the prefix that NLSR will use for key/certificate interests.
|
||||
*/
|
||||
void
|
||||
registerKeyPrefix();
|
||||
|
||||
/*! \brief Registers the prefix that NLSR will consider to be the machine-local, secure prefix.
|
||||
*/
|
||||
void
|
||||
registerLocalhostPrefix();
|
||||
|
||||
/*! \brief Registers the <router-prefix>/nlsr so that NLSR can respond to status requests from remote routers.
|
||||
*/
|
||||
void
|
||||
registerRouterPrefix();
|
||||
|
||||
/*! \brief Attempts to satisfy an Interest for a certificate, and send it back.
|
||||
*/
|
||||
void
|
||||
onKeyInterest(const ndn::Name& name, const ndn::Interest& interest);
|
||||
|
||||
/*! \brief Do nothing.
|
||||
*/
|
||||
void
|
||||
onKeyPrefixRegSuccess(const ndn::Name& name);
|
||||
registerPrefix(const ndn::Name& prefix);
|
||||
|
||||
/*! \brief Do nothing.
|
||||
*/
|
||||
void
|
||||
onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNotification);
|
||||
|
||||
void
|
||||
setFirstHelloInterval(uint32_t interval)
|
||||
{
|
||||
m_firstHelloInterval = interval;
|
||||
}
|
||||
|
||||
/*! \brief Continues canonizing neighbor URIs.
|
||||
*
|
||||
* For testability reasons, we want what each instance of
|
||||
* canonization does after completion to be controllable. The best
|
||||
* way to do this is to control that by simply passing a
|
||||
* continuation function.
|
||||
*/
|
||||
void
|
||||
canonizeContinuation(std::list<Adjacent>::iterator iterator,
|
||||
std::function<void(void)> finally);
|
||||
|
||||
void
|
||||
scheduleDatasetFetch();
|
||||
|
||||
@@ -486,60 +157,49 @@ private:
|
||||
void
|
||||
enableIncomingFaceIdIndication();
|
||||
|
||||
void
|
||||
onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp);
|
||||
|
||||
void
|
||||
onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr);
|
||||
|
||||
public:
|
||||
static const ndn::Name LOCALHOST_PREFIX;
|
||||
static inline const ndn::Name LOCALHOST_PREFIX{"/localhost/nlsr"};
|
||||
|
||||
private:
|
||||
ndn::Face& m_nlsrFace;
|
||||
ndn::Scheduler& m_scheduler;
|
||||
ndn::security::v2::KeyChain& m_keyChain;
|
||||
ConfParameter m_confParam;
|
||||
AdjacencyList m_adjacencyList;
|
||||
NamePrefixList m_namePrefixList;
|
||||
std::string m_configFileName;
|
||||
Lsdb m_nlsrLsdb;
|
||||
int64_t m_adjBuildCount;
|
||||
bool m_isBuildAdjLsaSheduled;
|
||||
bool m_isRouteCalculationScheduled;
|
||||
bool m_isRoutingTableCalculating;
|
||||
RoutingTable m_routingTable;
|
||||
Fib m_fib;
|
||||
NamePrefixTable m_namePrefixTable;
|
||||
|
||||
ndn::mgmt::Dispatcher m_dispatcher;
|
||||
|
||||
DatasetInterestHandler m_datasetHandler;
|
||||
ndn::Face& m_face;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ConfParameter& m_confParam;
|
||||
AdjacencyList& m_adjacencyList;
|
||||
NamePrefixList& m_namePrefixList;
|
||||
std::vector<ndn::Name> m_strategySetOnRouters;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
Fib m_fib;
|
||||
Lsdb m_lsdb;
|
||||
RoutingTable m_routingTable;
|
||||
NamePrefixTable m_namePrefixTable;
|
||||
HelloProtocol m_helloProtocol;
|
||||
|
||||
ndn::security::ValidatorConfig m_validator;
|
||||
private:
|
||||
ndn::signal::ScopedConnection m_onNewLsaConnection;
|
||||
ndn::signal::ScopedConnection m_onPrefixRegistrationSuccess;
|
||||
ndn::signal::ScopedConnection m_onInitialHelloDataValidated;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
ndn::mgmt::Dispatcher m_dispatcher;
|
||||
DatasetInterestHandler m_datasetHandler;
|
||||
|
||||
private:
|
||||
/*! \brief Where NLSR stores certificates it claims to be
|
||||
* authoritative for. Usually the router certificate.
|
||||
*/
|
||||
security::CertificateStore m_certStore;
|
||||
|
||||
ndn::nfd::Controller m_controller;
|
||||
ndn::nfd::Controller m_faceDatasetController;
|
||||
ndn::security::SigningInfo m_signingInfo;
|
||||
ndn::Name m_defaultCertName;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
update::PrefixUpdateProcessor m_prefixUpdateProcessor;
|
||||
update::NfdRibCommandProcessor m_nfdRibCommandProcessor;
|
||||
|
||||
StatsCollector m_statsCollector;
|
||||
|
||||
private:
|
||||
ndn::nfd::FaceMonitor m_faceMonitor;
|
||||
|
||||
uint32_t m_firstHelloInterval;
|
||||
|
||||
friend class NlsrRunner;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,11 +17,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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "dataset-interest-handler.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "tlv/lsdb-status.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
|
||||
@@ -31,238 +30,51 @@ namespace nlsr {
|
||||
|
||||
INIT_LOGGER(DatasetInterestHandler);
|
||||
|
||||
const ndn::PartialName ADJACENCIES_DATASET = ndn::PartialName("lsdb/adjacencies");
|
||||
const ndn::PartialName COORDINATES_DATASET = ndn::PartialName("lsdb/coordinates");
|
||||
const ndn::PartialName NAMES_DATASET = ndn::PartialName("lsdb/names");
|
||||
const ndn::PartialName RT_DATASET = ndn::PartialName("routing-table");
|
||||
const ndn::PartialName ADJACENCIES_DATASET{"lsdb/adjacencies"};
|
||||
const ndn::PartialName COORDINATES_DATASET{"lsdb/coordinates"};
|
||||
const ndn::PartialName NAMES_DATASET{"lsdb/names"};
|
||||
const ndn::PartialName RT_DATASET{"routing-table"};
|
||||
|
||||
DatasetInterestHandler::DatasetInterestHandler(const Lsdb& lsdb,
|
||||
const RoutingTable& rt,
|
||||
ndn::mgmt::Dispatcher& dispatcher,
|
||||
const ndn::Face& face,
|
||||
const ndn::KeyChain& keyChain)
|
||||
DatasetInterestHandler::DatasetInterestHandler(ndn::mgmt::Dispatcher& dispatcher,
|
||||
const Lsdb& lsdb,
|
||||
const RoutingTable& rt)
|
||||
: m_lsdb(lsdb)
|
||||
, m_dispatcher(dispatcher)
|
||||
, m_routingTableEntries(rt.getRoutingTableEntry())
|
||||
, m_dryRoutingTableEntries(rt.getDryRoutingTableEntry())
|
||||
{
|
||||
setDispatcher(m_dispatcher);
|
||||
}
|
||||
|
||||
void
|
||||
DatasetInterestHandler::setDispatcher(ndn::mgmt::Dispatcher& dispatcher)
|
||||
, m_routingTable(rt)
|
||||
{
|
||||
dispatcher.addStatusDataset(ADJACENCIES_DATASET,
|
||||
ndn::mgmt::makeAcceptAllAuthorization(),
|
||||
std::bind(&DatasetInterestHandler::publishAdjStatus, this, _1, _2, _3));
|
||||
std::bind(&DatasetInterestHandler::publishLsaStatus<AdjLsa>, this, _1, _2, _3));
|
||||
dispatcher.addStatusDataset(COORDINATES_DATASET,
|
||||
ndn::mgmt::makeAcceptAllAuthorization(),
|
||||
std::bind(&DatasetInterestHandler::publishCoordinateStatus, this, _1, _2, _3));
|
||||
std::bind(&DatasetInterestHandler::publishLsaStatus<CoordinateLsa>, this, _1, _2, _3));
|
||||
dispatcher.addStatusDataset(NAMES_DATASET,
|
||||
ndn::mgmt::makeAcceptAllAuthorization(),
|
||||
std::bind(&DatasetInterestHandler::publishNameStatus, this, _1, _2, _3));
|
||||
std::bind(&DatasetInterestHandler::publishLsaStatus<NameLsa>, this, _1, _2, _3));
|
||||
dispatcher.addStatusDataset(RT_DATASET,
|
||||
ndn::mgmt::makeAcceptAllAuthorization(),
|
||||
std::bind(&DatasetInterestHandler::publishRtStatus, this, _1, _2, _3));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
DatasetInterestHandler::publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
DatasetInterestHandler::publishLsaStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Received interest: " << interest);
|
||||
|
||||
auto lsaRange = std::make_pair<std::list<AdjLsa>::const_iterator,
|
||||
std::list<AdjLsa>::const_iterator>(
|
||||
m_lsdb.getAdjLsdb().cbegin(), m_lsdb.getAdjLsdb().cend());
|
||||
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
|
||||
tlv::AdjacencyLsa tlvLsa;
|
||||
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
|
||||
tlvLsa.setLsaInfo(*tlvLsaInfo);
|
||||
|
||||
for (const Adjacent& adj : lsa->getAdl().getAdjList()) {
|
||||
tlv::Adjacency tlvAdj;
|
||||
tlvAdj.setName(adj.getName());
|
||||
tlvAdj.setUri(adj.getFaceUri().toString());
|
||||
tlvAdj.setCost(adj.getLinkCost());
|
||||
tlvLsa.addAdjacency(tlvAdj);
|
||||
}
|
||||
const ndn::Block& wire = tlvLsa.wireEncode();
|
||||
context.append(wire);
|
||||
NLSR_LOG_TRACE("Received interest: " << interest);
|
||||
auto lsaRange = m_lsdb.getLsdbIterator<T>();
|
||||
for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
|
||||
context.append((*lsaIt)->wireEncode());
|
||||
}
|
||||
context.end();
|
||||
}
|
||||
|
||||
void
|
||||
DatasetInterestHandler::publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context)
|
||||
{
|
||||
auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
|
||||
std::list<CoordinateLsa>::const_iterator>(
|
||||
m_lsdb.getCoordinateLsdb().cbegin(), m_lsdb.getCoordinateLsdb().cend());
|
||||
|
||||
NLSR_LOG_DEBUG("Received interest: " << interest);
|
||||
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
|
||||
tlv::CoordinateLsa tlvLsa;
|
||||
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
|
||||
tlvLsa.setLsaInfo(*tlvLsaInfo);
|
||||
|
||||
tlvLsa.setHyperbolicRadius(lsa->getCorRadius());
|
||||
tlvLsa.setHyperbolicAngle(lsa->getCorTheta());
|
||||
|
||||
const ndn::Block& wire = tlvLsa.wireEncode();
|
||||
context.append(wire);
|
||||
}
|
||||
context.end();
|
||||
}
|
||||
|
||||
void
|
||||
DatasetInterestHandler::publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context)
|
||||
{
|
||||
auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator, std::list<NameLsa>::const_iterator>(
|
||||
m_lsdb.getNameLsdb().cbegin(), m_lsdb.getNameLsdb().cend());
|
||||
NLSR_LOG_DEBUG("Received interest: " << interest);
|
||||
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
|
||||
tlv::NameLsa tlvLsa;
|
||||
|
||||
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
|
||||
tlvLsa.setLsaInfo(*tlvLsaInfo);
|
||||
|
||||
for (const ndn::Name& name : lsa->getNpl().getNames()) {
|
||||
tlvLsa.addName(name);
|
||||
}
|
||||
|
||||
const ndn::Block& wire = tlvLsa.wireEncode();
|
||||
context.append(wire);
|
||||
}
|
||||
context.end();
|
||||
}
|
||||
|
||||
|
||||
std::vector<tlv::RoutingTable>
|
||||
DatasetInterestHandler::getTlvRTEntries()
|
||||
{
|
||||
std::vector<tlv::RoutingTable> rtable;
|
||||
for (const auto& rte : m_routingTableEntries) {
|
||||
tlv::RoutingTable tlvRoutingTable;
|
||||
std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(rte);
|
||||
tlvRoutingTable.setDestination(*tlvDes);
|
||||
for (const auto& nh : rte.getNexthopList().getNextHops()) {
|
||||
tlv::NextHop tlvNexthop;
|
||||
tlvNexthop.setUri(nh.getConnectingFaceUri());
|
||||
tlvNexthop.setCost(nh.getRouteCost());
|
||||
tlvRoutingTable.addNexthops(tlvNexthop);
|
||||
}
|
||||
rtable.push_back(tlvRoutingTable);
|
||||
}
|
||||
if (!m_dryRoutingTableEntries.empty()) {
|
||||
for (const auto& dryRte : m_dryRoutingTableEntries) {
|
||||
tlv::RoutingTable tlvRoutingTable;
|
||||
std::shared_ptr<tlv::Destination> tlvDes = tlv::makeDes(dryRte);
|
||||
tlvRoutingTable.setDestination(*tlvDes);
|
||||
for (const auto& nh : dryRte.getNexthopList().getNextHops()) {
|
||||
tlv::NextHop tlvNexthop;
|
||||
tlvNexthop.setUri(nh.getConnectingFaceUri());
|
||||
tlvNexthop.setCost(nh.getRouteCost());
|
||||
tlvRoutingTable.addNexthops(tlvNexthop);
|
||||
}
|
||||
rtable.push_back(tlvRoutingTable);
|
||||
}
|
||||
}
|
||||
return rtable;
|
||||
}
|
||||
|
||||
void
|
||||
DatasetInterestHandler::publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Received interest: " << interest);
|
||||
tlv::RoutingTableStatus rtStatus;
|
||||
for (const tlv::RoutingTable& rt : getTlvRTEntries()) {
|
||||
rtStatus.addRoutingTable(rt);
|
||||
}
|
||||
const ndn::Block& wire = rtStatus.wireEncode();
|
||||
context.append(wire);
|
||||
NLSR_LOG_TRACE("Received interest: " << interest);
|
||||
context.append(m_routingTable.wireEncode());
|
||||
context.end();
|
||||
}
|
||||
|
||||
template<> std::list<tlv::AdjacencyLsa>
|
||||
getTlvLsas<tlv::AdjacencyLsa>(const Lsdb& lsdb)
|
||||
{
|
||||
std::list<tlv::AdjacencyLsa> lsas;
|
||||
|
||||
auto lsaRange = std::make_pair<std::list<AdjLsa>::const_iterator,
|
||||
std::list<AdjLsa>::const_iterator>(
|
||||
lsdb.getAdjLsdb().cbegin(), lsdb.getAdjLsdb().cend());
|
||||
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
|
||||
tlv::AdjacencyLsa tlvLsa;
|
||||
|
||||
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
|
||||
tlvLsa.setLsaInfo(*tlvLsaInfo);
|
||||
|
||||
for (const Adjacent& adj : lsa->getAdl().getAdjList()) {
|
||||
tlv::Adjacency tlvAdj;
|
||||
tlvAdj.setName(adj.getName());
|
||||
tlvAdj.setUri(adj.getFaceUri().toString());
|
||||
tlvAdj.setCost(adj.getLinkCost());
|
||||
tlvLsa.addAdjacency(tlvAdj);
|
||||
}
|
||||
lsas.push_back(tlvLsa);
|
||||
}
|
||||
|
||||
return lsas;
|
||||
|
||||
}
|
||||
|
||||
template<> std::list<tlv::CoordinateLsa>
|
||||
getTlvLsas<tlv::CoordinateLsa>(const Lsdb& lsdb)
|
||||
{
|
||||
std::list<tlv::CoordinateLsa> lsas;
|
||||
|
||||
auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
|
||||
std::list<CoordinateLsa>::const_iterator>(
|
||||
lsdb.getCoordinateLsdb().cbegin(), lsdb.getCoordinateLsdb().cend());
|
||||
|
||||
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
|
||||
tlv::CoordinateLsa tlvLsa;
|
||||
|
||||
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
|
||||
tlvLsa.setLsaInfo(*tlvLsaInfo);
|
||||
|
||||
tlvLsa.setHyperbolicRadius(lsa->getCorRadius());
|
||||
tlvLsa.setHyperbolicAngle(lsa->getCorTheta());
|
||||
|
||||
lsas.push_back(tlvLsa);
|
||||
}
|
||||
|
||||
return lsas;
|
||||
|
||||
}
|
||||
|
||||
template<> std::list<tlv::NameLsa>
|
||||
getTlvLsas<tlv::NameLsa>(const Lsdb& lsdb)
|
||||
{
|
||||
std::list<tlv::NameLsa> lsas;
|
||||
|
||||
auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator,
|
||||
std::list<NameLsa>::const_iterator>(
|
||||
lsdb.getNameLsdb().cbegin(), lsdb.getNameLsdb().cend());
|
||||
for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
|
||||
tlv::NameLsa tlvLsa;
|
||||
|
||||
std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
|
||||
tlvLsa.setLsaInfo(*tlvLsaInfo);
|
||||
|
||||
for (const ndn::Name& name : lsa->getNpl().getNames()) {
|
||||
tlvLsa.addName(name);
|
||||
}
|
||||
|
||||
lsas.push_back(tlvLsa);
|
||||
}
|
||||
|
||||
return lsas;
|
||||
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
/*! \file dataset-interest-handler.hpp
|
||||
|
||||
@@ -35,23 +35,17 @@
|
||||
#include "route/routing-table.hpp"
|
||||
#include "route/nexthop-list.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include "tlv/adjacency-lsa.hpp"
|
||||
#include "tlv/coordinate-lsa.hpp"
|
||||
#include "tlv/name-lsa.hpp"
|
||||
#include "tlv/routing-table-status.hpp"
|
||||
#include "tlv/routing-table-entry.hpp"
|
||||
|
||||
#include <ndn-cxx/mgmt/dispatcher.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/mgmt/dispatcher.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
namespace dataset {
|
||||
const ndn::Name::Component ADJACENCY_COMPONENT = ndn::Name::Component{"adjacencies"};
|
||||
const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component{"names"};
|
||||
const ndn::Name::Component COORDINATE_COMPONENT = ndn::Name::Component{"coordinates"};
|
||||
inline const ndn::Name::Component ADJACENCY_COMPONENT{"adjacencies"};
|
||||
inline const ndn::Name::Component NAME_COMPONENT{"names"};
|
||||
inline const ndn::Name::Component COORDINATE_COMPONENT{"coordinates"};
|
||||
} // namespace dataset
|
||||
|
||||
/*!
|
||||
@@ -65,88 +59,32 @@ public:
|
||||
class Error : std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
DatasetInterestHandler(const Lsdb& lsdb,
|
||||
const RoutingTable& rt,
|
||||
ndn::mgmt::Dispatcher& dispatcher,
|
||||
const ndn::Face& face,
|
||||
const ndn::KeyChain& keyChain);
|
||||
|
||||
ndn::Name&
|
||||
getRouterNameCommandPrefix()
|
||||
{
|
||||
return m_routerNamePrefix;
|
||||
}
|
||||
|
||||
void
|
||||
setRouterNameCommandPrefix(const ndn::Name& routerName) {
|
||||
m_routerNamePrefix = routerName;
|
||||
m_routerNamePrefix.append(Lsdb::NAME_COMPONENT);
|
||||
}
|
||||
DatasetInterestHandler(ndn::mgmt::Dispatcher& dispatcher,
|
||||
const Lsdb& lsdb,
|
||||
const RoutingTable& rt);
|
||||
|
||||
private:
|
||||
/*! \brief set dispatcher for localhost or remote router
|
||||
*/
|
||||
void
|
||||
setDispatcher(ndn::mgmt::Dispatcher& dispatcher);
|
||||
|
||||
/*! \brief generate a TLV-format of routing table entry
|
||||
*/
|
||||
std::vector<tlv::RoutingTable>
|
||||
getTlvRTEntries();
|
||||
|
||||
/*! \brief provide routing-table dataset
|
||||
*/
|
||||
void
|
||||
publishRtStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context);
|
||||
|
||||
/*! \brief provide adjacent status dataset
|
||||
/*! \brief provide LSA status dataset
|
||||
*/
|
||||
template<typename T>
|
||||
void
|
||||
publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
publishLsaStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context);
|
||||
|
||||
/*! \brief provide coordinate status dataset
|
||||
*/
|
||||
void
|
||||
publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context);
|
||||
|
||||
/*! \brief provide name status dataset
|
||||
*/
|
||||
void
|
||||
publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context);
|
||||
|
||||
private:
|
||||
const Lsdb& m_lsdb;
|
||||
ndn::Name m_routerNamePrefix;
|
||||
|
||||
ndn::mgmt::Dispatcher& m_dispatcher;
|
||||
|
||||
const std::list<RoutingTableEntry>& m_routingTableEntries;
|
||||
const std::list<RoutingTableEntry>& m_dryRoutingTableEntries;
|
||||
const RoutingTable& m_routingTable;
|
||||
};
|
||||
|
||||
template<typename T> std::list<T>
|
||||
getTlvLsas(const Lsdb& lsdb);
|
||||
|
||||
template<> std::list<tlv::AdjacencyLsa>
|
||||
getTlvLsas<tlv::AdjacencyLsa>(const Lsdb& lsdb);
|
||||
|
||||
template<> std::list<tlv::CoordinateLsa>
|
||||
getTlvLsas<tlv::CoordinateLsa>(const Lsdb& lsdb);
|
||||
|
||||
template<> std::list<tlv::NameLsa>
|
||||
getTlvLsas<tlv::NameLsa>(const Lsdb& lsdb);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_PUBLISHER_DATASET_INTEREST_HANDLER_HPP
|
||||
@@ -1,141 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD 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
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
|
||||
#define NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
|
||||
|
||||
#include <ndn-cxx/encoding/encoding-buffer.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
/*! \brief provides a publisher of Status Dataset or other segmented octet stream
|
||||
\sa https://redmine.named-data.net/projects/nfd/wiki/StatusDataset
|
||||
*/
|
||||
template <class FaceBase>
|
||||
class SegmentPublisher : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
SegmentPublisher(FaceBase& face,
|
||||
ndn::KeyChain& keyChain,
|
||||
const ndn::security::SigningInfo& signingInfo,
|
||||
const ndn::time::milliseconds& freshnessPeriod = getDefaultFreshness())
|
||||
: m_face(face)
|
||||
, m_keyChain(keyChain)
|
||||
, m_signingInfo(signingInfo)
|
||||
, m_freshnessPeriod(freshnessPeriod)
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~SegmentPublisher()
|
||||
{
|
||||
}
|
||||
|
||||
/*! \brief Define the max segment size as half the max NDN packet size.
|
||||
*/
|
||||
static size_t
|
||||
getMaxSegmentSize()
|
||||
{
|
||||
static const size_t MAX_SEGMENT_SIZE = ndn::MAX_NDN_PACKET_SIZE >> 1;
|
||||
return MAX_SEGMENT_SIZE;
|
||||
}
|
||||
|
||||
static constexpr ndn::time::milliseconds
|
||||
getDefaultFreshness()
|
||||
{
|
||||
return ndn::time::milliseconds(1000);
|
||||
}
|
||||
|
||||
/*! \brief Publish data under the provided prefix
|
||||
*
|
||||
* Processes whatever is provided from SegmentPublisher::generate,
|
||||
* by breaking it into segments of MAX_SEGMENT_SIZE and sending each
|
||||
* one individually. The last segment is distinguished by having the
|
||||
* final block ID set to a timestamp.
|
||||
*/
|
||||
void
|
||||
publish(const ndn::Name& prefix)
|
||||
{
|
||||
ndn::EncodingBuffer buffer;
|
||||
generate(buffer);
|
||||
|
||||
const uint8_t* rawBuffer = buffer.buf();
|
||||
const uint8_t* segmentBegin = rawBuffer;
|
||||
const uint8_t* end = rawBuffer + buffer.size();
|
||||
|
||||
ndn::Name segmentPrefix(prefix);
|
||||
segmentPrefix.appendVersion();
|
||||
|
||||
uint64_t segmentNo = 0;
|
||||
do {
|
||||
const uint8_t* segmentEnd = segmentBegin + getMaxSegmentSize();
|
||||
if (segmentEnd > end) {
|
||||
segmentEnd = end;
|
||||
}
|
||||
|
||||
ndn::Name segmentName(segmentPrefix);
|
||||
segmentName.appendSegment(segmentNo);
|
||||
|
||||
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(segmentName);
|
||||
data->setContent(segmentBegin, segmentEnd - segmentBegin);
|
||||
data->setFreshnessPeriod(m_freshnessPeriod);
|
||||
|
||||
segmentBegin = segmentEnd;
|
||||
if (segmentBegin >= end) {
|
||||
data->setFinalBlock(segmentName[-1]);
|
||||
}
|
||||
|
||||
publishSegment(data);
|
||||
++segmentNo;
|
||||
} while (segmentBegin < end);
|
||||
}
|
||||
|
||||
protected:
|
||||
/*! \brief In a derived class, write the octets into outBuffer.
|
||||
*/
|
||||
virtual size_t
|
||||
generate(ndn::EncodingBuffer& outBuffer) = 0;
|
||||
|
||||
private:
|
||||
/*! \brief Helper function to sign and put data on a Face.
|
||||
*/
|
||||
void
|
||||
publishSegment(std::shared_ptr<ndn::Data>& data)
|
||||
{
|
||||
m_keyChain.sign(*data, m_signingInfo);
|
||||
m_face.put(*data);
|
||||
}
|
||||
|
||||
private:
|
||||
FaceBase& m_face;
|
||||
ndn::KeyChain& m_keyChain;
|
||||
const ndn::security::SigningInfo& m_signingInfo;
|
||||
const ndn::time::milliseconds m_freshnessPeriod;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_PUBLISHER_SEGMENT_PUBLISHER_HPP
|
||||
@@ -1,44 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
*
|
||||
**/
|
||||
#include "face-map.hpp"
|
||||
#include "common.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(route.FaceMap);
|
||||
|
||||
void
|
||||
FaceMap::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG("------- Face Map-----------");
|
||||
for (const auto& it : m_table) {
|
||||
NLSR_LOG_DEBUG("Face Map Entry (FaceUri: " << (it.second).getFaceUri()
|
||||
<< " Face Id: " << (it.second).getFaceId() << ")");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,121 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef NLSR_FACE_MAP_HPP
|
||||
#define NLSR_FACE_MAP_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class FaceMapEntry
|
||||
{
|
||||
|
||||
public:
|
||||
FaceMapEntry(const std::string& faceUri, uint32_t faceId)
|
||||
: m_faceUri(faceUri)
|
||||
, m_faceId(faceId)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
setFaceUri(const std::string& faceUri)
|
||||
{
|
||||
m_faceUri = faceUri;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getFaceUri() const
|
||||
{
|
||||
return m_faceUri;
|
||||
}
|
||||
|
||||
void
|
||||
setFaceId(uint32_t faceId)
|
||||
{
|
||||
m_faceId = faceId;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
getFaceId() const
|
||||
{
|
||||
return m_faceId;
|
||||
}
|
||||
|
||||
bool
|
||||
compare(const FaceMapEntry& fme)
|
||||
{
|
||||
return m_faceUri == fme.getFaceUri();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_faceUri;
|
||||
uint32_t m_faceId;
|
||||
};
|
||||
|
||||
class FaceMap
|
||||
{
|
||||
|
||||
public:
|
||||
FaceMap()
|
||||
{
|
||||
}
|
||||
|
||||
~FaceMap()
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
update(const std::string& faceUri, uint32_t faceId)
|
||||
{
|
||||
FaceMapEntry fme(faceUri, faceId);
|
||||
std::map<std::string, FaceMapEntry>::iterator it = m_table.find(faceUri);
|
||||
if (it == m_table.end()) {
|
||||
m_table.emplace(faceUri, fme);
|
||||
}
|
||||
else {
|
||||
(it->second).setFaceId(fme.getFaceId());
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
getFaceId(const std::string& faceUri)
|
||||
{
|
||||
FaceMapEntry fme(faceUri, 0);
|
||||
std::map<std::string, FaceMapEntry>::iterator it = m_table.find(faceUri);
|
||||
if (it != m_table.end()) {
|
||||
return (it->second).getFaceId();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
writeLog();
|
||||
|
||||
private:
|
||||
std::map<std::string, FaceMapEntry> m_table;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_FACE_MAP_HPP
|
||||
@@ -1,115 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#ifndef NLSR_FIB_ENTRY_HPP
|
||||
#define NLSR_FIB_ENTRY_HPP
|
||||
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
#include "nexthop-list.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class FibEntry
|
||||
{
|
||||
public:
|
||||
FibEntry()
|
||||
: m_name()
|
||||
, m_seqNo(1)
|
||||
, m_nexthopList()
|
||||
{
|
||||
}
|
||||
|
||||
FibEntry(const ndn::Name& name)
|
||||
: m_seqNo(1)
|
||||
, m_nexthopList()
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
NexthopList&
|
||||
getNexthopList()
|
||||
{
|
||||
return m_nexthopList;
|
||||
}
|
||||
|
||||
void
|
||||
setRefreshEventId(ndn::EventId id)
|
||||
{
|
||||
m_refreshEventId = id;
|
||||
}
|
||||
|
||||
ndn::EventId
|
||||
getRefreshEventId() const
|
||||
{
|
||||
return m_refreshEventId;
|
||||
}
|
||||
|
||||
void
|
||||
setSeqNo(int32_t fsn)
|
||||
{
|
||||
m_seqNo = fsn;
|
||||
}
|
||||
|
||||
int32_t
|
||||
getSeqNo() const
|
||||
{
|
||||
return m_seqNo;
|
||||
}
|
||||
|
||||
void
|
||||
writeLog();
|
||||
|
||||
typedef NexthopList::const_iterator const_iterator;
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
private:
|
||||
ndn::Name m_name;
|
||||
ndn::EventId m_refreshEventId;
|
||||
int32_t m_seqNo;
|
||||
NexthopList m_nexthopList;
|
||||
};
|
||||
|
||||
inline FibEntry::const_iterator
|
||||
FibEntry::begin() const
|
||||
{
|
||||
return m_nexthopList.cbegin();
|
||||
}
|
||||
|
||||
inline FibEntry::const_iterator
|
||||
FibEntry::end() const
|
||||
{
|
||||
return m_nexthopList.cend();
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_FIB_ENTRY_HPP
|
||||
+124
-173
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "fib.hpp"
|
||||
#include "adjacency-list.hpp"
|
||||
@@ -24,51 +24,56 @@
|
||||
#include "logger.hpp"
|
||||
#include "nexthop-list.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(route.Fib);
|
||||
|
||||
const uint64_t Fib::GRACE_PERIOD = 10;
|
||||
Fib::Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList,
|
||||
ConfParameter& conf, ndn::security::KeyChain& keyChain)
|
||||
: m_scheduler(scheduler)
|
||||
, m_refreshTime(2 * conf.getLsaRefreshTime())
|
||||
, m_controller(face, keyChain)
|
||||
, m_adjacencyList(adjacencyList)
|
||||
, m_confParameter(conf)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Fib::remove(const ndn::Name& name)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Fib::remove called");
|
||||
std::map<ndn::Name, FibEntry>::iterator it = m_table.find(name);
|
||||
if (it != m_table.end()) {
|
||||
for (std::set<NextHop, NextHopComparator>::iterator nhit =
|
||||
(it->second).getNexthopList().getNextHops().begin();
|
||||
nhit != (it->second).getNexthopList().getNextHops().end(); nhit++) {
|
||||
//remove entry from NDN-FIB
|
||||
// Only unregister the prefix if it ISN'T a neighbor.
|
||||
if (isPrefixUpdatable((it->second).getName())) {
|
||||
unregisterPrefix((it->second).getName(), nhit->getConnectingFaceUri());
|
||||
}
|
||||
auto it = m_table.find(name);
|
||||
|
||||
// Only unregister the prefix if it ISN'T a neighbor.
|
||||
if (it != m_table.end() && isNotNeighbor((it->second).name)) {
|
||||
for (const auto& nexthop : (it->second).nexthopSet) {
|
||||
unregisterPrefix((it->second).name, nexthop.getConnectingFaceUri());
|
||||
}
|
||||
cancelEntryRefresh(it->second);
|
||||
m_table.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd)
|
||||
Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd)
|
||||
{
|
||||
const ndn::Name& name = entry.getName();
|
||||
const ndn::Name& name = entry.name;
|
||||
|
||||
for (NexthopList::iterator it = hopsToAdd.begin(); it != hopsToAdd.end(); ++it)
|
||||
bool shouldRegister = isNotNeighbor(name);
|
||||
|
||||
for (const auto& hop : hopsToAdd)
|
||||
{
|
||||
// Add nexthop to FIB entry
|
||||
entry.getNexthopList().addNextHop(*it);
|
||||
NLSR_LOG_DEBUG("Adding " << hop.getConnectingFaceUri() << " to " << entry.name);
|
||||
entry.nexthopSet.addNextHop(hop);
|
||||
|
||||
if (isPrefixUpdatable(name)) {
|
||||
if (shouldRegister) {
|
||||
// Add nexthop to NDN-FIB
|
||||
registerPrefix(name, ndn::FaceUri(it->getConnectingFaceUri()),
|
||||
it->getRouteCostAsAdjustedInteger(),
|
||||
registerPrefix(name, ndn::FaceUri(hop.getConnectingFaceUri()),
|
||||
hop.getRouteCostAsAdjustedInteger(),
|
||||
ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
}
|
||||
@@ -76,36 +81,33 @@ Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd)
|
||||
}
|
||||
|
||||
void
|
||||
Fib::update(const ndn::Name& name, NexthopList& allHops)
|
||||
Fib::update(const ndn::Name& name, const NexthopList& allHops)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Fib::update called");
|
||||
|
||||
// Get the max possible faces which is the minumum of the configuration setting and
|
||||
// Get the max possible faces which is the minimum of the configuration setting and
|
||||
// the length of the list of all next hops.
|
||||
unsigned int maxFaces = getNumberOfFacesForName(allHops);
|
||||
|
||||
NexthopList hopsToAdd;
|
||||
NextHopsUriSortedSet hopsToAdd;
|
||||
unsigned int nFaces = 0;
|
||||
|
||||
// Create a list of next hops to be installed with length == maxFaces
|
||||
for (NexthopList::iterator it = allHops.begin(); it != allHops.end() && nFaces < maxFaces;
|
||||
++it, ++nFaces) {
|
||||
for (auto it = allHops.cbegin(); it != allHops.cend() && nFaces < maxFaces; ++it, ++nFaces) {
|
||||
hopsToAdd.addNextHop(*it);
|
||||
}
|
||||
|
||||
std::map<ndn::Name, FibEntry>::iterator entryIt = m_table.find(name);
|
||||
auto entryIt = m_table.find(name);
|
||||
|
||||
// New FIB entry that has nextHops
|
||||
if (entryIt == m_table.end() && hopsToAdd.size() != 0) {
|
||||
NLSR_LOG_DEBUG("New FIB Entry");
|
||||
|
||||
FibEntry entry(name);
|
||||
|
||||
FibEntry entry;
|
||||
entry.name = name;
|
||||
addNextHopsToFibEntryAndNfd(entry, hopsToAdd);
|
||||
|
||||
m_table.emplace(name, entry);
|
||||
|
||||
entryIt = m_table.find(name);
|
||||
entryIt = m_table.try_emplace(name, std::move(entry)).first;
|
||||
}
|
||||
// Existing FIB entry that may or may not have nextHops
|
||||
else {
|
||||
@@ -118,92 +120,72 @@ Fib::update(const ndn::Name& name, NexthopList& allHops)
|
||||
return;
|
||||
}
|
||||
|
||||
FibEntry& entry = (entryIt->second);
|
||||
FibEntry& entry = entryIt->second;
|
||||
addNextHopsToFibEntryAndNfd(entry, hopsToAdd);
|
||||
|
||||
std::set<NextHop, NextHopComparator> hopsToRemove;
|
||||
std::set_difference(entry.getNexthopList().begin(), entry.getNexthopList().end(),
|
||||
std::set<NextHop, NextHopUriSortedComparator> hopsToRemove;
|
||||
std::set_difference(entry.nexthopSet.begin(), entry.nexthopSet.end(),
|
||||
hopsToAdd.begin(), hopsToAdd.end(),
|
||||
std::inserter(hopsToRemove, hopsToRemove.end()), NextHopComparator());
|
||||
std::inserter(hopsToRemove, hopsToRemove.begin()),
|
||||
NextHopUriSortedComparator());
|
||||
|
||||
bool isUpdatable = isPrefixUpdatable(entry.getName());
|
||||
bool isUpdatable = isNotNeighbor(entry.name);
|
||||
// Remove the uninstalled next hops from NFD and FIB entry
|
||||
for (const auto& hop: hopsToRemove){
|
||||
for (const auto& hop : hopsToRemove){
|
||||
if (isUpdatable) {
|
||||
unregisterPrefix(entry.getName(), hop.getConnectingFaceUri());
|
||||
unregisterPrefix(entry.name, hop.getConnectingFaceUri());
|
||||
}
|
||||
NLSR_LOG_DEBUG("Removing " << hop.getConnectingFaceUri() << " from " << entry.getName());
|
||||
entry.getNexthopList().removeNextHop(hop);
|
||||
NLSR_LOG_DEBUG("Removing " << hop.getConnectingFaceUri() << " from " << entry.name);
|
||||
entry.nexthopSet.removeNextHop(hop);
|
||||
}
|
||||
|
||||
// Increment sequence number
|
||||
entry.setSeqNo(entry.getSeqNo() + 1);
|
||||
|
||||
entry.seqNo += 1;
|
||||
entryIt = m_table.find(name);
|
||||
|
||||
}
|
||||
if (entryIt != m_table.end() && !entryIt->second.getRefreshEventId()) {
|
||||
scheduleEntryRefresh(entryIt->second,
|
||||
[this] (FibEntry& entry) {
|
||||
scheduleLoop(entry);
|
||||
});
|
||||
|
||||
if (entryIt != m_table.end() &&
|
||||
!entryIt->second.refreshEventId &&
|
||||
isNotNeighbor(entryIt->second.name)) {
|
||||
scheduleEntryRefresh(entryIt->second, [this] (FibEntry& entry) { scheduleLoop(entry); });
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fib::clean()
|
||||
{
|
||||
NLSR_LOG_DEBUG("Fib::clean called");
|
||||
for (std::map<ndn::Name, FibEntry>::iterator it = m_table.begin();
|
||||
it != m_table.end();
|
||||
++it) {
|
||||
NLSR_LOG_DEBUG("Cancelling Scheduled event. Name: " << it->second.getName());
|
||||
cancelEntryRefresh(it->second);
|
||||
for (std::set<NextHop, NextHopComparator>::iterator nhit =
|
||||
(it->second).getNexthopList().getNextHops().begin();
|
||||
nhit != (it->second).getNexthopList().getNextHops().end(); nhit++) {
|
||||
//Remove entry from NDN-FIB
|
||||
unregisterPrefix((it->second).getName(), nhit->getConnectingFaceUri());
|
||||
NLSR_LOG_DEBUG("Clean called");
|
||||
for (const auto& it : m_table) {
|
||||
for (const auto& hop : it.second.nexthopSet) {
|
||||
unregisterPrefix(it.second.name, hop.getConnectingFaceUri());
|
||||
}
|
||||
}
|
||||
if (m_table.size() > 0) {
|
||||
m_table.clear();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
Fib::getNumberOfFacesForName(NexthopList& nextHopList)
|
||||
Fib::getNumberOfFacesForName(const NexthopList& nextHopList)
|
||||
{
|
||||
uint32_t nNextHops = static_cast<uint32_t>(nextHopList.getNextHops().size());
|
||||
uint32_t nMaxFaces = m_confParameter.getMaxFacesPerPrefix();
|
||||
|
||||
// Allow all faces
|
||||
if (nMaxFaces == 0) {
|
||||
return nNextHops;
|
||||
}
|
||||
else {
|
||||
return std::min(nNextHops, nMaxFaces);
|
||||
}
|
||||
// 0 == all faces
|
||||
return nMaxFaces == 0 ? nNextHops : std::min(nNextHops, nMaxFaces);
|
||||
}
|
||||
|
||||
bool
|
||||
Fib::isPrefixUpdatable(const ndn::Name& name) {
|
||||
if (!m_adjacencyList.isNeighbor(name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
Fib::isNotNeighbor(const ndn::Name& name)
|
||||
{
|
||||
return !m_adjacencyList.isNeighbor(name);
|
||||
}
|
||||
|
||||
void
|
||||
Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
|
||||
uint64_t faceCost,
|
||||
const ndn::time::milliseconds& timeout,
|
||||
uint64_t faceCost, const ndn::time::milliseconds& timeout,
|
||||
uint64_t flags, uint8_t times)
|
||||
{
|
||||
uint64_t faceId = m_adjacencyList.getFaceId(ndn::FaceUri(faceUri));
|
||||
uint64_t faceId = m_adjacencyList.getFaceId(faceUri);
|
||||
|
||||
if (faceId != 0) {
|
||||
if (faceId > 0) {
|
||||
ndn::nfd::ControlParameters faceParameters;
|
||||
faceParameters
|
||||
.setName(namePrefix)
|
||||
@@ -215,14 +197,9 @@ Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
|
||||
|
||||
NLSR_LOG_DEBUG("Registering prefix: " << faceParameters.getName() << " faceUri: " << faceUri);
|
||||
m_controller.start<ndn::nfd::RibRegisterCommand>(faceParameters,
|
||||
std::bind(&Fib::onRegistrationSuccess, this, _1,
|
||||
"Successful in name registration",
|
||||
faceUri),
|
||||
std::bind(&Fib::onRegistrationFailure,
|
||||
this, _1,
|
||||
"Failed in name registration",
|
||||
faceParameters,
|
||||
faceUri, times));
|
||||
std::bind(&Fib::onRegistrationSuccess, this, _1, faceUri),
|
||||
std::bind(&Fib::onRegistrationFailure, this, _1,
|
||||
faceParameters, faceUri, times));
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_WARN("Error: No Face Id for face uri: " << faceUri);
|
||||
@@ -230,31 +207,28 @@ Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
|
||||
}
|
||||
|
||||
void
|
||||
Fib::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const std::string& message, const ndn::FaceUri& faceUri)
|
||||
Fib::onRegistrationSuccess(const ndn::nfd::ControlParameters& param,
|
||||
const ndn::FaceUri& faceUri)
|
||||
{
|
||||
NLSR_LOG_DEBUG(message << ": " << commandSuccessResult.getName() <<
|
||||
" Face Uri: " << faceUri << " faceId: " << commandSuccessResult.getFaceId());
|
||||
NLSR_LOG_DEBUG("Successful in name registration: " << param.getName() <<
|
||||
" Face Uri: " << faceUri << " faceId: " << param.getFaceId());
|
||||
|
||||
AdjacencyList::iterator adjacent = m_adjacencyList.findAdjacent(faceUri);
|
||||
auto adjacent = m_adjacencyList.findAdjacent(faceUri);
|
||||
if (adjacent != m_adjacencyList.end()) {
|
||||
adjacent->setFaceId(commandSuccessResult.getFaceId());
|
||||
adjacent->setFaceId(param.getFaceId());
|
||||
}
|
||||
|
||||
// Update the fast-access FaceMap with the new Face ID, too
|
||||
m_faceMap.update(faceUri.toString(), commandSuccessResult.getFaceId());
|
||||
m_faceMap.writeLog();
|
||||
onPrefixRegistrationSuccess(param.getName());
|
||||
}
|
||||
|
||||
void
|
||||
Fib::onRegistrationFailure(const ndn::nfd::ControlResponse& response,
|
||||
const std::string& message,
|
||||
const ndn::nfd::ControlParameters& parameters,
|
||||
const ndn::FaceUri& faceUri,
|
||||
uint8_t times)
|
||||
{
|
||||
NLSR_LOG_DEBUG(message << ": " << response.getText() << " (code: " << response.getCode() << ")");
|
||||
NLSR_LOG_DEBUG("Prefix: " << parameters.getName() << " failed for: " << times);
|
||||
NLSR_LOG_DEBUG("Failed in name registration: " << response.getText() <<
|
||||
" (code: " << response.getCode() << ")");
|
||||
NLSR_LOG_DEBUG("Prefix: " << parameters.getName() << " failed for: " << +times);
|
||||
if (times < 3) {
|
||||
NLSR_LOG_DEBUG("Trying to register again...");
|
||||
registerPrefix(parameters.getName(), faceUri,
|
||||
@@ -268,9 +242,14 @@ Fib::onRegistrationFailure(const ndn::nfd::ControlResponse& response,
|
||||
}
|
||||
|
||||
void
|
||||
Fib::unregisterPrefix(const ndn::Name& namePrefix, const std::string& faceUri)
|
||||
Fib::unregisterPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri)
|
||||
{
|
||||
uint32_t faceId = m_faceMap.getFaceId(faceUri);
|
||||
uint64_t faceId = 0;
|
||||
auto adjacent = m_adjacencyList.findAdjacent(faceUri);
|
||||
if (adjacent != m_adjacencyList.end()) {
|
||||
faceId = adjacent->getFaceId();
|
||||
}
|
||||
|
||||
NLSR_LOG_DEBUG("Unregister prefix: " << namePrefix << " Face Uri: " << faceUri);
|
||||
if (faceId > 0) {
|
||||
ndn::nfd::ControlParameters controlParameters;
|
||||
@@ -278,32 +257,21 @@ Fib::unregisterPrefix(const ndn::Name& namePrefix, const std::string& faceUri)
|
||||
.setName(namePrefix)
|
||||
.setFaceId(faceId)
|
||||
.setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR);
|
||||
|
||||
m_controller.start<ndn::nfd::RibUnregisterCommand>(controlParameters,
|
||||
std::bind(&Fib::onUnregistrationSuccess, this, _1,
|
||||
"Successful in unregistering name"),
|
||||
std::bind(&Fib::onUnregistrationFailure,
|
||||
this, _1,
|
||||
"Failed in unregistering name"));
|
||||
[] (const ndn::nfd::ControlParameters& commandSuccessResult) {
|
||||
NLSR_LOG_DEBUG("Unregister successful Prefix: " << commandSuccessResult.getName() <<
|
||||
" Face Id: " << commandSuccessResult.getFaceId());
|
||||
},
|
||||
[] (const ndn::nfd::ControlResponse& response) {
|
||||
NLSR_LOG_DEBUG("Failed in unregistering name" << ": " << response.getText() <<
|
||||
" (code: " << response.getCode() << ")");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fib::onUnregistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const std::string& message)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Unregister successful Prefix: " << commandSuccessResult.getName() <<
|
||||
" Face Id: " << commandSuccessResult.getFaceId());
|
||||
}
|
||||
|
||||
void
|
||||
Fib::onUnregistrationFailure(const ndn::nfd::ControlResponse& response,
|
||||
const std::string& message)
|
||||
{
|
||||
NLSR_LOG_DEBUG(message << ": " << response.getText() << " (code: " << response.getCode() << ")");
|
||||
}
|
||||
|
||||
void
|
||||
Fib::setStrategy(const ndn::Name& name, const std::string& strategy, uint32_t count)
|
||||
Fib::setStrategy(const ndn::Name& name, const ndn::Name& strategy, uint32_t count)
|
||||
{
|
||||
ndn::nfd::ControlParameters parameters;
|
||||
parameters
|
||||
@@ -311,80 +279,63 @@ Fib::setStrategy(const ndn::Name& name, const std::string& strategy, uint32_t co
|
||||
.setStrategy(strategy);
|
||||
|
||||
m_controller.start<ndn::nfd::StrategyChoiceSetCommand>(parameters,
|
||||
std::bind(&Fib::onSetStrategySuccess, this, _1,
|
||||
"Successfully set strategy choice"),
|
||||
std::bind(&Fib::onSetStrategySuccess, this, _1),
|
||||
std::bind(&Fib::onSetStrategyFailure, this, _1,
|
||||
parameters,
|
||||
count,
|
||||
"Failed to set strategy choice"));
|
||||
parameters, count));
|
||||
}
|
||||
|
||||
void
|
||||
Fib::onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const std::string& message)
|
||||
Fib::onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult)
|
||||
{
|
||||
NLSR_LOG_DEBUG(message << ": " << commandSuccessResult.getStrategy() << " "
|
||||
<< "for name: " << commandSuccessResult.getName());
|
||||
NLSR_LOG_DEBUG("Successfully set strategy choice: " << commandSuccessResult.getStrategy() <<
|
||||
" for name: " << commandSuccessResult.getName());
|
||||
}
|
||||
|
||||
void
|
||||
Fib::onSetStrategyFailure(const ndn::nfd::ControlResponse& response,
|
||||
const ndn::nfd::ControlParameters& parameters,
|
||||
uint32_t count,
|
||||
const std::string& message)
|
||||
uint32_t count)
|
||||
{
|
||||
NLSR_LOG_DEBUG(message << ": " << parameters.getStrategy() << " "
|
||||
<< "for name: " << parameters.getName());
|
||||
NLSR_LOG_DEBUG("Failed to set strategy choice: " << parameters.getStrategy() <<
|
||||
" for name: " << parameters.getName());
|
||||
if (count < 3) {
|
||||
setStrategy(parameters.getName(), parameters.getStrategy().toUri(),count+1);
|
||||
setStrategy(parameters.getName(), parameters.getStrategy().toUri(), count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fib::scheduleEntryRefresh(FibEntry& entry, const afterRefreshCallback& refreshCallback)
|
||||
Fib::scheduleEntryRefresh(FibEntry& entry, const AfterRefreshCallback& refreshCallback)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Scheduling refresh for " << entry.getName()
|
||||
<< " Seq Num: " << entry.getSeqNo()
|
||||
<< " in " << m_refreshTime << " seconds");
|
||||
NLSR_LOG_DEBUG("Scheduling refresh for " << entry.name <<
|
||||
" Seq Num: " << entry.seqNo <<
|
||||
" in " << m_refreshTime << " seconds");
|
||||
|
||||
entry.setRefreshEventId(m_scheduler.scheduleEvent(ndn::time::seconds(m_refreshTime),
|
||||
std::bind(&Fib::refreshEntry, this,
|
||||
entry.getName(), refreshCallback)));
|
||||
entry.refreshEventId = m_scheduler.schedule(ndn::time::seconds(m_refreshTime),
|
||||
std::bind(&Fib::refreshEntry, this,
|
||||
entry.name, refreshCallback));
|
||||
}
|
||||
|
||||
void
|
||||
Fib::scheduleLoop(FibEntry& entry)
|
||||
{
|
||||
scheduleEntryRefresh(entry,
|
||||
std::bind(&Fib::scheduleLoop, this, _1));
|
||||
scheduleEntryRefresh(entry, std::bind(&Fib::scheduleLoop, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Fib::cancelEntryRefresh(const FibEntry& entry)
|
||||
Fib::refreshEntry(const ndn::Name& name, AfterRefreshCallback refreshCb)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Cancelling refresh for " << entry.getName() << " Seq Num: " << entry.getSeqNo());
|
||||
|
||||
m_scheduler.cancelEvent(entry.getRefreshEventId());
|
||||
entry.getRefreshEventId().reset();
|
||||
}
|
||||
|
||||
void
|
||||
Fib::refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb)
|
||||
{
|
||||
std::map<ndn::Name, FibEntry>::iterator it = m_table.find(name);
|
||||
|
||||
auto it = m_table.find(name);
|
||||
if (it == m_table.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
FibEntry& entry = it->second;
|
||||
NLSR_LOG_DEBUG("Refreshing " << entry.getName() << " Seq Num: " << entry.getSeqNo());
|
||||
NLSR_LOG_DEBUG("Refreshing " << entry.name << " Seq Num: " << entry.seqNo);
|
||||
|
||||
// Increment sequence number
|
||||
entry.setSeqNo(entry.getSeqNo() + 1);
|
||||
entry.seqNo += 1;
|
||||
|
||||
for (const NextHop& hop : entry) {
|
||||
registerPrefix(entry.getName(),
|
||||
for (const NextHop& hop : entry.nexthopSet) {
|
||||
registerPrefix(entry.name,
|
||||
ndn::FaceUri(hop.getConnectingFaceUri()),
|
||||
hop.getRouteCostAsAdjustedInteger(),
|
||||
ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
|
||||
@@ -398,10 +349,10 @@ void
|
||||
Fib::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG("-------------------FIB-----------------------------");
|
||||
for (std::map<ndn::Name, FibEntry>::iterator it = m_table.begin();
|
||||
it != m_table.end();
|
||||
++it) {
|
||||
(it->second).writeLog();
|
||||
for (const auto& entry : m_table) {
|
||||
NLSR_LOG_DEBUG("Name prefix: " << entry.first);
|
||||
NLSR_LOG_DEBUG("Seq No: " << entry.second.seqNo);
|
||||
NLSR_LOG_DEBUG("Nexthop List: \n" << entry.second.nexthopSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+37
-63
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -22,20 +22,29 @@
|
||||
#ifndef NLSR_ROUTE_FIB_HPP
|
||||
#define NLSR_ROUTE_FIB_HPP
|
||||
|
||||
#include "face-map.hpp"
|
||||
#include "fib-entry.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
#include "nexthop-list.hpp"
|
||||
|
||||
#include <ndn-cxx/mgmt/nfd/controller.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
typedef std::function<void(FibEntry&)> afterRefreshCallback;
|
||||
using NextHopsUriSortedSet = NexthopListT<NextHopUriSortedComparator>;
|
||||
|
||||
struct FibEntry
|
||||
{
|
||||
ndn::Name name;
|
||||
ndn::scheduler::ScopedEventId refreshEventId;
|
||||
int32_t seqNo = 1;
|
||||
NextHopsUriSortedSet nexthopSet;
|
||||
};
|
||||
|
||||
using AfterRefreshCallback = std::function<void(FibEntry&)>;
|
||||
|
||||
class AdjacencyList;
|
||||
class ConfParameter;
|
||||
class FibEntry;
|
||||
|
||||
/*! \brief Maps names to lists of next hops, and exports this information to NFD.
|
||||
*
|
||||
@@ -53,18 +62,8 @@ class FibEntry;
|
||||
class Fib
|
||||
{
|
||||
public:
|
||||
Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList, ConfParameter& conf,
|
||||
ndn::security::v2::KeyChain& keyChain)
|
||||
: m_scheduler(scheduler)
|
||||
, m_refreshTime(0)
|
||||
, m_controller(face, keyChain)
|
||||
, m_adjacencyList(adjacencyList)
|
||||
, m_confParameter(conf)
|
||||
{
|
||||
}
|
||||
|
||||
VIRTUAL_WITH_TESTS
|
||||
~Fib() = default;
|
||||
Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList,
|
||||
ConfParameter& conf, ndn::security::KeyChain& keyChain);
|
||||
|
||||
/*! \brief Completely remove a name prefix from the FIB.
|
||||
*
|
||||
@@ -74,7 +73,7 @@ public:
|
||||
*
|
||||
* \sa nlsr::NamePrefixTable::removeEntry
|
||||
*/
|
||||
VIRTUAL_WITH_TESTS void
|
||||
void
|
||||
remove(const ndn::Name& name);
|
||||
|
||||
/*! \brief Set the nexthop list of a name.
|
||||
@@ -88,8 +87,8 @@ public:
|
||||
* \param name The name prefix that the next-hops apply to
|
||||
* \param allHops A complete list of next-hops to associate with name.
|
||||
*/
|
||||
VIRTUAL_WITH_TESTS void
|
||||
update(const ndn::Name& name, NexthopList& allHops);
|
||||
void
|
||||
update(const ndn::Name& name, const NexthopList& allHops);
|
||||
|
||||
/*! \brief Remove all entries from the FIB.
|
||||
*
|
||||
@@ -98,9 +97,6 @@ public:
|
||||
* strictly necessary, because eventually those prefix registrations
|
||||
* will expire, but cleaning up after ourselves improves
|
||||
* performance.
|
||||
*
|
||||
* \sa NlsrRunner::run
|
||||
*
|
||||
*/
|
||||
void
|
||||
clean();
|
||||
@@ -140,7 +136,7 @@ public:
|
||||
uint8_t times);
|
||||
|
||||
void
|
||||
setStrategy(const ndn::Name& name, const std::string& strategy, uint32_t count);
|
||||
setStrategy(const ndn::Name& name, const ndn::Name& strategy, uint32_t count);
|
||||
|
||||
void
|
||||
writeLog();
|
||||
@@ -151,7 +147,7 @@ private:
|
||||
* \return Whether the name is NOT associated with a direct neighbor
|
||||
*/
|
||||
bool
|
||||
isPrefixUpdatable(const ndn::Name& name);
|
||||
isNotNeighbor(const ndn::Name& name);
|
||||
|
||||
/*! \brief Does one half of the updating of a FibEntry with new next-hops.
|
||||
*
|
||||
@@ -160,57 +156,42 @@ private:
|
||||
* \sa Fib::removeOldNextHopsFromFibEntryAndNfd
|
||||
*/
|
||||
void
|
||||
addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd);
|
||||
addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd);
|
||||
|
||||
unsigned int
|
||||
getNumberOfFacesForName(NexthopList& nextHopList);
|
||||
getNumberOfFacesForName(const NexthopList& nextHopList);
|
||||
|
||||
/*! \brief Unregisters a prefix from NFD's RIB.
|
||||
*
|
||||
*/
|
||||
void
|
||||
unregisterPrefix(const ndn::Name& namePrefix, const std::string& faceUri);
|
||||
unregisterPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri);
|
||||
|
||||
/*! \brief Log registration success, and update the Face ID associated with a URI.
|
||||
*/
|
||||
void
|
||||
onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const std::string& message, const ndn::FaceUri& faceUri);
|
||||
onRegistrationSuccess(const ndn::nfd::ControlParameters& param,
|
||||
const ndn::FaceUri& faceUri);
|
||||
|
||||
/*! \brief Retry a prefix (next-hop) registration up to three (3) times.
|
||||
*/
|
||||
void
|
||||
onRegistrationFailure(const ndn::nfd::ControlResponse& response,
|
||||
const std::string& message,
|
||||
const ndn::nfd::ControlParameters& parameters,
|
||||
const ndn::FaceUri& faceUri,
|
||||
uint8_t times);
|
||||
|
||||
/*! \brief Log a successful unregistration.
|
||||
*/
|
||||
void
|
||||
onUnregistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const std::string& message);
|
||||
|
||||
/*! \brief Log an unregistration failure. Does not retry.
|
||||
*/
|
||||
void
|
||||
onUnregistrationFailure(const ndn::nfd::ControlResponse& response,
|
||||
const std::string& message);
|
||||
|
||||
/*! \brief Log a successful strategy setting.
|
||||
*/
|
||||
void
|
||||
onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
|
||||
const std::string& message);
|
||||
onSetStrategySuccess(const ndn::nfd::ControlParameters& commandSuccessResult);
|
||||
|
||||
/*! \brief Retry a strategy setting up to three (3) times.
|
||||
*/
|
||||
void
|
||||
onSetStrategyFailure(const ndn::nfd::ControlResponse& response,
|
||||
const ndn::nfd::ControlParameters& parameters,
|
||||
uint32_t count,
|
||||
const std::string& message);
|
||||
uint32_t count);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Schedule a refresh event for an entry.
|
||||
@@ -224,7 +205,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
* \sa Fib::scheduleLoop
|
||||
*/
|
||||
void
|
||||
scheduleEntryRefresh(FibEntry& entry, const afterRefreshCallback& refreshCb);
|
||||
scheduleEntryRefresh(FibEntry& entry, const AfterRefreshCallback& refreshCb);
|
||||
|
||||
private:
|
||||
/*! \brief Continue the entry refresh cycle.
|
||||
@@ -232,22 +213,16 @@ private:
|
||||
void
|
||||
scheduleLoop(FibEntry& entry);
|
||||
|
||||
/*! \brief Cancel an entry's refresh event.
|
||||
*
|
||||
* Cancel an entry's refresh event. This only needs to be done when
|
||||
* an entry is removed. Typically this happens when NLSR is
|
||||
* terminated or crashes, and we don't want the scheduler to crash
|
||||
* because it's referencing memory that has no valid function.
|
||||
*
|
||||
* \sa NlsrRunner::run
|
||||
*/
|
||||
void
|
||||
cancelEntryRefresh(const FibEntry& entry);
|
||||
|
||||
/*! \brief Refreshes an entry in NFD.
|
||||
*/
|
||||
void
|
||||
refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb);
|
||||
refreshEntry(const ndn::Name& name, AfterRefreshCallback refreshCb);
|
||||
|
||||
public:
|
||||
static inline const ndn::Name MULTICAST_STRATEGY{"/localhost/nfd/strategy/multicast"};
|
||||
static inline const ndn::Name BEST_ROUTE_STRATEGY{"/localhost/nfd/strategy/best-route"};
|
||||
|
||||
ndn::signal::Signal<Fib, ndn::Name> onPrefixRegistrationSuccess;
|
||||
|
||||
private:
|
||||
ndn::Scheduler& m_scheduler;
|
||||
@@ -255,7 +230,6 @@ private:
|
||||
ndn::nfd::Controller m_controller;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
FaceMap m_faceMap;
|
||||
std::map<ndn::Name, FibEntry> m_table;
|
||||
|
||||
private:
|
||||
@@ -266,7 +240,7 @@ private:
|
||||
* allow for things like stuttering prefix registrations and
|
||||
* processing time when refreshing events.
|
||||
*/
|
||||
static const uint64_t GRACE_PERIOD;
|
||||
static constexpr uint64_t GRACE_PERIOD = 10;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
+14
-32
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,12 +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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "map.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "lsa/lsa.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
@@ -32,7 +32,7 @@ INIT_LOGGER(route.Map);
|
||||
void
|
||||
Map::addEntry(const ndn::Name& rtrName)
|
||||
{
|
||||
MapEntry me(rtrName, m_mappingIndex);
|
||||
MapEntry me {rtrName, m_mappingIndex};
|
||||
if (addEntry(me)) {
|
||||
m_mappingIndex++;
|
||||
}
|
||||
@@ -44,47 +44,29 @@ Map::addEntry(MapEntry& mpe)
|
||||
return m_entries.insert(mpe).second;
|
||||
}
|
||||
|
||||
ndn::optional<ndn::Name>
|
||||
std::optional<ndn::Name>
|
||||
Map::getRouterNameByMappingNo(int32_t mn) const
|
||||
{
|
||||
auto&& mappingNumberView = m_entries.get<detail::byMappingNumber>();
|
||||
auto iterator = mappingNumberView.find(mn);
|
||||
if (iterator == mappingNumberView.end()) {
|
||||
return {};
|
||||
}
|
||||
else {
|
||||
return {iterator->getRouter()};
|
||||
}
|
||||
auto it = mappingNumberView.find(mn);
|
||||
return it == mappingNumberView.end() ? std::nullopt : std::optional(it->router);
|
||||
}
|
||||
|
||||
ndn::optional<int32_t>
|
||||
std::optional<int32_t>
|
||||
Map::getMappingNoByRouterName(const ndn::Name& rName)
|
||||
{
|
||||
auto&& routerNameView = m_entries.get<detail::byRouterName>();
|
||||
auto iterator = routerNameView.find(rName);
|
||||
if (iterator == routerNameView.end()) {
|
||||
return {};
|
||||
}
|
||||
else {
|
||||
return {iterator->getMappingNumber()};
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Map::reset()
|
||||
{
|
||||
m_entries = detail::entryContainer{};
|
||||
m_mappingIndex = 0;
|
||||
auto it = routerNameView.find(rName);
|
||||
return it == routerNameView.end() ? std::nullopt : std::optional(it->mappingNumber);
|
||||
}
|
||||
|
||||
void
|
||||
Map::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG("---------------Map----------------------");
|
||||
auto&& routerNameView = m_entries.get<detail::byRouterName>();
|
||||
for (auto entry = routerNameView.begin(); entry != routerNameView.end(); entry++) {
|
||||
NLSR_LOG_DEBUG("MapEntry: ( Router: " << entry->getRouter() << " Mapping No: "
|
||||
<< entry->getMappingNumber() << " )");
|
||||
for (const auto& entry : m_entries.get<detail::byRouterName>()) {
|
||||
NLSR_LOG_DEBUG("MapEntry: ( Router: " << entry.router << " Mapping No: " <<
|
||||
entry.mappingNumber << " )");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-21
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,25 +16,29 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_MAP_HPP
|
||||
#define NLSR_MAP_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "map-entry.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "lsa/adj-lsa.hpp"
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
struct MapEntry
|
||||
{
|
||||
ndn::Name router;
|
||||
int32_t mappingNumber = -1;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
using namespace boost::multi_index;
|
||||
@@ -45,17 +49,15 @@ namespace detail {
|
||||
MapEntry,
|
||||
indexed_by<
|
||||
hashed_unique<tag<byRouterName>,
|
||||
const_mem_fun<MapEntry, const ndn::Name&, &MapEntry::getRouter>,
|
||||
member<MapEntry, ndn::Name, &MapEntry::router>,
|
||||
std::hash<ndn::Name>>,
|
||||
hashed_unique<tag<byMappingNumber>,
|
||||
const_mem_fun<MapEntry, int32_t, &MapEntry::getMappingNumber>>
|
||||
member<MapEntry, int32_t, &MapEntry::mappingNumber>>
|
||||
>
|
||||
>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class Nlsr;
|
||||
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
@@ -83,8 +85,9 @@ public:
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(is_iterator<IteratorType>::value, "IteratorType must be an iterator!");
|
||||
for (auto lsa = begin; lsa != end; lsa++) {
|
||||
addEntry(lsa->getOrigRouter());
|
||||
for (const auto& adjacent : lsa->getAdl().getAdjList()) {
|
||||
auto adjLsa = std::static_pointer_cast<AdjLsa>(*lsa);
|
||||
addEntry(adjLsa->getOriginRouter());
|
||||
for (const auto& adjacent : adjLsa->getAdl().getAdjList()) {
|
||||
addEntry(adjacent.getName());
|
||||
}
|
||||
}
|
||||
@@ -100,19 +103,16 @@ public:
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(is_iterator<IteratorType>::value, "IteratorType must be an iterator!");
|
||||
for (auto lsa = begin; lsa != end; lsa++) {
|
||||
addEntry(lsa->getOrigRouter());
|
||||
addEntry((*lsa)->getOriginRouter());
|
||||
}
|
||||
}
|
||||
|
||||
ndn::optional<ndn::Name>
|
||||
std::optional<ndn::Name>
|
||||
getRouterNameByMappingNo(int32_t mn) const;
|
||||
|
||||
ndn::optional<int32_t>
|
||||
std::optional<int32_t>
|
||||
getMappingNoByRouterName(const ndn::Name& rName);
|
||||
|
||||
void
|
||||
reset();
|
||||
|
||||
size_t
|
||||
getMapSize() const
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "name-prefix-table-entry.hpp"
|
||||
|
||||
@@ -32,7 +32,7 @@ INIT_LOGGER(route.NamePrefixTableEntry);
|
||||
void
|
||||
NamePrefixTableEntry::generateNhlfromRteList()
|
||||
{
|
||||
m_nexthopList.reset();
|
||||
m_nexthopList.clear();
|
||||
for (auto iterator = m_rteList.begin(); iterator != m_rteList.end(); ++iterator) {
|
||||
for (auto nhItr = (*iterator)->getNexthopList().getNextHops().begin();
|
||||
nhItr != (*iterator)->getNexthopList().getNextHops().end();
|
||||
@@ -43,8 +43,7 @@ NamePrefixTableEntry::generateNhlfromRteList()
|
||||
}
|
||||
|
||||
uint64_t
|
||||
NamePrefixTableEntry::removeRoutingTableEntry(std::shared_ptr<RoutingTablePoolEntry>
|
||||
entryPtr)
|
||||
NamePrefixTableEntry::removeRoutingTableEntry(std::shared_ptr<RoutingTablePoolEntry> entryPtr)
|
||||
{
|
||||
auto iterator = std::find(m_rteList.begin(), m_rteList.end(), entryPtr);
|
||||
|
||||
@@ -62,8 +61,7 @@ NamePrefixTableEntry::removeRoutingTableEntry(std::shared_ptr<RoutingTablePoolEn
|
||||
}
|
||||
|
||||
void
|
||||
NamePrefixTableEntry::addRoutingTableEntry(std::shared_ptr<RoutingTablePoolEntry>
|
||||
entryPtr)
|
||||
NamePrefixTableEntry::addRoutingTableEntry(std::shared_ptr<RoutingTablePoolEntry> entryPtr)
|
||||
{
|
||||
auto iterator = std::find(m_rteList.begin(), m_rteList.end(), entryPtr);
|
||||
|
||||
@@ -78,28 +76,16 @@ NamePrefixTableEntry::addRoutingTableEntry(std::shared_ptr<RoutingTablePoolEntry
|
||||
// be updated there.
|
||||
}
|
||||
|
||||
void
|
||||
NamePrefixTableEntry::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG("Name: " << m_namePrefix);
|
||||
for (auto it = m_rteList.begin(); it != m_rteList.end(); ++it) {
|
||||
NLSR_LOG_DEBUG("Destination: " << (*it)->getDestination());
|
||||
NLSR_LOG_DEBUG("Nexthops: ");
|
||||
(*it)->getNexthopList().writeLog();
|
||||
}
|
||||
m_nexthopList.writeLog();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const NamePrefixTableEntry& lhs, const NamePrefixTableEntry& rhs)
|
||||
{
|
||||
return (lhs.getNamePrefix() == rhs.getNamePrefix());
|
||||
return lhs.getNamePrefix() == rhs.getNamePrefix();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const NamePrefixTableEntry& lhs, const ndn::Name& rhs)
|
||||
{
|
||||
return (lhs.getNamePrefix() == rhs);
|
||||
return lhs.getNamePrefix() == rhs;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
@@ -107,10 +93,10 @@ operator<<(std::ostream& os, const NamePrefixTableEntry& entry)
|
||||
{
|
||||
os << "Name: " << entry.getNamePrefix() << "\n";
|
||||
|
||||
for (const std::shared_ptr<RoutingTablePoolEntry> entryPtr : entry.getRteList()) {
|
||||
os << "Destination: " << entryPtr->getDestination() << "\n";
|
||||
for (const auto& entryPtr : entry.getRteList()) {
|
||||
os << " Destination: " << entryPtr->getDestination() << "\n";
|
||||
os << entryPtr->getNexthopList();
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,13 +17,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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NAME_PREFIX_TABLE_ENTRY_HPP
|
||||
#define NLSR_NAME_PREFIX_TABLE_ENTRY_HPP
|
||||
|
||||
#include "routing-table-pool-entry.hpp"
|
||||
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <list>
|
||||
@@ -64,7 +63,7 @@ public:
|
||||
{
|
||||
if (m_rteList.size() > 0) {
|
||||
for (auto it = m_rteList.begin(); it != m_rteList.end(); ++it) {
|
||||
(*it)->getNexthopList().reset();
|
||||
(*it)->getNexthopList().clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,8 +74,8 @@ public:
|
||||
return m_rteList.size();
|
||||
}
|
||||
|
||||
NexthopList&
|
||||
getNexthopList()
|
||||
const NexthopList&
|
||||
getNexthopList() const
|
||||
{
|
||||
return m_nexthopList;
|
||||
}
|
||||
@@ -112,7 +111,6 @@ private:
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
std::list<std::shared_ptr<RoutingTablePoolEntry>> m_rteList;
|
||||
NexthopList m_nexthopList;
|
||||
|
||||
};
|
||||
|
||||
bool
|
||||
|
||||
+116
-63
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "name-prefix-table.hpp"
|
||||
|
||||
@@ -33,35 +33,94 @@ namespace nlsr {
|
||||
|
||||
INIT_LOGGER(route.NamePrefixTable);
|
||||
|
||||
NamePrefixTable::NamePrefixTable(Nlsr& nlsr,
|
||||
std::unique_ptr<AfterRoutingChange>& afterRoutingChangeSignal)
|
||||
: m_nlsr(nlsr)
|
||||
NamePrefixTable::NamePrefixTable(const ndn::Name& ownRouterName, Fib& fib,
|
||||
RoutingTable& routingTable,
|
||||
AfterRoutingChange& afterRoutingChangeSignal,
|
||||
Lsdb::AfterLsdbModified& afterLsdbModifiedSignal)
|
||||
: m_ownRouterName(ownRouterName)
|
||||
, m_fib(fib)
|
||||
, m_routingTable(routingTable)
|
||||
{
|
||||
m_afterRoutingChangeConnection = afterRoutingChangeSignal->connect(
|
||||
m_afterRoutingChangeConnection = afterRoutingChangeSignal.connect(
|
||||
[this] (const std::list<RoutingTableEntry>& entries) {
|
||||
updateWithNewRoute(entries);
|
||||
});
|
||||
|
||||
m_afterLsdbModified = afterLsdbModifiedSignal.connect(
|
||||
[this] (std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
|
||||
const auto& namesToAdd, const auto& namesToRemove) {
|
||||
updateFromLsdb(lsa, updateType, namesToAdd, namesToRemove);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
NamePrefixTable::~NamePrefixTable()
|
||||
{
|
||||
m_afterRoutingChangeConnection.disconnect();
|
||||
m_afterLsdbModified.disconnect();
|
||||
}
|
||||
|
||||
void
|
||||
NamePrefixTable::updateFromLsdb(std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
|
||||
const std::list<ndn::Name>& namesToAdd,
|
||||
const std::list<ndn::Name>& namesToRemove)
|
||||
{
|
||||
if (m_ownRouterName == lsa->getOriginRouter()) {
|
||||
return;
|
||||
}
|
||||
NLSR_LOG_TRACE("Got update from Lsdb for router: " << lsa->getOriginRouter());
|
||||
|
||||
if (updateType == LsdbUpdate::INSTALLED) {
|
||||
addEntry(lsa->getOriginRouter(), lsa->getOriginRouter());
|
||||
|
||||
if (lsa->getType() == Lsa::Type::NAME) {
|
||||
auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
|
||||
for (const auto& name : nlsa->getNpl().getNames()) {
|
||||
if (name != m_ownRouterName) {
|
||||
addEntry(name, lsa->getOriginRouter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (updateType == LsdbUpdate::UPDATED) {
|
||||
if (lsa->getType() != Lsa::Type::NAME) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& name : namesToAdd) {
|
||||
if (name != m_ownRouterName) {
|
||||
addEntry(name, lsa->getOriginRouter());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& name : namesToRemove) {
|
||||
if (name != m_ownRouterName) {
|
||||
removeEntry(name, lsa->getOriginRouter());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
removeEntry(lsa->getOriginRouter(), lsa->getOriginRouter());
|
||||
if (lsa->getType() == Lsa::Type::NAME) {
|
||||
auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
|
||||
for (const auto& name : nlsa->getNpl().getNames()) {
|
||||
if (name != m_ownRouterName) {
|
||||
removeEntry(name, lsa->getOriginRouter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
{
|
||||
|
||||
// Check if the advertised name prefix is in the table already.
|
||||
NptEntryList::iterator nameItr =
|
||||
std::find_if(m_table.begin(),
|
||||
m_table.end(),
|
||||
[&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
|
||||
return name == entry->getNamePrefix();
|
||||
});
|
||||
auto nameItr = std::find_if(m_table.begin(), m_table.end(),
|
||||
[&] (const auto& entry) { return name == entry->getNamePrefix(); });
|
||||
|
||||
// Attempt to find a routing table pool entry (RTPE) we can use.
|
||||
RoutingTableEntryPool::iterator rtpeItr = m_rtpool.find(destRouter);
|
||||
auto rtpeItr = m_rtpool.find(destRouter);
|
||||
|
||||
// These declarations just to make the compiler happy...
|
||||
RoutingTablePoolEntry rtpe;
|
||||
@@ -70,8 +129,7 @@ NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
// There isn't currently a routing table entry in the pool for this name
|
||||
if (rtpeItr == m_rtpool.end()) {
|
||||
// See if there is a routing table entry available we could use
|
||||
RoutingTableEntry* routeEntryPtr = m_nlsr.getRoutingTable()
|
||||
.findRoutingTableEntry(destRouter);
|
||||
RoutingTableEntry* routeEntryPtr = m_routingTable.findRoutingTableEntry(destRouter);
|
||||
|
||||
// We have to create a new routing table entry
|
||||
if (routeEntryPtr == nullptr) {
|
||||
@@ -94,15 +152,16 @@ NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
// Either we have to make a new NPT entry or there already was one.
|
||||
if (nameItr == m_table.end()) {
|
||||
NLSR_LOG_DEBUG("Adding origin: " << rtpePtr->getDestination()
|
||||
<< " to a new name prefix: " << name);
|
||||
npte = make_shared<NamePrefixTableEntry>(name);
|
||||
<< " to a new name prefix: " << name);
|
||||
npte = std::make_shared<NamePrefixTableEntry>(name);
|
||||
npte->addRoutingTableEntry(rtpePtr);
|
||||
npte->generateNhlfromRteList();
|
||||
m_table.push_back(npte);
|
||||
|
||||
// If this entry has next hops, we need to inform the FIB
|
||||
if (npte->getNexthopList().size() > 0) {
|
||||
NLSR_LOG_TRACE("Updating FIB with next hops for " << npte);
|
||||
m_nlsr.getFib().update(name, npte->getNexthopList());
|
||||
NLSR_LOG_TRACE("Updating FIB with next hops for " << npte->getNamePrefix());
|
||||
m_fib.update(name, npte->getNexthopList());
|
||||
}
|
||||
// The routing table may recalculate and add a routing table entry
|
||||
// with no next hops to replace an existing routing table entry. In
|
||||
@@ -111,29 +170,30 @@ NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
// remain in the Name Prefix Table as a future routing table
|
||||
// calculation may add next hops.
|
||||
else {
|
||||
NLSR_LOG_TRACE(*npte << " has no next hops; removing from FIB");
|
||||
m_nlsr.getFib().remove(name);
|
||||
NLSR_LOG_TRACE(npte->getNamePrefix() << " has no next hops; removing from FIB");
|
||||
m_fib.remove(name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
npte = *nameItr;
|
||||
NLSR_LOG_TRACE("Adding origin: " << rtpePtr->getDestination()
|
||||
<< " to existing prefix: " << *nameItr);
|
||||
NLSR_LOG_TRACE("Adding origin: " << rtpePtr->getDestination() <<
|
||||
" to existing prefix: " << **nameItr);
|
||||
(*nameItr)->addRoutingTableEntry(rtpePtr);
|
||||
(*nameItr)->generateNhlfromRteList();
|
||||
|
||||
if ((*nameItr)->getNexthopList().size() > 0) {
|
||||
NLSR_LOG_TRACE("Updating FIB with next hops for " << (*nameItr));
|
||||
m_nlsr.getFib().update(name, (*nameItr)->getNexthopList());
|
||||
NLSR_LOG_TRACE("Updating FIB with next hops for " << (**nameItr));
|
||||
m_fib.update(name, (*nameItr)->getNexthopList());
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_TRACE((*nameItr) << " has no next hops; removing from FIB");
|
||||
m_nlsr.getFib().remove(name);
|
||||
NLSR_LOG_TRACE(npte->getNamePrefix() << " has no next hops; removing from FIB");
|
||||
m_fib.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the reference to this NPT to the RTPE.
|
||||
rtpePtr->namePrefixTableEntries.emplace(
|
||||
std::make_pair(npte->getNamePrefix(), std::weak_ptr<NamePrefixTableEntry>(npte)));
|
||||
rtpePtr->namePrefixTableEntries.try_emplace(npte->getNamePrefix(),
|
||||
std::weak_ptr<NamePrefixTableEntry>(npte));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -142,27 +202,23 @@ NamePrefixTable::removeEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
NLSR_LOG_DEBUG("Removing origin: " << destRouter << " from " << name);
|
||||
|
||||
// Fetch an iterator to the appropriate pair object in the pool.
|
||||
RoutingTableEntryPool::iterator rtpeItr = m_rtpool.find(destRouter);
|
||||
auto rtpeItr = m_rtpool.find(destRouter);
|
||||
|
||||
// Simple error checking to prevent any unusual behavior in the case
|
||||
// that we try to remove an entry that isn't there.
|
||||
if (rtpeItr == m_rtpool.end()) {
|
||||
NLSR_LOG_DEBUG("No entry for origin: " << destRouter
|
||||
<< " found, so it cannot be removed from prefix: "
|
||||
<< name);
|
||||
<< " found, so it cannot be removed from prefix: " << name);
|
||||
return;
|
||||
}
|
||||
std::shared_ptr<RoutingTablePoolEntry> rtpePtr = rtpeItr->second;
|
||||
|
||||
// Ensure that the entry exists
|
||||
NptEntryList::iterator nameItr =
|
||||
std::find_if(m_table.begin(), m_table.end(),
|
||||
[&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
|
||||
return entry->getNamePrefix() == name;
|
||||
});
|
||||
auto nameItr = std::find_if(m_table.begin(), m_table.end(),
|
||||
[&] (const auto& entry) { return entry->getNamePrefix() == name; });
|
||||
if (nameItr != m_table.end()) {
|
||||
NLSR_LOG_TRACE("Removing origin: " << rtpePtr->getDestination()
|
||||
<< " from prefix: " << **nameItr);
|
||||
<< " from prefix: " << **nameItr);
|
||||
|
||||
// Rather than iterating through the whole list periodically, just
|
||||
// delete them here if they have no references.
|
||||
@@ -187,20 +243,20 @@ NamePrefixTable::removeEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
//
|
||||
if ((*nameItr)->getRteListSize() == 0) {
|
||||
NLSR_LOG_TRACE(**nameItr << " has no routing table entries;"
|
||||
<< " removing from table and FIB");
|
||||
<< " removing from table and FIB");
|
||||
m_table.erase(nameItr);
|
||||
m_nlsr.getFib().remove(name);
|
||||
m_fib.remove(name);
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_TRACE(**nameItr << " has other routing table entries;"
|
||||
<< " updating FIB with next hops");
|
||||
<< " updating FIB with next hops");
|
||||
(*nameItr)->generateNhlfromRteList();
|
||||
m_nlsr.getFib().update(name, (*nameItr)->getNexthopList());
|
||||
m_fib.update(name, (*nameItr)->getNexthopList());
|
||||
}
|
||||
}
|
||||
else {
|
||||
NLSR_LOG_DEBUG("Attempted to remove origin: " << rtpePtr->getDestination()
|
||||
<< " from non-existent prefix: " << name);
|
||||
<< " from non-existent prefix: " << name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +284,7 @@ NamePrefixTable::updateWithNewRoute(const std::list<RoutingTableEntry>& entries)
|
||||
}
|
||||
else if (sourceEntry == entries.end()) {
|
||||
NLSR_LOG_DEBUG("Routing entry: " << poolEntry->getDestination() << " now has no next-hops.");
|
||||
poolEntry->getNexthopList().reset();
|
||||
poolEntry->getNexthopList().clear();
|
||||
for (const auto& nameEntry : poolEntry->namePrefixTableEntries) {
|
||||
auto nameEntryFullPtr = nameEntry.second.lock();
|
||||
addEntry(nameEntryFullPtr->getNamePrefix(), poolEntry->getDestination());
|
||||
@@ -241,33 +297,30 @@ NamePrefixTable::updateWithNewRoute(const std::list<RoutingTableEntry>& entries)
|
||||
}
|
||||
}
|
||||
|
||||
// Inserts the routing table pool entry into the NPT's RTE storage
|
||||
// pool. This cannot fail, so the pool is guaranteed to contain the
|
||||
// item after this occurs.
|
||||
// Inserts the routing table pool entry into the NPT's RTE storage
|
||||
// pool. This cannot fail, so the pool is guaranteed to contain the
|
||||
// item after this occurs.
|
||||
std::shared_ptr<RoutingTablePoolEntry>
|
||||
NamePrefixTable::addRtpeToPool(RoutingTablePoolEntry& rtpe)
|
||||
{
|
||||
RoutingTableEntryPool::iterator poolItr =
|
||||
m_rtpool.insert(std::make_pair(rtpe.getDestination(),
|
||||
std::make_shared<RoutingTablePoolEntry>
|
||||
(rtpe)))
|
||||
.first;
|
||||
return poolItr->second;
|
||||
auto poolIt = m_rtpool.try_emplace(rtpe.getDestination(),
|
||||
std::make_shared<RoutingTablePoolEntry>(rtpe)).first;
|
||||
return poolIt->second;
|
||||
}
|
||||
|
||||
// Removes the routing table pool entry from the storage pool. The
|
||||
// postconditions of this function are guaranteed to include that
|
||||
// the storage pool does not contain such an item. Additionally,
|
||||
// this function cannot fail, but nonetheless debug information is
|
||||
// given in the case that this function is called with an entry that
|
||||
// isn't in the pool.
|
||||
// Removes the routing table pool entry from the storage pool. The
|
||||
// postconditions of this function are guaranteed to include that
|
||||
// the storage pool does not contain such an item. Additionally,
|
||||
// this function cannot fail, but nonetheless debug information is
|
||||
// given in the case that this function is called with an entry that
|
||||
// isn't in the pool.
|
||||
void
|
||||
NamePrefixTable::deleteRtpeFromPool(std::shared_ptr<RoutingTablePoolEntry> rtpePtr)
|
||||
{
|
||||
if (m_rtpool.erase(rtpePtr->getDestination()) != 1) {
|
||||
NLSR_LOG_DEBUG("Attempted to delete non-existent origin: "
|
||||
<< rtpePtr->getDestination()
|
||||
<< " from NPT routing table entry storage pool.");
|
||||
<< rtpePtr->getDestination()
|
||||
<< " from NPT routing table entry storage pool.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NAME_PREFIX_TABLE_HPP
|
||||
#define NLSR_NAME_PREFIX_TABLE_HPP
|
||||
@@ -26,12 +26,13 @@
|
||||
#include "routing-table-pool-entry.hpp"
|
||||
#include "signals.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
#include "route/fib.hpp"
|
||||
#include "lsdb.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace nlsr {
|
||||
class Nlsr;
|
||||
|
||||
class NamePrefixTable
|
||||
{
|
||||
@@ -41,10 +42,23 @@ public:
|
||||
using NptEntryList = std::list<std::shared_ptr<NamePrefixTableEntry>>;
|
||||
using const_iterator = NptEntryList::const_iterator;
|
||||
|
||||
NamePrefixTable(Nlsr& nlsr, std::unique_ptr<AfterRoutingChange>& afterRoutingChangeSignal);
|
||||
NamePrefixTable(const ndn::Name& ownRouterName, Fib& fib, RoutingTable& routingTable,
|
||||
AfterRoutingChange& afterRoutingChangeSignal,
|
||||
Lsdb::AfterLsdbModified& afterLsdbModifiedSignal);
|
||||
|
||||
~NamePrefixTable();
|
||||
|
||||
/*! \brief Add, update, or remove Names according to the Lsdb update
|
||||
\param lsa The LSA class pointer
|
||||
\param updateType Update type from Lsdb (INSTALLED, UPDATED, REMOVED)
|
||||
\param namesToAdd If LSA is UPDATED, then these are the names to add
|
||||
\param namesToRemove If LSA is UPDATED, then these are the names to remove
|
||||
*/
|
||||
void
|
||||
updateFromLsdb(std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
|
||||
const std::list<ndn::Name>& namesToAdd,
|
||||
const std::list<ndn::Name>& namesToRemove);
|
||||
|
||||
/*! \brief Adds a destination to the specified name prefix.
|
||||
\param name The name prefix
|
||||
\param destRouter The destination router prefix
|
||||
@@ -124,8 +138,11 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
NptEntryList m_table;
|
||||
|
||||
private:
|
||||
Nlsr& m_nlsr;
|
||||
ndn::util::signal::Connection m_afterRoutingChangeConnection;
|
||||
const ndn::Name& m_ownRouterName;
|
||||
Fib& m_fib;
|
||||
RoutingTable& m_routingTable;
|
||||
ndn::signal::Connection m_afterRoutingChangeConnection;
|
||||
ndn::signal::Connection m_afterLsdbModified;
|
||||
};
|
||||
|
||||
inline NamePrefixTable::const_iterator
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2018, 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.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "nexthop-list.hpp"
|
||||
#include "common.hpp"
|
||||
#include "nexthop.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(route.NexthopList);
|
||||
|
||||
static bool
|
||||
nexthopAddCompare(const NextHop& nh1, const NextHop& nh2)
|
||||
{
|
||||
return nh1.getConnectingFaceUri() == nh2.getConnectingFaceUri();
|
||||
}
|
||||
|
||||
static bool
|
||||
nexthopRemoveCompare(const NextHop& nh1, const NextHop& nh2)
|
||||
{
|
||||
return (nh1.getConnectingFaceUri() == nh2.getConnectingFaceUri() &&
|
||||
nh1.getRouteCostAsAdjustedInteger() == nh2.getRouteCostAsAdjustedInteger()) ;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const NexthopList& lhs, const NexthopList& rhs)
|
||||
{
|
||||
if (lhs.size() != rhs.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NexthopList slhs = lhs;
|
||||
NexthopList srhs = rhs;
|
||||
|
||||
for (struct {std::set<NextHop>::iterator lItr;
|
||||
std::set<NextHop>::iterator rItr;} pair = {slhs.begin(), srhs.begin()};
|
||||
(pair.lItr != slhs.end() || pair.rItr != srhs.end());
|
||||
pair.rItr++, pair.lItr++) {
|
||||
if (!((*pair.lItr) == (*pair.rItr))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const NexthopList& lhs, const NexthopList& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NexthopList& nhl)
|
||||
{
|
||||
NexthopList& ucnhl = const_cast<NexthopList&>(nhl);
|
||||
os << "NexthopList(\nNext hops: ";
|
||||
for (auto&& nh : ucnhl.getNextHops()) {
|
||||
os << nh;
|
||||
}
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
void
|
||||
NexthopList::addNextHop(const NextHop& nh)
|
||||
{
|
||||
std::set<NextHop, NextHopComparator>::iterator it = std::find_if(m_nexthopList.begin(),
|
||||
m_nexthopList.end(),
|
||||
std::bind(&nexthopAddCompare, _1, nh));
|
||||
if (it == m_nexthopList.end()) {
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
else if (it->getRouteCost() > nh.getRouteCost()) {
|
||||
removeNextHop(*it);
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NexthopList::removeNextHop(const NextHop& nh)
|
||||
{
|
||||
std::set<NextHop, NextHopComparator>::iterator it = std::find_if(m_nexthopList.begin(),
|
||||
m_nexthopList.end(),
|
||||
std::bind(&nexthopRemoveCompare, _1, nh));
|
||||
if (it != m_nexthopList.end()) {
|
||||
m_nexthopList.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NexthopList::writeLog()
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
for (std::set<NextHop, NextHopComparator>::iterator it = m_nexthopList.begin();
|
||||
it != m_nexthopList.end() ; it++, i++) {
|
||||
NLSR_LOG_DEBUG("Nexthop " << i << ": " << (*it).getConnectingFaceUri()
|
||||
<< " Route Cost: " << (*it).getRouteCost());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
Loaded 100 of 225 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user