Compare commits
95
Commits
NLSR-0.5.0
..
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 |
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
-24
@@ -1,33 +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 gcovr lcov libgd-perl
|
||||
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
|
||||
+23
-31
@@ -1,57 +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=
|
||||
NDN_CXX=$(ndnsec version)
|
||||
OLD_NDN_CXX=$(cat ndn_cxx_chrono.txt || :)
|
||||
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
|
||||
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
|
||||
echo "$NDN_CXX" > ndn_cxx_chrono.txt
|
||||
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
|
||||
+23
-31
@@ -1,57 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -exo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
PROJ=PSync
|
||||
|
||||
set -x
|
||||
|
||||
pushd "${CACHE_DIR:-/tmp}" >/dev/null
|
||||
pushd "$CACHE_DIR" >/dev/null
|
||||
|
||||
INSTALLED_VERSION=
|
||||
NDN_CXX=$(ndnsec version)
|
||||
OLD_NDN_CXX=$(cat ndn_cxx_psync.txt || :)
|
||||
OLD_NDN_CXX=$(cat "$PROJ-ndn-cxx.txt" || :)
|
||||
if [[ $OLD_NDN_CXX != $NDN_CXX ]]; then
|
||||
echo "$NDN_CXX" > ndn_cxx_psync.txt
|
||||
echo "$NDN_CXX" > "$PROJ-ndn-cxx.txt"
|
||||
INSTALLED_VERSION=NONE
|
||||
fi
|
||||
|
||||
if [[ -z $INSTALLED_VERSION ]]; then
|
||||
INSTALLED_VERSION=$(git -C PSync 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 PSync-latest
|
||||
|
||||
git clone --depth 1 git://github.com/named-data/PSync PSync-latest
|
||||
|
||||
LATEST_VERSION=$(git -C PSync-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 PSync
|
||||
mv PSync-latest PSync
|
||||
sudo rm -rf "$PROJ"
|
||||
mv "$PROJ-latest" "$PROJ"
|
||||
else
|
||||
sudo rm -Rf PSync-latest
|
||||
sudo rm -rf "$PROJ-latest"
|
||||
fi
|
||||
|
||||
sudo rm -fr /usr/local/include/PSync
|
||||
sudo rm -f /usr/local/lib/libPSync*
|
||||
sudo rm -f /usr/local/lib/pkgconfig/PSync*
|
||||
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 PSync >/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=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-16.04`, `Ubuntu-18.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.11`, `OSX-10.12`, `OSX-10.13`
|
||||
- `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` (Ubuntu Linux 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}
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
language: cpp
|
||||
dist: xenial
|
||||
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++-5
|
||||
- os: linux
|
||||
env: COMPILER=g++-6
|
||||
- os: linux
|
||||
env: COMPILER=g++-7
|
||||
- os: linux
|
||||
env: COMPILER=g++-8
|
||||
|
||||
# Linux/clang
|
||||
# https://apt.llvm.org/
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.5
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.6
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.8
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.9
|
||||
- os: linux
|
||||
env: COMPILER=clang++-4.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-5.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-6.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-7
|
||||
|
||||
# macOS/clang
|
||||
# https://docs.travis-ci.com/user/reference/osx/#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.3
|
||||
env: OSX_VERSION=10.13
|
||||
|
||||
allow_failures:
|
||||
- env: COMPILER=g++-6
|
||||
- env: COMPILER=g++-7
|
||||
- env: COMPILER=g++-8
|
||||
- env: COMPILER=clang++-3.5
|
||||
- env: COMPILER=clang++-3.6
|
||||
- env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
|
||||
- env: COMPILER=clang++-3.8
|
||||
- env: COMPILER=clang++-3.9
|
||||
- env: COMPILER=clang++-4.0
|
||||
- env: COMPILER=clang++-5.0
|
||||
- env: COMPILER=clang++-6.0
|
||||
- env: COMPILER=clang++-7
|
||||
|
||||
fast_finish: true
|
||||
|
||||
install: |
|
||||
case ${COMPILER} in
|
||||
g++-[6789])
|
||||
travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
travis_retry sudo apt-get -qq update
|
||||
travis_retry sudo apt-get -qy install "${COMPILER}"
|
||||
;;
|
||||
clang++-*)
|
||||
CLANG_VERSION=${COMPILER/clang++}
|
||||
if [[ ${CLANG_VERSION} != "-3."* ]]; then
|
||||
wget -O - "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo apt-key add -
|
||||
travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial${CLANG_VERSION/-7} main"
|
||||
fi
|
||||
travis_retry sudo apt-get -qq update
|
||||
travis_retry sudo apt-get -qy install "clang${CLANG_VERSION}"
|
||||
;;
|
||||
esac
|
||||
|
||||
before_script:
|
||||
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-16.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 < (5, 3, 0):
|
||||
if ccver < (7, 4, 0):
|
||||
errmsg = ('The version of gcc you are using is too old.\n'
|
||||
'The minimum supported gcc version is 5.3.0.')
|
||||
'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, 6, 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.6.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,11 +46,11 @@ 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++ language standard)
|
||||
generalFlags = conf.flags.getGeneralFlags(conf)
|
||||
@@ -45,6 +58,7 @@ def configure(conf):
|
||||
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,95 +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++14']
|
||||
if Utils.unversioned_sys_platform() == 'linux':
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold']
|
||||
elif Utils.unversioned_sys_platform() == 'freebsd':
|
||||
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'] += ['-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'] += ['-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)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
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)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
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
|
||||
if Utils.unversioned_sys_platform() == 'freebsd':
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']] # Bug #4790
|
||||
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-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']
|
||||
if version < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
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']
|
||||
if version < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
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
-55
@@ -1,59 +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>
|
||||
* Saurab Dulal <https://dulalsaurab.github.io>
|
||||
## Technical Advisors
|
||||
|
||||
## Past project leads:
|
||||
|
||||
* A K M Mahmudul Hoque <https://sites.google.com/site/akmhoque/home>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
* Nicholas Gordon <nmgordon@memphis.edu>
|
||||
|
||||
## 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>
|
||||
|
||||
* Universidad Autónoma de San Luis Potosí (UASLP)
|
||||
|
||||
* Pedro David Arjona Villicaña <david.arjona@uaslp.mx>
|
||||
|
||||
* Individual Contributor(s)
|
||||
|
||||
* Junxiao Shi <https://www.linkedin.com/in/shijunxiao>
|
||||
* 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), Saurab Dulal (sdulal@memphis.edu),
|
||||
Muktadir R Chowdhury (mrchwdhr@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>
|
||||
+5
-3
@@ -15,14 +15,16 @@ NLSR relies on third-party software, licensed under the following licenses:
|
||||
- PSync is licensed under the terms of the
|
||||
[GNU Lesser General Public License version 3](https://github.com/named-data/PSync/blob/master/COPYING.md)
|
||||
|
||||
- ndn-svs is licensed under the terms of the
|
||||
[GNU Lesser General Public License v2.1](https://github.com/named-data/ndn-svs/blob/master/COPYING.md)
|
||||
|
||||
- The waf build system is licensed under the terms of the
|
||||
[BSD license](https://github.com/named-data/NLSR/blob/master/waf)
|
||||
|
||||
|
||||
The GPL license is provided below in this file.
|
||||
For more information, see http://www.gnu.org/licenses/
|
||||
For more information, see <https://www.gnu.org/licenses/>
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
### GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
|
||||
+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.
|
||||
+12
-13
@@ -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,19 +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 following command will display all log
|
||||
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:
|
||||
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
|
||||
|
||||
Use `man ndn-log` for more detailed instructions.
|
||||
See ``man ndn-log`` for more details (`online version
|
||||
<https://docs.named-data.net/ndn-cxx/current/manpages/ndn-log.html>`__).
|
||||
+28
-21
@@ -7,48 +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 ChronoSync library and build it according to the instructions at the following
|
||||
address:
|
||||
Download the PSync library and build it according to the instructions available at
|
||||
https://github.com/named-data/PSync#build
|
||||
|
||||
::
|
||||
- ChronoSync library [optional, deprecated]
|
||||
|
||||
https://github.com/named-data/ChronoSync#build
|
||||
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
|
||||
|
||||
- PSync library:
|
||||
- SVS library [optional]
|
||||
|
||||
Download the PSync library and build it according to the instructions at the following
|
||||
address:
|
||||
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
|
||||
|
||||
::
|
||||
|
||||
https://github.com/named-data/PSync#build
|
||||
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
|
||||
@@ -49,16 +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. Its documentation can
|
||||
be found `here
|
||||
<https://named-data.net/doc/NFD/current/manpages/nfdc.html>`_
|
||||
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
|
||||
---------------------------
|
||||
|
||||
Whitespace-only changes.
+119
-120
@@ -17,11 +17,12 @@ A beginners guide to installing and testing NLSR on Fedora
|
||||
|
||||
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, 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>`__).
|
||||
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
|
||||
@@ -32,7 +33,7 @@ using the following command:
|
||||
|
||||
$ sudo -i
|
||||
|
||||
And then using the *passwd* command to set up a password. After setting
|
||||
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:
|
||||
|
||||
@@ -40,7 +41,7 @@ following command and providing the root password when prompted:
|
||||
|
||||
$ su -
|
||||
|
||||
Fedora employs the *dnf* command to install and verify installed
|
||||
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:
|
||||
|
||||
@@ -75,7 +76,7 @@ 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
|
||||
downloaded to their own directory using the ``git`` command, and then
|
||||
compiled in this directory.
|
||||
|
||||
.. _ndncxx:
|
||||
@@ -88,7 +89,7 @@ compiled in this directory.
|
||||
|
||||
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 bellow with the commands to verify that all
|
||||
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:
|
||||
|
||||
@@ -99,24 +100,22 @@ should be run as root:
|
||||
$ dnf list --installed gcc
|
||||
$ dnf list --installed gcc-c++
|
||||
|
||||
#. Python version 2.6 or later
|
||||
#. Python version 3.8 or later
|
||||
|
||||
::
|
||||
|
||||
$ python -V
|
||||
$ python3 -V
|
||||
|
||||
#. libsqlite3
|
||||
#. SQLite 3.x
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed sqlite
|
||||
$ dnf list --installed sqlite-devel
|
||||
|
||||
#. openssl version 1.0.1 or later
|
||||
#. OpenSSL version 1.1.1 or later
|
||||
|
||||
::
|
||||
|
||||
$ openssl version
|
||||
$ dnf list --installed openssl-devel
|
||||
|
||||
#. pkgconf that replaces pkg-config
|
||||
@@ -125,73 +124,47 @@ should be run as root:
|
||||
|
||||
$ dnf list --installed pkgconf*
|
||||
|
||||
#. boost libraries version 1.54 or later
|
||||
#. Boost libraries version 1.71.0 or later
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed boost
|
||||
$ dnf list --installed boost-devel
|
||||
|
||||
#. doxygen
|
||||
#. git
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed git
|
||||
|
||||
#. doxygen (optional)
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed doxygen
|
||||
|
||||
#. graphviz
|
||||
#. graphviz (optional)
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed graphviz
|
||||
|
||||
#. python2-sphinx that replaces python-sphinx
|
||||
#. python3-pip (optional)
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed python2-sphinx
|
||||
$ dnf list --installed python3-pip
|
||||
|
||||
#. After verifying that the python-sphinx package has been installed, it
|
||||
is necessary to run the following two commands:
|
||||
#. After verifying that the python3-pip package has been installed, it
|
||||
is necessary to run the following command:
|
||||
|
||||
::
|
||||
|
||||
$ pip-3 install sphinxcontrib-doxylink
|
||||
$ pip install sphinxcontrib-googleanalytics
|
||||
|
||||
Note: When the two previous commands are run before correctly
|
||||
installing python-sphinx, the following error message is produced
|
||||
when trying to install this latter package: “Error unpacking rpm
|
||||
package python2-urllib3-1.22-3.fc27.noarch”. To fix this problem, it
|
||||
is necessary to run the following commands before installing
|
||||
python-sphinx again:
|
||||
|
||||
::
|
||||
|
||||
$ dnf remove python2-sphinx
|
||||
$ pip uninstall sphinxcontrib-googleanalytics
|
||||
$ pip-3 uninstall sphinxcontrib-doxylink
|
||||
$ pip uninstall urllib3
|
||||
|
||||
#. dpkg-architecture
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed dpkg
|
||||
$ dnf list --installed dpkg-dev
|
||||
|
||||
#. git and valgrind, which is used when installing NFD (§
|
||||
`3 <#nfd>`__).
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed valgrind
|
||||
$ dnf list --installed valgrind-devel
|
||||
$ dnf list --installed git
|
||||
$ 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
|
||||
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>`__:
|
||||
|
||||
@@ -214,7 +187,7 @@ continuing:
|
||||
$ ./waf configure --with-examples
|
||||
|
||||
Compile the ndn-cxx library and install the compiled files at the
|
||||
system’s directories:
|
||||
system's directories:
|
||||
|
||||
::
|
||||
|
||||
@@ -248,8 +221,7 @@ Configure the NDN path:
|
||||
|
||||
::
|
||||
|
||||
$ echo export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig >>
|
||||
/etc/profile.d/ndn.sh
|
||||
$ 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
|
||||
@@ -281,17 +253,16 @@ 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:
|
||||
|
||||
#. libpcap libraries
|
||||
#. pcap library
|
||||
|
||||
::
|
||||
|
||||
$ dnf list --installed libpcap
|
||||
$ dnf list --installed libpcap-devel
|
||||
|
||||
3.2 Downloading and installing NFD
|
||||
----------------------------------
|
||||
|
||||
This library is downloaded and installed in a folder called *NFD*, which
|
||||
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:
|
||||
|
||||
@@ -303,25 +274,15 @@ following commands need to be run as a regular user:
|
||||
|
||||
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 execute either of the
|
||||
following two set of commands:
|
||||
this same output, which tells the user to run the following command:
|
||||
|
||||
::
|
||||
|
||||
$ git submodule init && git submodule update
|
||||
$ git submodule update --init
|
||||
|
||||
Or:
|
||||
|
||||
::
|
||||
|
||||
$ mkdir websocketpp
|
||||
$ curl -L https://github.com/zaphoyd/websocketpp/archive/0.7.0.tar.gz
|
||||
> websocket.tar.gz
|
||||
$ tar zxf websocket.tar.gz -C websocketpp/ --strip 1
|
||||
|
||||
After executing either of these instructions, complete the configuration
|
||||
by running *./waf configure* again. Then complete the installation by
|
||||
means of the following commands:
|
||||
After executing these instructions, complete the configuration by running
|
||||
``./waf configure`` again. Then complete the installation by means of the
|
||||
following commands:
|
||||
|
||||
::
|
||||
|
||||
@@ -337,7 +298,7 @@ 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
|
||||
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:
|
||||
|
||||
@@ -348,7 +309,7 @@ created, it is recommended to start NFD by using the following command:
|
||||
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
|
||||
to verify NDF's status and then stop NFD by using the following
|
||||
commands:
|
||||
|
||||
::
|
||||
@@ -361,8 +322,40 @@ commands:
|
||||
4. Installing NLSR
|
||||
==================
|
||||
|
||||
4.1 Installing ChronoSync
|
||||
-------------------------
|
||||
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
|
||||
@@ -391,19 +384,19 @@ This command should display a line similar to the following:
|
||||
|
||||
libChronoSync.so.0.5.0 -> libChronoSync.so.0.5.0
|
||||
|
||||
4.2 Installing PSync
|
||||
-------------------------
|
||||
4.3 [Optional] Installing SVS
|
||||
-----------------------------
|
||||
|
||||
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>`__:
|
||||
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/PSync.git
|
||||
$ cd PSync
|
||||
$ git clone --depth 1 https://github.com/named-data/ndn-svs.git
|
||||
$ cd ndn-svs
|
||||
$ ./waf configure
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
@@ -412,15 +405,15 @@ The following command needs to be used again to configure the libraries:
|
||||
|
||||
::
|
||||
|
||||
$ sudo ldconfig -v | grep -i psync
|
||||
$ sudo ldconfig -v | grep ndn-svs
|
||||
|
||||
This command should display a line similar to the following:
|
||||
|
||||
::
|
||||
|
||||
libPSync.so.0.1.0 -> libPSync.so.0.1.0
|
||||
libndn-svs.so.0.0.1 -> libndn-svs.so.0.0.1
|
||||
|
||||
4.3 Downloading and installing NLSR
|
||||
4.4 Downloading and installing NLSR
|
||||
-----------------------------------
|
||||
|
||||
NLSR is downloaded and installed in a folder called *NLSR* which should
|
||||
@@ -435,7 +428,13 @@ commands need to be run as a regular user:
|
||||
$ ./waf
|
||||
$ sudo ./waf install
|
||||
|
||||
4.4 Configuring NLSR
|
||||
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
|
||||
@@ -574,10 +573,10 @@ 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.
|
||||
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:
|
||||
brief description of all the ``ndnsec`` commands:
|
||||
|
||||
::
|
||||
|
||||
@@ -605,12 +604,12 @@ 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
|
||||
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:
|
||||
The simplest way to do this is by using the ``ping`` command:
|
||||
|
||||
::
|
||||
|
||||
@@ -620,7 +619,7 @@ The simplest way to do this is by using the *ping* command:
|
||||
--------------------------------
|
||||
|
||||
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*
|
||||
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
|
||||
@@ -644,7 +643,7 @@ to connect to a neighboring computer:
|
||||
|
||||
$ nfdc face create udp4://<remote-ip-address>
|
||||
|
||||
The face id may be displayed by running either *nfd-status* or:
|
||||
The face id may be displayed by running:
|
||||
|
||||
::
|
||||
|
||||
@@ -668,7 +667,7 @@ the other machine.
|
||||
-------------------------------------
|
||||
|
||||
Instructions on how to use the configuration file are already provided
|
||||
at the NLSR’s Router Configuration page [NLSRrtrconf]_.
|
||||
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:
|
||||
@@ -809,19 +808,19 @@ following two commands:
|
||||
$ 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:
|
||||
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>
|
||||
$ 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.
|
||||
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:
|
||||
|
||||
@@ -848,7 +847,7 @@ recommended:
|
||||
|
||||
$ nfd-stop
|
||||
|
||||
#. The crossover Ethernet cable may be unplugged and the computers’
|
||||
#. The crossover Ethernet cable may be unplugged and the computers'
|
||||
network configuration restored to its original settings.
|
||||
|
||||
5.7 Where to go from here
|
||||
@@ -861,27 +860,27 @@ configuration management tool, to manage the official NDN testbed
|
||||
deployment [NDNTestbed]_.
|
||||
|
||||
|
||||
.. [NDNmain] *Named Data Networking*, http://named-data.net/, March 2018.
|
||||
.. [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*, http://named-data.net/doc/ndn-cxx/current/INSTALL.html, April 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*, http://named-data.net/doc/NFD/current/INSTALL.html, April 2018.
|
||||
.. [NDNNFD] *Getting started with NFD*, https://docs.named-data.net/NFD/current/INSTALL.html, April 2018.
|
||||
|
||||
.. [NDNNFDusage] *NFD usage*, http://named-data.net/doc/NFD/current/manpages/nfd.html, May 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.
|
||||
.. [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*, http://named-data.net/doc/NLSR/current/SECURITY-CONFIG.html June 2018.
|
||||
.. [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.
|
||||
.. [NLSRdevguide] V. Lehman, M. Chowdhury, N. Gordon, A. Gawande. *NLSR Developer's Guide*, University of Memphis, November 2017.
|
||||
|
||||
.. [NLSRrtrconf] *NLSR Router Configuration*, http://named-data.net/doc/NLSR/current/ROUTER-CONFIG.html, April 2018.
|
||||
.. [NLSRrtrconf] *NLSR Router Configuration*, https://docs.named-data.net/NLSR/current/ROUTER-CONFIG.html, April 2018.
|
||||
|
||||
.. [NLSRstarting] *Getting Started with NLSR*, http://named-data.net/doc/NLSR/current/GETTING-STARTED.html, May 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.
|
||||
|
||||
|
||||
+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
-47
@@ -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,59 +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
|
||||
SECURITY-CONFIG
|
||||
ROUTER-CONFIG
|
||||
RELEASE-NOTES
|
||||
releases
|
||||
manpages
|
||||
beginners-guide
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
- :doc:`GETTING-STARTED`
|
||||
- :doc:`INSTALL`
|
||||
- :doc:`SECURITY-CONFIG`
|
||||
- :doc:`ROUTER-CONFIG`
|
||||
- :doc:`RELEASE-NOTES`
|
||||
- :doc:`releases`
|
||||
- :doc:`manpages`
|
||||
- :doc:`beginners-guide`
|
||||
- :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/*
|
||||
+19
-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``
|
||||
@@ -67,18 +79,16 @@ 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 %}
|
||||
|
||||
|
||||
@@ -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.5.0.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,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`)
|
||||
+57
-24
@@ -1,73 +1,106 @@
|
||||
NLSR Versions
|
||||
+++++++++++++
|
||||
All NLSR Releases
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
|
||||
release-notes/release-notes-0.5.0
|
||||
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
|
||||
:reversed:
|
||||
|
||||
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>`__)
|
||||
@@ -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,7 +19,7 @@ general
|
||||
; InterestLifetime (in seconds) for LSA fetching
|
||||
lsa-interest-lifetime 4 ; default value 4. Valid values 1-60
|
||||
|
||||
; select sync protocol: chronosync or psync
|
||||
; select sync protocol: chronosync / psync / svs
|
||||
sync-protocol psync
|
||||
|
||||
; sync interest lifetime of ChronoSync/PSync in milliseconds
|
||||
@@ -28,7 +28,7 @@ general
|
||||
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
|
||||
{
|
||||
@@ -38,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
|
||||
@@ -47,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
|
||||
@@ -149,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><><>$
|
||||
@@ -177,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>
|
||||
@@ -194,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"
|
||||
@@ -206,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><><><>$
|
||||
@@ -234,7 +257,7 @@ security
|
||||
checker
|
||||
{
|
||||
type hierarchical
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,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}$
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,7 +305,7 @@ security
|
||||
checker
|
||||
{
|
||||
type hierarchical
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+39
-95
@@ -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;
|
||||
}
|
||||
@@ -80,56 +60,47 @@ AdjacencyList::operator==(const AdjacencyList& adl) const
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -141,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);
|
||||
}
|
||||
@@ -164,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;
|
||||
}
|
||||
@@ -174,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++;
|
||||
}
|
||||
}
|
||||
@@ -198,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);
|
||||
|
||||
|
||||
+129
-41
@@ -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
|
||||
{
|
||||
@@ -83,16 +175,12 @@ Adjacent::operator<(const Adjacent& adjacent) const
|
||||
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
-19
@@ -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,43 +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/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-2019, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,103 +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 "hello-protocol.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "utility/name-helper.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
const std::string NLSR_COMPONENT = "nlsr";
|
||||
const std::string LSA_COMPONENT = "LSA";
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(SyncLogicHandler);
|
||||
|
||||
template<class T>
|
||||
class NullDeleter
|
||||
{
|
||||
public:
|
||||
void
|
||||
operator()(T*)
|
||||
{
|
||||
}
|
||||
};
|
||||
const std::string LSA_COMPONENT{"LSA"};
|
||||
|
||||
SyncLogicHandler::SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew,
|
||||
const ConfParameter& conf)
|
||||
: onNewLsa(std::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))
|
||||
{
|
||||
createSyncLogic(conf.getSyncPrefix());
|
||||
}
|
||||
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));
|
||||
|
||||
void
|
||||
SyncLogicHandler::createSyncLogic(const ndn::Name& syncPrefix, const ndn::time::milliseconds& syncInterestLifetime)
|
||||
{
|
||||
if (m_syncLogic != nullptr) {
|
||||
NLSR_LOG_WARN("Trying to create Sync Logic object, but Sync Logic object already exists");
|
||||
return;
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_ON) {
|
||||
m_syncLogic.addUserNode(m_adjLsaUserPrefix);
|
||||
}
|
||||
|
||||
// Build LSA sync update prefix
|
||||
buildUpdatePrefix();
|
||||
|
||||
NLSR_LOG_DEBUG("Creating Sync Logic object. Sync Prefix: " << syncPrefix);
|
||||
|
||||
// The face's lifetime is managed in main.cpp; Logic should not manage the memory
|
||||
// of the object
|
||||
std::shared_ptr<ndn::Face> facePtr(&m_syncFace, NullDeleter<ndn::Face>());
|
||||
|
||||
m_syncLogic = std::make_shared<SyncProtocolAdapter>(*facePtr,
|
||||
m_confParam.getSyncProtocol(),
|
||||
syncPrefix,
|
||||
m_nameLsaUserPrefix,
|
||||
syncInterestLifetime,
|
||||
std::bind(&SyncLogicHandler::processUpdate, this, _1, _2));
|
||||
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) {
|
||||
m_syncLogic->addUserNode(m_adjLsaUserPrefix);
|
||||
}
|
||||
else if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_syncLogic->addUserNode(m_coorLsaUserPrefix);
|
||||
}
|
||||
else {
|
||||
m_syncLogic->addUserNode(m_adjLsaUserPrefix);
|
||||
m_syncLogic->addUserNode(m_coorLsaUserPrefix);
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
|
||||
m_syncLogic.addUserNode(m_coorLsaUserPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::processUpdate(const ndn::Name& updateName, uint64_t highSeq)
|
||||
SyncLogicHandler::processUpdate(const ndn::Name& updateName, uint64_t highSeq, uint64_t incomingFaceId)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Update Name: " << updateName << " Seq no: " << highSeq);
|
||||
|
||||
int32_t nlsrPosition = util::getNameComponentPosition(updateName, nlsr::NLSR_COMPONENT);
|
||||
int32_t lsaPosition = util::getNameComponentPosition(updateName, nlsr::LSA_COMPONENT);
|
||||
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;
|
||||
}
|
||||
|
||||
ndn::Name networkName = updateName.getSubName(1, nlsrPosition-1);
|
||||
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, highSeq);
|
||||
processUpdateFromSync(originRouter, updateName, highSeq, incomingFaceId);
|
||||
}
|
||||
|
||||
void
|
||||
SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
const ndn::Name& updateName, uint64_t seqNo)
|
||||
const ndn::Name& updateName, uint64_t seqNo,
|
||||
uint64_t incomingFaceId)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Origin Router of update: " << originRouter);
|
||||
|
||||
@@ -126,7 +92,7 @@ SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
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 " <<
|
||||
@@ -140,7 +106,8 @@ SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
"is enabled. Not going to fetch.");
|
||||
return;
|
||||
}
|
||||
(*onNewLsa)(updateName, seqNo);
|
||||
|
||||
onNewLsa(updateName, seqNo, originRouter, incomingFaceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,42 +115,19 @@ SyncLogicHandler::processUpdateFromSync(const ndn::Name& originRouter,
|
||||
void
|
||||
SyncLogicHandler::publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo)
|
||||
{
|
||||
if (m_syncLogic == nullptr) {
|
||||
NLSR_LOG_FATAL("Cannot publish routing update; SyncLogic does not exist");
|
||||
|
||||
BOOST_THROW_EXCEPTION(SyncLogicHandler::Error("Cannot publish routing update; SyncLogic does not exist"));
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case Lsa::Type::ADJACENCY:
|
||||
m_syncLogic->publishUpdate(m_adjLsaUserPrefix, seqNo);
|
||||
m_syncLogic.publishUpdate(m_adjLsaUserPrefix, seqNo);
|
||||
break;
|
||||
case Lsa::Type::COORDINATE:
|
||||
m_syncLogic->publishUpdate(m_coorLsaUserPrefix, seqNo);
|
||||
m_syncLogic.publishUpdate(m_coorLsaUserPrefix, seqNo);
|
||||
break;
|
||||
case Lsa::Type::NAME:
|
||||
m_syncLogic->publishUpdate(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));
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,52 +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 "sync-protocol-adapter.hpp"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
class InterestManager;
|
||||
#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*/)>;
|
||||
|
||||
SyncLogicHandler(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
IsLsaNew isLsaNew, const ConfParameter& conf);
|
||||
|
||||
/*! \brief Instruct ChronoSync to publish an update.
|
||||
*
|
||||
@@ -77,19 +65,6 @@ public:
|
||||
publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Create and configure a Logic object to enable Sync for this NLSR.
|
||||
*
|
||||
* In a typical situation this only needs to be called once, when NLSR starts.
|
||||
* \param syncPrefix The sync prefix you want this Sync to use
|
||||
* \param syncInterestLifetime ChronoSync/PSync sends a periodic sync interest every
|
||||
* \p syncInterestLifetime / 2 ms
|
||||
* \sa Nlsr::initialize
|
||||
*/
|
||||
void
|
||||
createSyncLogic(const ndn::Name& syncPrefix,
|
||||
const ndn::time::milliseconds& syncInterestLifetime =
|
||||
ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT));
|
||||
|
||||
/*! \brief Callback from Sync protocol
|
||||
*
|
||||
* In a typical situation this only needs to be called once, when NLSR starts.
|
||||
@@ -97,12 +72,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
* \param highSeq The latest sequence number of the update
|
||||
*/
|
||||
void
|
||||
processUpdate(const ndn::Name& updateName, uint64_t highSeq);
|
||||
|
||||
/*! \brief Simple function to glue Name components together
|
||||
*/
|
||||
void
|
||||
buildUpdatePrefix();
|
||||
processUpdate(const ndn::Name& updateName, uint64_t highSeq, uint64_t incomingFaceId);
|
||||
|
||||
/*! \brief Determine which kind of LSA was updated and fetch it.
|
||||
*
|
||||
@@ -114,15 +84,11 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
*/
|
||||
void
|
||||
processUpdateFromSync(const ndn::Name& originRouter,
|
||||
const ndn::Name& updateName, 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;
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
std::shared_ptr<SyncProtocolAdapter> m_syncLogic;
|
||||
private:
|
||||
IsLsaNew m_isLsaNew;
|
||||
const ConfParameter& m_confParam;
|
||||
@@ -132,9 +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
|
||||
|
||||
@@ -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,32 +17,37 @@
|
||||
*
|
||||
* 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"
|
||||
|
||||
INIT_LOGGER(SyncProtocolAdapter);
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(SyncProtocolAdapter);
|
||||
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
const auto FIXED_SESSION = ndn::name::Component::fromNumber(0);
|
||||
#endif
|
||||
|
||||
SyncProtocolAdapter::SyncProtocolAdapter(ndn::Face& face,
|
||||
int32_t syncProtocol,
|
||||
ndn::KeyChain& keyChain,
|
||||
SyncProtocol syncProtocol,
|
||||
const ndn::Name& syncPrefix,
|
||||
const ndn::Name& userPrefix,
|
||||
ndn::time::milliseconds syncInterestLifetime,
|
||||
const SyncUpdateCallback& syncUpdateCallback)
|
||||
: m_syncProtocol(syncProtocol)
|
||||
, m_syncUpdateCallback(syncUpdateCallback)
|
||||
SyncUpdateCallback syncUpdateCallback)
|
||||
: m_syncProtocol(syncProtocol)
|
||||
, m_syncUpdateCallback(std::move(syncUpdateCallback))
|
||||
{
|
||||
if (m_syncProtocol == SYNC_PROTOCOL_CHRONOSYNC) {
|
||||
switch (m_syncProtocol) {
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
case SyncProtocol::CHRONOSYNC:
|
||||
NDN_LOG_DEBUG("Using ChronoSync");
|
||||
m_chronoSyncLogic = std::make_shared<chronosync::Logic>(face,
|
||||
syncPrefix,
|
||||
userPrefix,
|
||||
std::bind(&SyncProtocolAdapter::onChronoSyncUpdate, this, _1),
|
||||
[this] (auto&&... args) { onChronoSyncUpdate(std::forward<decltype(args)>(args)...); },
|
||||
chronosync::Logic::DEFAULT_NAME,
|
||||
chronosync::Logic::DEFAULT_VALIDATOR,
|
||||
chronosync::Logic::DEFAULT_RESET_TIMER,
|
||||
@@ -52,40 +57,81 @@ SyncProtocolAdapter::SyncProtocolAdapter(ndn::Face& face,
|
||||
chronosync::Logic::DEFAULT_SYNC_REPLY_FRESHNESS,
|
||||
chronosync::Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME,
|
||||
FIXED_SESSION);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
#endif // HAVE_CHRONOSYNC
|
||||
#ifdef HAVE_PSYNC
|
||||
case SyncProtocol::PSYNC:
|
||||
NDN_LOG_DEBUG("Using PSync");
|
||||
m_psyncLogic = std::make_shared<psync::FullProducer>(80,
|
||||
face,
|
||||
m_psyncLogic = std::make_shared<psync::FullProducer>(face,
|
||||
keyChain,
|
||||
80,
|
||||
syncPrefix,
|
||||
userPrefix,
|
||||
std::bind(&SyncProtocolAdapter::onPSyncUpdate, this, _1),
|
||||
[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)
|
||||
{
|
||||
if (m_syncProtocol == SYNC_PROTOCOL_CHRONOSYNC) {
|
||||
switch (m_syncProtocol) {
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
case SyncProtocol::CHRONOSYNC:
|
||||
m_chronoSyncLogic->addUserNode(userPrefix, chronosync::Logic::DEFAULT_NAME, FIXED_SESSION);
|
||||
}
|
||||
else {
|
||||
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)
|
||||
{
|
||||
if (m_syncProtocol == SYNC_PROTOCOL_CHRONOSYNC) {
|
||||
switch (m_syncProtocol) {
|
||||
#ifdef HAVE_CHRONOSYNC
|
||||
case SyncProtocol::CHRONOSYNC:
|
||||
m_chronoSyncLogic->updateSeqNo(seq, userPrefix);
|
||||
}
|
||||
else {
|
||||
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)
|
||||
{
|
||||
@@ -93,18 +139,33 @@ SyncProtocolAdapter::onChronoSyncUpdate(const std::vector<chronosync::MissingDat
|
||||
|
||||
for (const auto& update : updates) {
|
||||
// Remove FIXED_SESSION
|
||||
m_syncUpdateCallback(update.session.getPrefix(-1), update.high);
|
||||
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);
|
||||
m_syncUpdateCallback(update.prefix, update.highSeq, update.incomingFace);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_PSYNC
|
||||
|
||||
} // namespace nlsr
|
||||
#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
|
||||
@@ -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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_SYNC_PROTOCOL_ADAPTER_HPP
|
||||
#define NLSR_SYNC_PROTOCOL_ADAPTER_HPP
|
||||
@@ -25,32 +25,42 @@
|
||||
#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 {
|
||||
|
||||
typedef std::function<void(const ndn::Name& updateName,
|
||||
uint64_t seqNo)> SyncUpdateCallback;
|
||||
using SyncUpdateCallback = std::function<void(const ndn::Name& updateName,
|
||||
uint64_t seqNo, uint64_t incomingFaceId)>;
|
||||
|
||||
class SyncProtocolAdapter
|
||||
{
|
||||
public:
|
||||
SyncProtocolAdapter(ndn::Face& facePtr,
|
||||
int32_t syncProtocol,
|
||||
SyncProtocolAdapter(ndn::Face& face,
|
||||
ndn::KeyChain& keyChain,
|
||||
SyncProtocol syncProtocol,
|
||||
const ndn::Name& syncPrefix,
|
||||
const ndn::Name& userPrefix,
|
||||
ndn::time::milliseconds syncInterestLifetime,
|
||||
const SyncUpdateCallback& syncUpdateCallback);
|
||||
SyncUpdateCallback syncUpdateCallback);
|
||||
|
||||
/*! \brief Add user node to ChronoSync or PSync
|
||||
/*! \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 ChronoSync or PSync
|
||||
/*! \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.
|
||||
@@ -62,33 +72,55 @@ public:
|
||||
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.
|
||||
* \sa m_syncUpdateCallback
|
||||
*
|
||||
* \param v A container with the new information sync has received
|
||||
* \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.
|
||||
* \sa m_syncUpdateCallback
|
||||
*
|
||||
* \param v A container with the new information sync has received
|
||||
* \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:
|
||||
int32_t m_syncProtocol;
|
||||
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
|
||||
|
||||
+154
-155
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,20 +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 "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 {
|
||||
|
||||
@@ -39,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)
|
||||
@@ -124,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;
|
||||
|
||||
@@ -142,76 +146,66 @@ ConfFileProcessor::ConfFileProcessor(ConfParameter& 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;
|
||||
}
|
||||
@@ -219,6 +213,38 @@ 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");
|
||||
@@ -228,7 +254,7 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
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);
|
||||
@@ -236,7 +262,7 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
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);
|
||||
@@ -244,7 +270,7 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -260,15 +286,14 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
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_confParam.getLsaRefreshTime()) {
|
||||
m_confParam.setRouterDeadInterval(routerDeadInterval);
|
||||
@@ -285,24 +310,9 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
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;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// sync-protocol
|
||||
std::string syncProtocol = section.get<std::string>("sync-protocol", "chronosync");
|
||||
if (syncProtocol == "chronosync") {
|
||||
m_confParam.setSyncProtocol(SYNC_PROTOCOL_CHRONOSYNC);
|
||||
}
|
||||
else if (syncProtocol == "psync") {
|
||||
m_confParam.setSyncProtocol(SYNC_PROTOCOL_PSYNC);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Sync protocol " << syncProtocol << " is not supported!"
|
||||
<< "Use chronosync or psync" << std::endl;
|
||||
std::cerr << "Invalid value for lsa-interest-timeout. "
|
||||
<< "Allowed range: " << LSA_INTEREST_LIFETIME_MIN
|
||||
<< "-" << LSA_INTEREST_LIFETIME_MAX << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -314,47 +324,63 @@ ConfFileProcessor::processConfSectionGeneral(const ConfigSection& section)
|
||||
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 stateDir = section.get<std::string>("state-dir");
|
||||
if (boost::filesystem::exists(stateDir)) {
|
||||
if (boost::filesystem::is_directory(stateDir)) {
|
||||
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;
|
||||
}
|
||||
|
||||
// copying nlsr.conf file to a user define directory for possible modification
|
||||
std::string conFileDynamic = (boost::filesystem::path(stateDir) / "nlsr.conf").c_str();
|
||||
m_confParam.setConfFileNameDynamic(conFileDynamic);
|
||||
try {
|
||||
copy_file(m_confFileName, conFileDynamic, boost::filesystem::copy_option::overwrite_if_exists);
|
||||
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 boost::filesystem::filesystem_error& e) {
|
||||
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 = (boost::filesystem::path(stateDir) / "test.seq").c_str();
|
||||
|
||||
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 state 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: " << stateDir << "is not a directory" << std::endl;
|
||||
std::cerr << "Provided path '" << stateDir << "' is not a directory" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Provided state directory <" << stateDir << "> does not exist" << std::endl;
|
||||
std::cerr << "Provided state directory '" << stateDir << "' does not exist" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -377,10 +403,8 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -391,10 +415,8 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -405,10 +427,8 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -426,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_confParam,
|
||||
_1));
|
||||
&m_confParam, _1));
|
||||
|
||||
faceDatasetFetchTries.setMinAndMaxValue(FACE_DATASET_FETCH_TRIES_MIN,
|
||||
FACE_DATASET_FETCH_TRIES_MAX);
|
||||
@@ -439,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_confParam,
|
||||
_1));
|
||||
std::bind(&ConfParameter::setFaceDatasetFetchInterval,
|
||||
&m_confParam, _1));
|
||||
|
||||
faceDatasetFetchInterval.setMinAndMaxValue(FACE_DATASET_FETCH_INTERVAL_MIN,
|
||||
FACE_DATASET_FETCH_INTERVAL_MAX);
|
||||
@@ -451,51 +469,38 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
|
||||
return false;
|
||||
}
|
||||
|
||||
// first-hello-interval
|
||||
ConfigurationVariable<uint32_t> firstHelloInterval("first-hello-interval",
|
||||
std::bind(&ConfParameter::setFirstHelloInterval,
|
||||
&m_confParam, _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;
|
||||
}
|
||||
|
||||
bool failedToCanonize = false;
|
||||
faceUri.canonize([&faceUri] (ndn::FaceUri canonicalUri) {
|
||||
faceUri.canonize([&faceUri] (const auto& canonicalUri) {
|
||||
faceUri = canonicalUri;
|
||||
},
|
||||
[&faceUri, &failedToCanonize] (const std::string& reason) {
|
||||
[&faceUri, &failedToCanonize] (const auto& reason) {
|
||||
failedToCanonize = true;
|
||||
std::cerr << "Could not canonize URI: " << faceUri
|
||||
<< "because: " << reason << std::endl;
|
||||
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);
|
||||
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);
|
||||
@@ -527,13 +532,12 @@ ConfFileProcessor::processConfSectionHyperbolic(const ConfigSection& section)
|
||||
else if (boost::iequals(state, "on")) {
|
||||
m_confParam.setHyperbolicState(HYPERBOLIC_STATE_ON);
|
||||
}
|
||||
else if (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;
|
||||
}
|
||||
|
||||
@@ -579,14 +583,13 @@ 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -607,12 +610,10 @@ 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_confParam.getNamePrefixList().insert(namePrefix);
|
||||
}
|
||||
@@ -633,10 +634,10 @@ 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;
|
||||
}
|
||||
|
||||
@@ -648,28 +649,26 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
|
||||
|
||||
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_confParam.getCertStore().insert(*idCert);
|
||||
m_confParam.getValidator().loadAnchor("Authoritative-Certificate",
|
||||
ndn::security::v2::Certificate(*idCert));
|
||||
m_confParam.getPrefixUpdateValidator().loadAnchor("Authoritative-Certificate",
|
||||
ndn::security::v2::Certificate(*idCert));
|
||||
m_confParam.addCertPath(certfilePath.string());
|
||||
m_confParam.loadCertToValidator(idCert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-16
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,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_CONF_FILE_PROCESSOR_HPP
|
||||
#define NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
@@ -24,24 +25,20 @@
|
||||
#include "common.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
|
||||
{
|
||||
@@ -59,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
|
||||
@@ -123,9 +118,10 @@ private:
|
||||
std::string m_confFileName;
|
||||
/*! m_confParam The ConfFileProcessor object to configure as parsing is done. */
|
||||
ConfParameter& m_confParam;
|
||||
/*! m_io For canonization of faceUri. */
|
||||
boost::asio::io_service m_io;
|
||||
/*! m_io For canonization of FaceUri. */
|
||||
boost::asio::io_context m_io;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_CONF_FILE_PROCESSOR_HPP
|
||||
+85
-22
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,26 +16,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/>.
|
||||
*
|
||||
* \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 = 6;
|
||||
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, const std::string& confFileName)
|
||||
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_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)))
|
||||
@@ -47,13 +51,13 @@ ConfParameter::ConfParameter(ndn::Face& face, const std::string& confFileName)
|
||||
, m_corR(0)
|
||||
, m_maxFacesPerPrefix(MAX_FACES_PER_PREFIX_MIN)
|
||||
, m_syncInterestLifetime(ndn::time::milliseconds(SYNC_INTEREST_LIFETIME_DEFAULT))
|
||||
, m_syncProtocol(SYNC_PROTOCOL_CHRONOSYNC)
|
||||
, m_adjl()
|
||||
, m_npl()
|
||||
, m_validator(std::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(face))
|
||||
, m_prefixUpdateValidator(std::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(face))
|
||||
{
|
||||
}
|
||||
, m_validator(makeCertificateFetcher(face))
|
||||
, m_prefixUpdateValidator(std::make_unique<ndn::security::CertificateFetcherDirectFetch>(face))
|
||||
, m_keyChain(keyChain)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConfParameter::writeLog()
|
||||
@@ -72,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("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);
|
||||
}
|
||||
|
||||
@@ -91,7 +96,9 @@ ConfParameter::setNetwork(const ndn::Name& networkName)
|
||||
{
|
||||
m_network = networkName;
|
||||
|
||||
m_syncPrefix.append("localhop");
|
||||
if (m_syncProtocol != SyncProtocol::SVS) {
|
||||
m_syncPrefix.append("localhop");
|
||||
}
|
||||
m_syncPrefix.append(m_network);
|
||||
m_syncPrefix.append("nlsr");
|
||||
m_syncPrefix.append("sync");
|
||||
@@ -103,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
|
||||
+72
-56
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,38 +17,36 @@
|
||||
*
|
||||
* 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 "security/certificate-store.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/validator-config.hpp>
|
||||
#include <ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp>
|
||||
#include <ndn-cxx/util/time.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,
|
||||
LSA_REFRESH_TIME_MAX = 7200
|
||||
};
|
||||
|
||||
enum {
|
||||
SYNC_PROTOCOL_CHRONOSYNC = 0,
|
||||
SYNC_PROTOCOL_PSYNC = 1
|
||||
};
|
||||
|
||||
enum {
|
||||
LSA_INTEREST_LIFETIME_MIN = 1,
|
||||
LSA_INTEREST_LIFETIME_DEFAULT = 4,
|
||||
@@ -56,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 {
|
||||
@@ -94,7 +86,7 @@ enum {
|
||||
|
||||
enum {
|
||||
HELLO_TIMEOUT_MIN = 1,
|
||||
HELLO_TIMEOUT_DEFAULT = 3,
|
||||
HELLO_TIMEOUT_DEFAULT = 1,
|
||||
HELLO_TIMEOUT_MAX = 15
|
||||
};
|
||||
|
||||
@@ -136,9 +128,9 @@ enum {
|
||||
*/
|
||||
class ConfParameter
|
||||
{
|
||||
|
||||
public:
|
||||
ConfParameter(ndn::Face& face, const std::string& confFileName = "nlsr.conf");
|
||||
ConfParameter(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
const std::string& confFileName = "nlsr.conf");
|
||||
|
||||
const std::string&
|
||||
getConfFileName()
|
||||
@@ -180,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&
|
||||
@@ -193,6 +189,12 @@ public:
|
||||
return m_routerPrefix;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getSyncUserPrefix() const
|
||||
{
|
||||
return m_syncUserPrefix;
|
||||
}
|
||||
|
||||
const ndn::Name&
|
||||
getSyncPrefix() const
|
||||
{
|
||||
@@ -211,18 +213,16 @@ public:
|
||||
m_lsaRefreshTime = lrt;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SyncProtocol
|
||||
getSyncProtocol() const
|
||||
{
|
||||
return m_syncProtocol;
|
||||
}
|
||||
|
||||
void
|
||||
setSyncProtocol(int32_t syncProtocol)
|
||||
setSyncProtocol(SyncProtocol syncProtocol)
|
||||
{
|
||||
if (syncProtocol == SYNC_PROTOCOL_CHRONOSYNC || syncProtocol == SYNC_PROTOCOL_PSYNC) {
|
||||
m_syncProtocol = syncProtocol;
|
||||
}
|
||||
m_syncProtocol = syncProtocol;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -255,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)
|
||||
{
|
||||
@@ -415,7 +403,8 @@ public:
|
||||
return m_stateFileDir;
|
||||
}
|
||||
|
||||
void setConfFileNameDynamic(const std::string& confFileDynamic)
|
||||
void
|
||||
setConfFileNameDynamic(const std::string& confFileDynamic)
|
||||
{
|
||||
m_confFileNameDynamic = confFileDynamic;
|
||||
}
|
||||
@@ -462,25 +451,52 @@ public:
|
||||
return m_prefixUpdateValidator;
|
||||
}
|
||||
|
||||
security::CertificateStore&
|
||||
getCertStore()
|
||||
const ndn::security::SigningInfo&
|
||||
getSigningInfo() const
|
||||
{
|
||||
return m_certStore;
|
||||
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();
|
||||
|
||||
private:
|
||||
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_syncPrefix;
|
||||
ndn::Name m_lsaPrefix;
|
||||
@@ -488,7 +504,6 @@ private:
|
||||
uint32_t m_lsaRefreshTime;
|
||||
|
||||
uint32_t m_adjLsaBuildInterval;
|
||||
uint32_t m_firstHelloInterval;
|
||||
uint32_t m_routingCalcInterval;
|
||||
|
||||
uint32_t m_faceDatasetFetchTries;
|
||||
@@ -512,18 +527,19 @@ private:
|
||||
|
||||
ndn::time::milliseconds m_syncInterestLifetime;
|
||||
|
||||
int32_t m_syncProtocol;
|
||||
|
||||
std::string m_confFileNameDynamic;
|
||||
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;
|
||||
security::CertificateStore m_certStore;
|
||||
ndn::security::SigningInfo m_signingInfo;
|
||||
std::unordered_set<std::string> m_certs;
|
||||
ndn::KeyChain& m_keyChain;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
+89
-76
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,85 +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(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
ndn::security::SigningInfo& signingInfo,
|
||||
ConfParameter& confParam, RoutingTable& routingTable,
|
||||
Lsdb& lsdb)
|
||||
: m_face(face)
|
||||
, m_scheduler(m_face.getIoService())
|
||||
, m_scheduler(m_face.getIoContext())
|
||||
, m_keyChain(keyChain)
|
||||
, m_signingInfo(signingInfo)
|
||||
, 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);
|
||||
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] (const ndn::Interest& interest, const ndn::lp::Nack& nack)
|
||||
{
|
||||
NDN_LOG_TRACE("Received Nack with reason " << nack.getReason());
|
||||
NDN_LOG_TRACE("Treating as timeout");
|
||||
processInterestTimedOut(interest);
|
||||
},
|
||||
std::bind(&HelloProtocol::processInterestTimedOut, this, _1));
|
||||
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()
|
||||
HelloProtocol::sendHelloInterest(const ndn::Name& neighbor)
|
||||
{
|
||||
for (const auto& adjacent : m_confParam.getAdjacencyList().getAdjList()) {
|
||||
// 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(m_confParam.getRouterPrefix().wireEncode());
|
||||
expressInterest(interestName, m_confParam.getInterestResendTime());
|
||||
NLSR_LOG_DEBUG("Sending scheduled interest: " << interestName);
|
||||
}
|
||||
auto adjacent = m_adjacencyList.findAdjacent(neighbor);
|
||||
if (adjacent == m_adjacencyList.end()) {
|
||||
return;
|
||||
}
|
||||
scheduleInterest(m_confParam.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),
|
||||
[this] {
|
||||
sendScheduledInterest();
|
||||
});
|
||||
m_scheduler.schedule(ndn::time::seconds(m_confParam.getInfoInterestInterval()),
|
||||
[this, neighbor] { sendHelloInterest(neighbor); });
|
||||
}
|
||||
|
||||
void
|
||||
@@ -107,22 +117,22 @@ 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_confParam.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_keyChain.sign(*data, m_signingInfo);
|
||||
|
||||
@@ -132,7 +142,7 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
// increment SENT_HELLO_DATA
|
||||
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
|
||||
|
||||
auto adjacent = m_confParam.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.
|
||||
@@ -141,7 +151,7 @@ HelloProtocol::processInterest(const ndn::Name& name,
|
||||
ndn::Name interestName(neighbor);
|
||||
interestName.append(NLSR_COMPONENT);
|
||||
interestName.append(INFO_COMPONENT);
|
||||
interestName.append(m_confParam.getRouterPrefix().wireEncode());
|
||||
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
|
||||
expressInterest(interestName, m_confParam.getInterestResendTime());
|
||||
}
|
||||
}
|
||||
@@ -159,12 +169,11 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
|
||||
}
|
||||
ndn::Name neighbor = interestName.getPrefix(-3);
|
||||
NLSR_LOG_DEBUG("Neighbor: " << neighbor);
|
||||
m_confParam.getAdjacencyList().incrementTimedOutInterestCount(neighbor);
|
||||
m_adjacencyList.incrementTimedOutInterestCount(neighbor);
|
||||
|
||||
Adjacent::Status status = m_confParam.getAdjacencyList().getStatusOfNeighbor(neighbor);
|
||||
Adjacent::Status status = m_adjacencyList.getStatusOfNeighbor(neighbor);
|
||||
|
||||
uint32_t infoIntTimedOutCount =
|
||||
m_confParam.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_confParam.getInterestRetryNumber()) {
|
||||
@@ -172,31 +181,34 @@ HelloProtocol::processInterestTimedOut(const ndn::Interest& interest)
|
||||
ndn::Name interestName(neighbor);
|
||||
interestName.append(NLSR_COMPONENT);
|
||||
interestName.append(INFO_COMPONENT);
|
||||
interestName.append(m_confParam.getRouterPrefix().wireEncode());
|
||||
interestName.append(ndn::tlv::GenericNameComponent, m_confParam.getRouterPrefix().wireEncode());
|
||||
NLSR_LOG_DEBUG("Resending interest: " << interestName);
|
||||
expressInterest(interestName, m_confParam.getInterestResendTime());
|
||||
}
|
||||
else if ((status == Adjacent::STATUS_ACTIVE) &&
|
||||
(infoIntTimedOutCount == m_confParam.getInterestRetryNumber())) {
|
||||
m_confParam.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_lsdb.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_confParam.getValidator().validate(data,
|
||||
std::bind(&HelloProtocol::onContentValidated, this, _1),
|
||||
@@ -214,13 +226,13 @@ HelloProtocol::onContentValidated(const ndn::Data& data)
|
||||
if (dataName.get(-3).toUri() == INFO_COMPONENT) {
|
||||
ndn::Name neighbor = dataName.getPrefix(-4);
|
||||
|
||||
Adjacent::Status oldStatus = m_confParam.getAdjacencyList().getStatusOfNeighbor(neighbor);
|
||||
m_confParam.getAdjacencyList().setStatusOfNeighbor(neighbor, Adjacent::STATUS_ACTIVE);
|
||||
m_confParam.getAdjacencyList().setTimedOutInterestCount(neighbor, 0);
|
||||
Adjacent::Status newStatus = m_confParam.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_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
@@ -229,6 +241,7 @@ HelloProtocol::onContentValidated(const ndn::Data& data)
|
||||
else {
|
||||
m_lsdb.scheduleAdjLsaBuild();
|
||||
}
|
||||
onInitialHelloDataValidated(neighbor);
|
||||
}
|
||||
}
|
||||
// increment RCV_HELLO_DATA
|
||||
@@ -237,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
|
||||
+22
-69
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,45 +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 "statistics.hpp"
|
||||
#include "test-access-control.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/security/validator-config.hpp>
|
||||
#include <ndn-cxx/util/signal.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class HelloProtocol
|
||||
{
|
||||
public:
|
||||
HelloProtocol(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
ndn::security::SigningInfo& signingInfo,
|
||||
ConfParameter& confParam, RoutingTable& routingTable, Lsdb& lsdb);
|
||||
|
||||
/*! \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.
|
||||
*
|
||||
@@ -75,14 +59,12 @@ public:
|
||||
*
|
||||
* 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 currently 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();
|
||||
sendHelloInterest(const ndn::Name& neighbor);
|
||||
|
||||
/*! \brief Processes a Hello Interest from a neighbor.
|
||||
*
|
||||
@@ -101,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
|
||||
@@ -138,52 +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:
|
||||
ndn::Face& m_face;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ndn::security::v2::KeyChain& m_keyChain;
|
||||
ndn::security::SigningInfo& m_signingInfo;
|
||||
ndn::security::KeyChain& m_keyChain;
|
||||
const ndn::security::SigningInfo& m_signingInfo;
|
||||
ConfParameter& m_confParam;
|
||||
RoutingTable& m_routingTable;
|
||||
Lsdb& m_lsdb;
|
||||
|
||||
static const std::string INFO_COMPONENT;
|
||||
static const std::string NLSR_COMPONENT;
|
||||
AdjacencyList& m_adjacencyList;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
@@ -1,149 +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.");
|
||||
NLSR_LOG_TRACE("LSA data segment's 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.");
|
||||
}
|
||||
|
||||
ndn::time::seconds expirationTime(LSA_REFRESH_TIME_DEFAULT);
|
||||
|
||||
// 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
|
||||
-374
@@ -1,374 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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::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
|
||||
-417
@@ -1,417 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2019, 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 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;
|
||||
|
||||
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
|
||||
+353
-1135
File diff suppressed because it is too large.
Load diff
+226
-296
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,198 +17,78 @@
|
||||
*
|
||||
* 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 "route/name-prefix-table.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 <ndn-cxx/util/segment-fetcher.hpp>
|
||||
|
||||
#include <PSync/segment-publisher.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 {
|
||||
|
||||
namespace bmi = boost::multi_index;
|
||||
|
||||
inline constexpr ndn::time::seconds GRACE_PERIOD = 10_s;
|
||||
|
||||
enum class LsdbUpdate {
|
||||
INSTALLED,
|
||||
UPDATED,
|
||||
REMOVED
|
||||
};
|
||||
|
||||
class Lsdb
|
||||
{
|
||||
public:
|
||||
Lsdb(ndn::Face& face, ndn::KeyChain& keyChain,
|
||||
ndn::security::SigningInfo& signingInfo, ConfParameter& confParam,
|
||||
NamePrefixTable& namePrefixTable, RoutingTable& routingTable);
|
||||
Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam);
|
||||
|
||||
~Lsdb();
|
||||
|
||||
SyncLogicHandler&
|
||||
getSyncLogicHandler()
|
||||
/*! \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);
|
||||
|
||||
/*! \brief Installs a name LSA into the LSDB
|
||||
\param nlsa The name LSA to install into the LSDB.
|
||||
*/
|
||||
bool
|
||||
installNameLsa(NameLsa& nlsa);
|
||||
|
||||
/*! \brief Remove a name LSA from the LSDB.
|
||||
\param key The name of the router that published the LSA to remove.
|
||||
|
||||
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
|
||||
writeNameLsdbLog();
|
||||
|
||||
const std::list<NameLsa>&
|
||||
getNameLsdb() const;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Builds a cor. LSA for this router and installs it into the LSDB. */
|
||||
bool
|
||||
void
|
||||
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
|
||||
|
||||
public:
|
||||
/*! \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;
|
||||
}
|
||||
|
||||
void
|
||||
writeAdjLsdbLog();
|
||||
|
||||
void
|
||||
expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
|
||||
ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);
|
||||
writeLog() const;
|
||||
|
||||
/* \brief Process interest which can be either:
|
||||
* 1) Discovery interest from segment fetcher:
|
||||
@@ -220,35 +100,149 @@ public:
|
||||
processInterest(const ndn::Name& name, const ndn::Interest& interest);
|
||||
|
||||
bool
|
||||
getIsBuildAdjLsaSheduled()
|
||||
getIsBuildAdjLsaScheduled() const
|
||||
{
|
||||
return m_isBuildAdjLsaSheduled;
|
||||
return m_isBuildAdjLsaScheduled;
|
||||
}
|
||||
|
||||
private:
|
||||
/* \brief Add a name LSA to the LSDB if it isn't already there.
|
||||
\param nlsa The candidade name LSA.
|
||||
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
|
||||
addNameLsa(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;
|
||||
}
|
||||
|
||||
/*! \brief Returns whether the LSDB contains some LSA.
|
||||
\param key The name of the publishing router whose LSA to check for.
|
||||
void
|
||||
installLsa(std::shared_ptr<Lsa> lsa);
|
||||
|
||||
/*! \brief Remove a name LSA from the LSDB.
|
||||
\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
|
||||
doesNameLsaExist(const ndn::Name& key);
|
||||
void
|
||||
removeLsa(const ndn::Name& router, Lsa::Type lsaType);
|
||||
|
||||
/*! \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);
|
||||
void
|
||||
removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt);
|
||||
|
||||
/*! \brief Attempts to construct an adj. LSA.
|
||||
|
||||
@@ -260,89 +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
|
||||
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
|
||||
|
||||
@@ -358,13 +294,10 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
is reached.
|
||||
*/
|
||||
void
|
||||
onFetchLsaError(uint32_t errorCode,
|
||||
const std::string& msg,
|
||||
const 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
|
||||
@@ -373,63 +306,60 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/<network>/NLSR/LSA/<site>/%C1.Router/<router>/<lsa-type>/<seqNo>
|
||||
*/
|
||||
void
|
||||
afterFetchLsa(const ndn::ConstBufferPtr& data, const 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::util::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
|
||||
ndn::util::signal::Signal<Lsdb, const ndn::Data&> afterSegmentValidatedSignal;
|
||||
|
||||
private:
|
||||
ndn::Face& m_face;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ndn::security::SigningInfo& m_signingInfo;
|
||||
|
||||
ConfParameter& m_confParam;
|
||||
NamePrefixTable& m_namePrefixTable;
|
||||
RoutingTable& m_routingTable;
|
||||
SyncLogicHandler m_sync;
|
||||
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;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
LsaSegmentStorage m_lsaStorage;
|
||||
ndn::Face& m_face;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ConfParameter& m_confParam;
|
||||
|
||||
private:
|
||||
std::list<NameLsa> m_nameLsdb;
|
||||
std::list<AdjLsa> m_adjLsdb;
|
||||
std::list<CoordinateLsa> m_corLsdb;
|
||||
SyncLogicHandler m_sync;
|
||||
|
||||
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::util::SegmentFetcher>> m_fetchers;
|
||||
psync::SegmentPublisher m_segmentPublisher;
|
||||
std::set<std::shared_ptr<ndn::SegmentFetcher>> m_fetchers;
|
||||
ndn::Segmenter m_segmenter;
|
||||
ndn::InMemoryStorageFifo m_segmentFifo;
|
||||
|
||||
bool m_isBuildAdjLsaSheduled;
|
||||
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
|
||||
|
||||
+20
-34
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2019, The University of Memphis,
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -20,32 +20,12 @@
|
||||
**/
|
||||
|
||||
#include "conf-file-processor.hpp"
|
||||
#include "nlsr-runner.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "security/certificate-store.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
#include <sstream>
|
||||
|
||||
template<typename E>
|
||||
static std::string
|
||||
getExtendedErrorMessage(const E& exception)
|
||||
{
|
||||
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();
|
||||
}
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <iostream>
|
||||
|
||||
static void
|
||||
printUsage(std::ostream& os, const std::string& programName)
|
||||
@@ -83,27 +63,33 @@ main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
boost::asio::io_service ioService;
|
||||
ndn::Face face(ioService);
|
||||
ndn::KeyChain keyChain;
|
||||
ndn::Face face(nullptr, keyChain);
|
||||
|
||||
nlsr::ConfParameter confParam(face, configFileName);
|
||||
nlsr::ConfParameter confParam(face, keyChain, configFileName);
|
||||
nlsr::ConfFileProcessor configProcessor(confParam);
|
||||
|
||||
if (!configProcessor.processConfFile()) {
|
||||
std::cerr << "Error in configuration file processing" << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
confParam.buildRouterPrefix();
|
||||
confParam.writeLog();
|
||||
// Since confParam is already populated, key is initialized here before
|
||||
// and independent of the NLSR class
|
||||
auto certificate = confParam.initializeKey();
|
||||
|
||||
nlsr::NlsrRunner runner(face, confParam);
|
||||
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 << "FATAL: " << getExtendedErrorMessage(e) << std::endl;
|
||||
nlsr.getFib().clean();
|
||||
std::cerr << "FATAL: " << boost::diagnostic_information(e) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+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,70 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2019, 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 "conf-parameter.hpp"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/scheduler.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:
|
||||
explicit
|
||||
NlsrRunner(ndn::Face& face, ConfParameter& confParam);
|
||||
|
||||
/*! \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 ConfFileError The configuration file cannot be processed.
|
||||
* NLSR is not started.
|
||||
* \sa Nlsr::canonizeNeighborUris
|
||||
*/
|
||||
void
|
||||
run();
|
||||
|
||||
private:
|
||||
ndn::Face& m_face;
|
||||
ndn::KeyChain m_keyChain;
|
||||
ConfParameter& m_confParam;
|
||||
Nlsr m_nlsr;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_NLSR_RUNNER_HPP
|
||||
+137
-375
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2023, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -17,377 +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(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam)
|
||||
: m_face(face)
|
||||
, m_scheduler(face.getIoService())
|
||||
, m_keyChain(keyChain)
|
||||
, m_scheduler(face.getIoContext())
|
||||
, m_confParam(confParam)
|
||||
, m_adjacencyList(confParam.getAdjacencyList())
|
||||
, m_namePrefixList(confParam.getNamePrefixList())
|
||||
, m_validator(m_confParam.getValidator())
|
||||
, m_fib(m_face, m_scheduler, m_adjacencyList, m_confParam, m_keyChain)
|
||||
, m_routingTable(m_scheduler, m_fib, m_lsdb, m_namePrefixTable, m_confParam)
|
||||
, m_namePrefixTable(m_fib, m_routingTable, m_routingTable.afterRoutingChange)
|
||||
, m_lsdb(m_face, m_keyChain, m_signingInfo,
|
||||
m_confParam, m_namePrefixTable, m_routingTable)
|
||||
, m_afterSegmentValidatedConnection(m_lsdb.afterSegmentValidatedSignal.connect(
|
||||
std::bind(&Nlsr::afterFetcherSignalEmitted, this, _1)))
|
||||
, m_dispatcher(m_face, m_keyChain)
|
||||
, 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_helloProtocol(m_face, m_keyChain, m_signingInfo, confParam, m_routingTable, m_lsdb)
|
||||
, m_certStore(m_confParam.getCertStore())
|
||||
, m_controller(m_face, m_keyChain)
|
||||
, m_faceDatasetController(m_face, m_keyChain)
|
||||
, m_controller(m_face, keyChain)
|
||||
, m_faceDatasetController(m_face, keyChain)
|
||||
, m_prefixUpdateProcessor(m_dispatcher,
|
||||
m_confParam.getPrefixUpdateValidator(),
|
||||
m_namePrefixList,
|
||||
m_lsdb,
|
||||
m_confParam.getConfFileNameDynamic())
|
||||
m_confParam.getPrefixUpdateValidator(),
|
||||
m_namePrefixList,
|
||||
m_lsdb,
|
||||
m_confParam.getConfFileNameDynamic())
|
||||
, m_nfdRibCommandProcessor(m_dispatcher,
|
||||
m_namePrefixList,
|
||||
m_lsdb)
|
||||
m_namePrefixList,
|
||||
m_lsdb)
|
||||
, m_statsCollector(m_lsdb, m_helloProtocol)
|
||||
, m_faceMonitor(m_face)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Initializing Nlsr");
|
||||
|
||||
m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification, this, _1));
|
||||
m_faceMonitor.start();
|
||||
|
||||
setStrategies();
|
||||
m_fib.setStrategy(m_confParam.getLsaPrefix(), Fib::MULTICAST_STRATEGY, 0);
|
||||
m_fib.setStrategy(m_confParam.getSyncPrefix(), Fib::MULTICAST_STRATEGY, 0);
|
||||
|
||||
NLSR_LOG_DEBUG("Default NLSR identity: " << m_confParam.getSigningInfo().getSignerName());
|
||||
|
||||
// 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));
|
||||
|
||||
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) {
|
||||
for (auto&& neighbor : m_adjacencyList.getAdjList()) {
|
||||
neighbor.setLinkCost(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registrationFailed(const ndn::Name& name)
|
||||
Nlsr::registerStrategyForCerts(const ndn::Name& originRouter)
|
||||
{
|
||||
NLSR_LOG_ERROR("ERROR: Failed to register prefix in local hub's daemon");
|
||||
BOOST_THROW_EXCEPTION(Error("Error: Prefix registration failed"));
|
||||
}
|
||||
for (const ndn::Name& router : m_strategySetOnRouters) {
|
||||
if (router == originRouter) {
|
||||
// Have already set strategy for this router's certs once
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::onRegistrationSuccess(const ndn::Name& name)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
|
||||
}
|
||||
m_strategySetOnRouters.push_back(originRouter);
|
||||
|
||||
void
|
||||
Nlsr::setInfoInterestFilter()
|
||||
{
|
||||
ndn::Name name(m_confParam.getRouterPrefix());
|
||||
name.append("nlsr");
|
||||
name.append("INFO");
|
||||
ndn::Name routerKey(originRouter);
|
||||
routerKey.append(ndn::security::Certificate::KEY_COMPONENT);
|
||||
ndn::Name instanceKey(originRouter);
|
||||
instanceKey.append("nlsr").append(ndn::security::Certificate::KEY_COMPONENT);
|
||||
|
||||
NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
|
||||
m_fib.setStrategy(routerKey, Fib::BEST_ROUTE_STRATEGY, 0);
|
||||
m_fib.setStrategy(instanceKey, Fib::BEST_ROUTE_STRATEGY, 0);
|
||||
|
||||
m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(false),
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
void
|
||||
Nlsr::setLsaInterestFilter()
|
||||
{
|
||||
ndn::Name name = m_confParam.getLsaPrefix();
|
||||
|
||||
NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);
|
||||
|
||||
m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(false),
|
||||
std::bind(&Lsdb::processInterest, &m_lsdb, _1, _2),
|
||||
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1),
|
||||
m_signingInfo, ndn::nfd::ROUTE_FLAG_CAPTURE);
|
||||
opPrefix.append(std::string("%C1.Operator"));
|
||||
m_fib.setStrategy(opPrefix, Fib::BEST_ROUTE_STRATEGY, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
|
||||
{
|
||||
registerPrefix(topPrefix);
|
||||
try {
|
||||
// false since we want to have control over the registration process
|
||||
m_dispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
|
||||
m_dispatcher.addTopPrefix(topPrefix, false, m_confParam.getSigningInfo());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
|
||||
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::setStrategies()
|
||||
Nlsr::registerPrefix(const ndn::Name& prefix)
|
||||
{
|
||||
const std::string strategy("ndn:/localhost/nfd/strategy/multicast");
|
||||
|
||||
m_fib.setStrategy(m_confParam.getLsaPrefix(), strategy, 0);
|
||||
m_fib.setStrategy(m_confParam.getSyncPrefix(), strategy, 0);
|
||||
}
|
||||
|
||||
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::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);
|
||||
ndn::Name certName = ndn::security::v2::extractKeyNameFromCertName(cert->getName());
|
||||
NLSR_LOG_TRACE("Setting interest filter for: " << certName);
|
||||
m_face.setInterestFilter(ndn::InterestFilter(certName).allowLoopback(false),
|
||||
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()
|
||||
{
|
||||
NLSR_LOG_DEBUG("Initializing Nlsr");
|
||||
|
||||
// Logging start
|
||||
m_adjacencyList.writeLog();
|
||||
NLSR_LOG_DEBUG(m_namePrefixList);
|
||||
|
||||
initializeKey();
|
||||
|
||||
NLSR_LOG_DEBUG("Default NLSR identity: " << m_signingInfo.getSignerName());
|
||||
|
||||
// Can be moved to HelloProtocol and Lsdb ctor if initializeKey is set
|
||||
// earlier in the Nlsr constructor so as to set m_signingInfo
|
||||
setInfoInterestFilter();
|
||||
setLsaInterestFilter();
|
||||
|
||||
// add top-level prefixes: router and localhost prefix
|
||||
addDispatcherTopPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"));
|
||||
addDispatcherTopPrefix(LOCALHOST_PREFIX);
|
||||
|
||||
initializeFaces(std::bind(&Nlsr::processFaceDataset, this, _1),
|
||||
std::bind(&Nlsr::onFaceDatasetFetchTimeout, this, _1, _2, 0));
|
||||
|
||||
enableIncomingFaceIdIndication();
|
||||
|
||||
m_lsdb.buildAndInstallOwnNameLsa();
|
||||
|
||||
// Install coordinate LSAs if using HR or dry-run HR.
|
||||
if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
|
||||
m_lsdb.buildAndInstallOwnCoordinateLsa();
|
||||
}
|
||||
|
||||
registerKeyPrefix();
|
||||
registerLocalhostPrefix();
|
||||
registerRouterPrefix();
|
||||
|
||||
m_helloProtocol.scheduleInterest(m_confParam.getFirstHelloInterval());
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::initializeKey()
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
|
||||
auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
|
||||
|
||||
ndn::security::v2::Certificate certificate;
|
||||
|
||||
ndn::Name certificateName = nlsrInstanceKey.getName();
|
||||
certificateName.append("NA");
|
||||
certificateName.appendVersion();
|
||||
certificate.setName(certificateName);
|
||||
|
||||
// set metainfo
|
||||
certificate.setContentType(ndn::tlv::ContentType_Key);
|
||||
certificate.setFreshnessPeriod(ndn::time::days(365));
|
||||
|
||||
// set content
|
||||
certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
|
||||
|
||||
// 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)));
|
||||
try {
|
||||
m_keyChain.sign(certificate,
|
||||
ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.getRouterPrefix()))
|
||||
.setSignatureInfo(signatureInfo));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
|
||||
nlsrInstanceName);
|
||||
|
||||
loadCertToPublish(certificate);
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registerKeyPrefix()
|
||||
{
|
||||
// Start listening for the interest of this router's NLSR certificate
|
||||
ndn::Name nlsrKeyPrefix = m_confParam.getRouterPrefix();
|
||||
nlsrKeyPrefix.append("nlsr");
|
||||
nlsrKeyPrefix.append("KEY");
|
||||
|
||||
m_face.setInterestFilter(ndn::InterestFilter(nlsrKeyPrefix).allowLoopback(false),
|
||||
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 = m_confParam.getRouterPrefix();
|
||||
routerKeyPrefix.append("KEY");
|
||||
|
||||
m_face.setInterestFilter(ndn::InterestFilter(routerKeyPrefix).allowLoopback(false),
|
||||
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 = m_confParam.getNetwork();
|
||||
operatorKeyPrefix.append(m_confParam.getSiteName());
|
||||
operatorKeyPrefix.append(std::string("%C1.Operator"));
|
||||
|
||||
m_face.setInterestFilter(ndn::InterestFilter(operatorKeyPrefix).allowLoopback(false),
|
||||
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 = m_confParam.getNetwork();
|
||||
siteKeyPrefix.append(m_confParam.getSiteName());
|
||||
siteKeyPrefix.append("KEY");
|
||||
|
||||
m_face.setInterestFilter(ndn::InterestFilter(siteKeyPrefix).allowLoopback(false),
|
||||
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_face.registerPrefix(LOCALHOST_PREFIX,
|
||||
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
|
||||
std::bind(&Nlsr::registrationFailed, this, _1));
|
||||
}
|
||||
|
||||
void
|
||||
Nlsr::registerRouterPrefix()
|
||||
{
|
||||
m_face.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_face.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: {
|
||||
@@ -422,10 +207,12 @@ 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) {
|
||||
if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
|
||||
m_routingTable.scheduleRoutingTableCalculation();
|
||||
}
|
||||
else {
|
||||
// Will call scheduleRoutingTableCalculation internally
|
||||
// if needed in case of LS or DRY_RUN
|
||||
m_lsdb.scheduleAdjLsaBuild();
|
||||
}
|
||||
}
|
||||
@@ -443,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) {
|
||||
m_routingTable.scheduleRoutingTableCalculation();
|
||||
}
|
||||
else {
|
||||
m_lsdb.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;
|
||||
}
|
||||
@@ -472,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
|
||||
@@ -484,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()) {
|
||||
@@ -513,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();
|
||||
@@ -523,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.getSyncPrefix(),
|
||||
faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
|
||||
m_fib.registerPrefix(m_confParam.getLsaPrefix(),
|
||||
faceUri, linkCost, timeout,
|
||||
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
|
||||
@@ -537,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 " <<
|
||||
@@ -559,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); });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -581,25 +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());
|
||||
[] (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
|
||||
+32
-135
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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(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,15 +88,7 @@ public:
|
||||
void
|
||||
addDispatcherTopPrefix(const ndn::Name& topPrefix);
|
||||
|
||||
Fib&
|
||||
getFib()
|
||||
{
|
||||
return m_fib;
|
||||
}
|
||||
|
||||
void
|
||||
initialize();
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Initializes neighbors' Faces using information from NFD.
|
||||
* \sa Nlsr::initialize()
|
||||
* \sa Nlsr::processFaceDataset()
|
||||
@@ -143,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
|
||||
@@ -153,84 +132,12 @@ 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);
|
||||
|
||||
/*! \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();
|
||||
|
||||
/*! \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;
|
||||
}
|
||||
|
||||
void
|
||||
setStrategies();
|
||||
|
||||
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.
|
||||
*/
|
||||
@@ -250,50 +157,42 @@ 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_face;
|
||||
ndn::Scheduler m_scheduler;
|
||||
ndn::security::v2::KeyChain& m_keyChain;
|
||||
ConfParameter& m_confParam;
|
||||
AdjacencyList& m_adjacencyList;
|
||||
NamePrefixList& m_namePrefixList;
|
||||
bool m_isDaemonProcess;
|
||||
ndn::security::ValidatorConfig& m_validator;
|
||||
std::vector<ndn::Name> m_strategySetOnRouters;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
Fib m_fib;
|
||||
Lsdb m_lsdb;
|
||||
RoutingTable m_routingTable;
|
||||
NamePrefixTable m_namePrefixTable;
|
||||
Lsdb m_lsdb;
|
||||
HelloProtocol m_helloProtocol;
|
||||
|
||||
private:
|
||||
ndn::util::signal::ScopedConnection m_afterSegmentValidatedConnection;
|
||||
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;
|
||||
HelloProtocol m_helloProtocol;
|
||||
|
||||
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;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
ndn::security::SigningInfo m_signingInfo;
|
||||
update::PrefixUpdateProcessor m_prefixUpdateProcessor;
|
||||
update::NfdRibCommandProcessor m_nfdRibCommandProcessor;
|
||||
|
||||
@@ -301,8 +200,6 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
|
||||
private:
|
||||
ndn::nfd::FaceMonitor m_faceMonitor;
|
||||
|
||||
friend class NlsrRunner;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,236 +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(ndn::mgmt::Dispatcher& dispatcher,
|
||||
const Lsdb& lsdb,
|
||||
const RoutingTable& rt)
|
||||
: m_dispatcher(dispatcher)
|
||||
, m_lsdb(lsdb)
|
||||
, m_routingTableEntries(rt.getRoutingTableEntry())
|
||||
, m_dryRoutingTableEntries(rt.getDryRoutingTableEntry())
|
||||
{
|
||||
setDispatcher(m_dispatcher);
|
||||
}
|
||||
|
||||
void
|
||||
DatasetInterestHandler::setDispatcher(ndn::mgmt::Dispatcher& dispatcher)
|
||||
: m_lsdb(lsdb)
|
||||
, 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-2019, 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,11 +59,7 @@ public:
|
||||
class Error : std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
DatasetInterestHandler(ndn::mgmt::Dispatcher& dispatcher,
|
||||
@@ -77,60 +67,24 @@ public:
|
||||
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:
|
||||
ndn::mgmt::Dispatcher& m_dispatcher;
|
||||
const Lsdb& m_lsdb;
|
||||
|
||||
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,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,36 +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/>.
|
||||
**/
|
||||
|
||||
#include "fib-entry.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(route.FibEntry);
|
||||
|
||||
void
|
||||
FibEntry::writeLog() const
|
||||
{
|
||||
NLSR_LOG_DEBUG("Name Prefix: " << m_name);
|
||||
NLSR_LOG_DEBUG("Seq No: " << m_seqNo);
|
||||
m_nexthopList.writeLog();
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,115 +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/>.
|
||||
**/
|
||||
|
||||
#ifndef NLSR_FIB_ENTRY_HPP
|
||||
#define NLSR_FIB_ENTRY_HPP
|
||||
|
||||
#include "nexthop-list.hpp"
|
||||
|
||||
#include <ndn-cxx/util/scheduler.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() const;
|
||||
|
||||
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
|
||||
+95
-141
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,19 +24,16 @@
|
||||
#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::v2::KeyChain& keyChain)
|
||||
ConfParameter& conf, ndn::security::KeyChain& keyChain)
|
||||
: m_scheduler(scheduler)
|
||||
, m_refreshTime(2 * conf.getLsaRefreshTime())
|
||||
, m_controller(face, keyChain)
|
||||
@@ -49,29 +46,29 @@ void
|
||||
Fib::remove(const ndn::Name& name)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Fib::remove called");
|
||||
std::map<ndn::Name, FibEntry>::iterator it = m_table.find(name);
|
||||
auto it = m_table.find(name);
|
||||
|
||||
// Only unregister the prefix if it ISN'T a neighbor.
|
||||
if (it != m_table.end() && isNotNeighbor((it->second).getName())) {
|
||||
for (const auto& nexthop : (it->second).getNexthopList().getNextHops()) {
|
||||
unregisterPrefix((it->second).getName(), nexthop.getConnectingFaceUri());
|
||||
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, const NexthopList& hopsToAdd)
|
||||
Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd)
|
||||
{
|
||||
const ndn::Name& name = entry.getName();
|
||||
const ndn::Name& name = entry.name;
|
||||
|
||||
bool shouldRegister = isNotNeighbor(name);
|
||||
|
||||
for (const auto& hop : hopsToAdd.getNextHops())
|
||||
for (const auto& hop : hopsToAdd)
|
||||
{
|
||||
// Add nexthop to FIB entry
|
||||
entry.getNexthopList().addNextHop(hop);
|
||||
NLSR_LOG_DEBUG("Adding " << hop.getConnectingFaceUri() << " to " << entry.name);
|
||||
entry.nexthopSet.addNextHop(hop);
|
||||
|
||||
if (shouldRegister) {
|
||||
// Add nexthop to NDN-FIB
|
||||
@@ -92,28 +89,25 @@ Fib::update(const ndn::Name& name, const NexthopList& allHops)
|
||||
// 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.cbegin(); it != allHops.cend() && 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 {
|
||||
@@ -126,51 +120,44 @@ Fib::update(const ndn::Name& name, const 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 = isNotNeighbor(entry.getName());
|
||||
bool isUpdatable = isNotNeighbor(entry.name);
|
||||
// Remove the uninstalled next hops from NFD and FIB entry
|
||||
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() &&
|
||||
isNotNeighbor(entryIt->second.getName())) {
|
||||
scheduleEntryRefresh(entryIt->second,
|
||||
[this] (FibEntry& entry) {
|
||||
scheduleLoop(entry);
|
||||
});
|
||||
!entryIt->second.refreshEventId &&
|
||||
isNotNeighbor(entryIt->second.name)) {
|
||||
scheduleEntryRefresh(entryIt->second, [this] (FibEntry& entry) { scheduleLoop(entry); });
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Fib::clean()
|
||||
{
|
||||
NLSR_LOG_DEBUG("Fib::clean called");
|
||||
// can't use const ref here as getNexthopList can't be marked const
|
||||
for (auto&& it : m_table) {
|
||||
NLSR_LOG_DEBUG("Canceling Scheduled event. Name: " << it.second.getName());
|
||||
cancelEntryRefresh(it.second);
|
||||
|
||||
for (const auto& hop : it.second.getNexthopList().getNextHops()) {
|
||||
unregisterPrefix(it.second.getName(), hop.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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,13 +168,8 @@ 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
|
||||
@@ -198,13 +180,12 @@ Fib::isNotNeighbor(const ndn::Name& 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)
|
||||
@@ -216,13 +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,29 +279,24 @@ 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() <<
|
||||
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() <<
|
||||
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);
|
||||
@@ -341,15 +304,15 @@ Fib::onSetStrategyFailure(const ndn::nfd::ControlResponse& response,
|
||||
}
|
||||
|
||||
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() <<
|
||||
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
|
||||
@@ -359,31 +322,20 @@ Fib::scheduleLoop(FibEntry& entry)
|
||||
}
|
||||
|
||||
void
|
||||
Fib::cancelEntryRefresh(const FibEntry& entry)
|
||||
Fib::refreshEntry(const ndn::Name& name, AfterRefreshCallback refreshCb)
|
||||
{
|
||||
NLSR_LOG_DEBUG("Canceling 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,7 +350,9 @@ Fib::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG("-------------------FIB-----------------------------");
|
||||
for (const auto& entry : m_table) {
|
||||
entry.second.writeLog();
|
||||
NLSR_LOG_DEBUG("Name prefix: " << entry.first);
|
||||
NLSR_LOG_DEBUG("Seq No: " << entry.second.seqNo);
|
||||
NLSR_LOG_DEBUG("Nexthop List: \n" << entry.second.nexthopSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-47
@@ -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.
|
||||
*
|
||||
@@ -54,7 +63,7 @@ class Fib
|
||||
{
|
||||
public:
|
||||
Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList,
|
||||
ConfParameter& conf, ndn::security::v2::KeyChain& keyChain);
|
||||
ConfParameter& conf, ndn::security::KeyChain& keyChain);
|
||||
|
||||
/*! \brief Completely remove a name prefix from the FIB.
|
||||
*
|
||||
@@ -88,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();
|
||||
@@ -130,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();
|
||||
@@ -150,7 +156,7 @@ private:
|
||||
* \sa Fib::removeOldNextHopsFromFibEntryAndNfd
|
||||
*/
|
||||
void
|
||||
addNextHopsToFibEntryAndNfd(FibEntry& entry, const NexthopList& hopsToAdd);
|
||||
addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd);
|
||||
|
||||
unsigned int
|
||||
getNumberOfFacesForName(const NexthopList& nextHopList);
|
||||
@@ -159,48 +165,33 @@ private:
|
||||
*
|
||||
*/
|
||||
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.
|
||||
@@ -214,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.
|
||||
@@ -222,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;
|
||||
@@ -245,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:
|
||||
@@ -256,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
-19
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,10 +49,10 @@ 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>>
|
||||
>
|
||||
>;
|
||||
|
||||
@@ -81,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());
|
||||
}
|
||||
}
|
||||
@@ -98,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-2018, 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +111,6 @@ private:
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
std::list<std::shared_ptr<RoutingTablePoolEntry>> m_rteList;
|
||||
NexthopList m_nexthopList;
|
||||
|
||||
};
|
||||
|
||||
bool
|
||||
|
||||
+102
-49
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,36 +33,94 @@ namespace nlsr {
|
||||
|
||||
INIT_LOGGER(route.NamePrefixTable);
|
||||
|
||||
NamePrefixTable::NamePrefixTable(Fib& fib, RoutingTable& routingTable,
|
||||
std::unique_ptr<AfterRoutingChange>& afterRoutingChangeSignal)
|
||||
: m_fib(fib)
|
||||
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;
|
||||
@@ -94,11 +152,12 @@ 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->getNamePrefix());
|
||||
@@ -131,9 +190,10 @@ NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
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_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_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-2019, 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
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "signals.hpp"
|
||||
#include "test-access-control.hpp"
|
||||
#include "route/fib.hpp"
|
||||
#include "lsdb.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
@@ -41,11 +42,23 @@ public:
|
||||
using NptEntryList = std::list<std::shared_ptr<NamePrefixTableEntry>>;
|
||||
using const_iterator = NptEntryList::const_iterator;
|
||||
|
||||
NamePrefixTable(Fib& fib, RoutingTable& routingTable,
|
||||
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
|
||||
@@ -125,9 +138,11 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
NptEntryList m_table;
|
||||
|
||||
private:
|
||||
const ndn::Name& m_ownRouterName;
|
||||
Fib& m_fib;
|
||||
RoutingTable& m_routingTable;
|
||||
ndn::util::signal::Connection m_afterRoutingChangeConnection;
|
||||
ndn::signal::Connection m_afterRoutingChangeConnection;
|
||||
ndn::signal::Connection m_afterLsdbModified;
|
||||
};
|
||||
|
||||
inline NamePrefixTable::const_iterator
|
||||
|
||||
@@ -1,120 +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() const
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
for (const auto& nexthop : m_nexthopList) {
|
||||
NLSR_LOG_DEBUG("Nexthop " << i++ << ": " << nexthop.getConnectingFaceUri() <<
|
||||
" Route Cost: " << nexthop.getRouteCost());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+75
-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-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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_NEXTHOP_LIST_HPP
|
||||
#define NLSR_NEXTHOP_LIST_HPP
|
||||
@@ -24,48 +24,50 @@
|
||||
#include "nexthop.hpp"
|
||||
#include "adjacent.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/ostream-joiner.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
struct NextHopComparator {
|
||||
struct NextHopUriSortedComparator
|
||||
{
|
||||
bool
|
||||
operator() (const NextHop& nh1, const NextHop& nh2) const {
|
||||
if (nh1.getRouteCostAsAdjustedInteger() < nh2.getRouteCostAsAdjustedInteger()) {
|
||||
return true;
|
||||
}
|
||||
else if (nh1.getRouteCostAsAdjustedInteger() == nh2.getRouteCostAsAdjustedInteger()) {
|
||||
return nh1.getConnectingFaceUri() < nh2.getConnectingFaceUri();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
operator()(const NextHop& lhs, const NextHop& rhs) const
|
||||
{
|
||||
return lhs.getConnectingFaceUri() < rhs.getConnectingFaceUri();
|
||||
}
|
||||
};
|
||||
|
||||
class NexthopList
|
||||
template<typename T = std::less<NextHop>>
|
||||
class NexthopListT
|
||||
{
|
||||
public:
|
||||
NexthopList()
|
||||
{
|
||||
}
|
||||
|
||||
~NexthopList()
|
||||
{
|
||||
}
|
||||
NexthopListT() = default;
|
||||
|
||||
/*! \brief Adds a next hop to the list.
|
||||
\param nh The next hop.
|
||||
|
||||
Adds a next hop to this object. If the next hop is new it is
|
||||
added. If the next hop already exists in the list then that next
|
||||
hop's route cost is updated.
|
||||
added. If the next hop already exists but has a higher cost then
|
||||
its route cost is updated.
|
||||
*/
|
||||
void
|
||||
addNextHop(const NextHop& nh);
|
||||
addNextHop(const NextHop& nh)
|
||||
{
|
||||
auto it = std::find_if(m_nexthopList.begin(), m_nexthopList.end(),
|
||||
[&nh] (const auto& item) {
|
||||
return item.getConnectingFaceUri() == nh.getConnectingFaceUri();
|
||||
});
|
||||
if (it == m_nexthopList.end()) {
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
else if (it->getRouteCost() > nh.getRouteCost()) {
|
||||
m_nexthopList.erase(it);
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Remove a next hop from the Next Hop list
|
||||
\param nh The NextHop we want to remove.
|
||||
@@ -73,7 +75,13 @@ public:
|
||||
The next hop gets removed only if both next hop face and route cost are same.
|
||||
*/
|
||||
void
|
||||
removeNextHop(const NextHop& nh);
|
||||
removeNextHop(const NextHop& nh)
|
||||
{
|
||||
auto it = std::find(m_nexthopList.begin(), m_nexthopList.end(), nh);
|
||||
if (it != m_nexthopList.end()) {
|
||||
m_nexthopList.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
size() const
|
||||
@@ -82,28 +90,30 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
reset()
|
||||
clear()
|
||||
{
|
||||
m_nexthopList.clear();
|
||||
}
|
||||
|
||||
const std::set<NextHop, NextHopComparator>&
|
||||
const std::set<NextHop, T>&
|
||||
getNextHops() const
|
||||
{
|
||||
return m_nexthopList;
|
||||
}
|
||||
|
||||
typedef std::set<NextHop, NextHopComparator>::iterator iterator;
|
||||
typedef std::set<NextHop, NextHopComparator>::const_iterator const_iterator;
|
||||
typedef T value_type;
|
||||
typedef typename std::set<NextHop, T>::iterator iterator;
|
||||
typedef typename std::set<NextHop, T>::const_iterator const_iterator;
|
||||
typedef typename std::set<NextHop, T>::reverse_iterator reverse_iterator;
|
||||
|
||||
iterator
|
||||
begin()
|
||||
begin() const
|
||||
{
|
||||
return m_nexthopList.begin();
|
||||
}
|
||||
|
||||
iterator
|
||||
end()
|
||||
end() const
|
||||
{
|
||||
return m_nexthopList.end();
|
||||
}
|
||||
@@ -120,24 +130,46 @@ public:
|
||||
return m_nexthopList.end();
|
||||
}
|
||||
|
||||
void
|
||||
writeLog() const;
|
||||
reverse_iterator
|
||||
rbegin() const
|
||||
{
|
||||
return m_nexthopList.rbegin();
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rend() const
|
||||
{
|
||||
return m_nexthopList.rend();
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<NextHop, NextHopComparator> m_nexthopList;
|
||||
std::set<NextHop, T> m_nexthopList;
|
||||
};
|
||||
|
||||
bool
|
||||
operator==(NexthopList& lhs, NexthopList& rhs);
|
||||
typedef NexthopListT<> NexthopList;
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
operator==(const NexthopList& lhs, const NexthopList& rhs);
|
||||
operator==(const NexthopListT<T>& lhs, const NexthopListT<T>& rhs)
|
||||
{
|
||||
return lhs.getNextHops() == rhs.getNextHops();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
operator!=(const NexthopList& lhs, const NexthopList& rhs);
|
||||
operator!=(const NexthopListT<T>& lhs, const NexthopListT<T>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NexthopList& nhl);
|
||||
operator<<(std::ostream& os, const NexthopListT<T>& nhl)
|
||||
{
|
||||
os << " ";
|
||||
std::copy(nhl.cbegin(), nhl.cend(), ndn::make_ostream_joiner(os, "\n "));
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
|
||||
+77
-14
@@ -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
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,29 +16,92 @@
|
||||
*
|
||||
* 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.hpp"
|
||||
#include "tlv-nlsr.hpp"
|
||||
|
||||
#include <ndn-cxx/encoding/block-helpers.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
bool
|
||||
operator==(const NextHop& lhs, const NextHop& rhs)
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
NextHop::wireEncode(ndn::EncodingImpl<TAG>& block) const
|
||||
{
|
||||
return ((lhs.getRouteCostAsAdjustedInteger() == rhs.getRouteCostAsAdjustedInteger())
|
||||
&&
|
||||
(lhs.getConnectingFaceUri() == rhs.getConnectingFaceUri()));
|
||||
size_t totalLength = 0;
|
||||
|
||||
totalLength += ndn::encoding::prependDoubleBlock(block, nlsr::tlv::CostDouble, m_routeCost);
|
||||
totalLength += ndn::encoding::prependStringBlock(block, nlsr::tlv::Uri, m_connectingFaceUri.toString());
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(nlsr::tlv::NextHop);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(NextHop);
|
||||
|
||||
const ndn::Block&
|
||||
NextHop::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
|
||||
NextHop::wireDecode(const ndn::Block& wire)
|
||||
{
|
||||
m_connectingFaceUri = {};
|
||||
m_routeCost = 0;
|
||||
|
||||
m_wire = wire;
|
||||
|
||||
if (m_wire.type() != nlsr::tlv::NextHop) {
|
||||
NDN_THROW(Error("NextHop", m_wire.type()));
|
||||
}
|
||||
|
||||
m_wire.parse();
|
||||
|
||||
auto val = m_wire.elements_begin();
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Uri) {
|
||||
try {
|
||||
m_connectingFaceUri = ndn::FaceUri(ndn::encoding::readString(*val));
|
||||
}
|
||||
catch (const ndn::FaceUri::Error& e) {
|
||||
NDN_THROW_NESTED(Error("Invalid Uri"));
|
||||
}
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Uri field"));
|
||||
}
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == nlsr::tlv::CostDouble) {
|
||||
m_routeCost = ndn::encoding::readDouble(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required CostDouble field"));
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NextHop& hop)
|
||||
{
|
||||
os << "Nexthop("
|
||||
<< "face-uri: " << hop.getConnectingFaceUri()
|
||||
<< ", cost: " << hop.getRouteCost() << ")";
|
||||
|
||||
os << "NextHop(Uri: " << hop.getConnectingFaceUri() << ", Cost: " << hop.getRouteCost() << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
+73
-25
@@ -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
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,42 +16,60 @@
|
||||
*
|
||||
* 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_NEXTHOP_HPP
|
||||
#define NLSR_NEXTHOP_HPP
|
||||
*/
|
||||
|
||||
#ifndef NLSR_ROUTE_NEXTHOP_HPP
|
||||
#define NLSR_ROUTE_NEXTHOP_HPP
|
||||
|
||||
#include "test-access-control.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <ndn-cxx/encoding/block.hpp>
|
||||
#include <ndn-cxx/encoding/encoding-buffer.hpp>
|
||||
#include <ndn-cxx/encoding/tlv.hpp>
|
||||
#include <ndn-cxx/net/face-uri.hpp>
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace nlsr {
|
||||
class NextHop
|
||||
|
||||
/*! \brief Data abstraction for Nexthop
|
||||
*
|
||||
* NextHop := NEXTHOP-TYPE TLV-LENGTH
|
||||
* Uri
|
||||
* Cost
|
||||
*
|
||||
* \sa https://redmine.named-data.net/projects/nlsr/wiki/Routing_Table_Dataset
|
||||
*/
|
||||
class NextHop : private boost::totally_ordered<NextHop>
|
||||
{
|
||||
public:
|
||||
NextHop()
|
||||
: m_connectingFaceUri()
|
||||
, m_routeCost(0)
|
||||
, m_isHyperbolic(false)
|
||||
using Error = ndn::tlv::Error;
|
||||
|
||||
NextHop() = default;
|
||||
|
||||
NextHop(const ndn::FaceUri& cfu, double rc)
|
||||
: m_connectingFaceUri(cfu)
|
||||
, m_routeCost(rc)
|
||||
{
|
||||
}
|
||||
|
||||
NextHop(const std::string& cfu, double rc)
|
||||
: m_isHyperbolic(false)
|
||||
explicit
|
||||
NextHop(const ndn::Block& block)
|
||||
{
|
||||
m_connectingFaceUri = cfu;
|
||||
m_routeCost = rc;
|
||||
wireDecode(block);
|
||||
}
|
||||
|
||||
const std::string&
|
||||
const ndn::FaceUri&
|
||||
getConnectingFaceUri() const
|
||||
{
|
||||
return m_connectingFaceUri;
|
||||
}
|
||||
|
||||
void
|
||||
setConnectingFaceUri(const std::string& cfu)
|
||||
setConnectingFaceUri(const ndn::FaceUri& cfu)
|
||||
{
|
||||
m_connectingFaceUri = cfu;
|
||||
}
|
||||
@@ -94,10 +112,41 @@ public:
|
||||
return m_isHyperbolic;
|
||||
}
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(ndn::EncodingImpl<TAG>& block) const;
|
||||
|
||||
const ndn::Block&
|
||||
wireEncode() const;
|
||||
|
||||
void
|
||||
wireDecode(const ndn::Block& wire);
|
||||
|
||||
private: // non-member operators
|
||||
// NOTE: the following "hidden friend" operators are available via
|
||||
// argument-dependent lookup only and must be defined inline.
|
||||
// boost::totally_ordered provides !=, <=, >=, and > operators.
|
||||
|
||||
friend bool
|
||||
operator==(const NextHop& lhs, const NextHop& rhs)
|
||||
{
|
||||
return lhs.getRouteCostAsAdjustedInteger() == rhs.getRouteCostAsAdjustedInteger() &&
|
||||
lhs.getConnectingFaceUri() == rhs.getConnectingFaceUri();
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator<(const NextHop& lhs, const NextHop& rhs)
|
||||
{
|
||||
return std::forward_as_tuple(lhs.getRouteCostAsAdjustedInteger(), lhs.getConnectingFaceUri()) <
|
||||
std::forward_as_tuple(rhs.getRouteCostAsAdjustedInteger(), rhs.getConnectingFaceUri());
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_connectingFaceUri;
|
||||
double m_routeCost;
|
||||
bool m_isHyperbolic;
|
||||
ndn::FaceUri m_connectingFaceUri;
|
||||
double m_routeCost = 0.0;
|
||||
bool m_isHyperbolic = false;
|
||||
|
||||
mutable ndn::Block m_wire;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/*! \brief Used to adjust floating point route costs to integers
|
||||
@@ -110,15 +159,14 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
|
||||
e.g costs 12.34 and 12.35 will be installed into NFD's FIB as 12340 and 12350
|
||||
*/
|
||||
static const uint64_t HYPERBOLIC_COST_ADJUSTMENT_FACTOR = 1000;
|
||||
static constexpr uint64_t HYPERBOLIC_COST_ADJUSTMENT_FACTOR = 1000;
|
||||
};
|
||||
|
||||
bool
|
||||
operator==(const NextHop& lhs, const NextHop& rhs);
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NextHop);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NextHop& hop);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif //NLSR_NEXTHOP_HPP
|
||||
#endif // NLSR_ROUTE_NEXTHOP_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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/>.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "routing-table-calculator.hpp"
|
||||
#include "lsdb.hpp"
|
||||
@@ -25,16 +25,23 @@
|
||||
#include "nexthop.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "adjacent.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
#include <cmath>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER(route.RoutingTableCalculator);
|
||||
|
||||
constexpr int EMPTY_PARENT = -12345;
|
||||
constexpr double INF_DISTANCE = 2147483647;
|
||||
constexpr int NO_MAPPING_NUM = -1;
|
||||
constexpr int NO_NEXT_HOP = -12345;
|
||||
constexpr double UNKNOWN_DISTANCE = -1.0;
|
||||
constexpr double UNKNOWN_RADIUS = -1.0;
|
||||
|
||||
void
|
||||
RoutingTableCalculator::allocateAdjMatrix()
|
||||
{
|
||||
@@ -50,27 +57,28 @@ RoutingTableCalculator::initMatrix()
|
||||
{
|
||||
for (size_t i = 0; i < m_nRouters; i++) {
|
||||
for (size_t j = 0; j < m_nRouters; j++) {
|
||||
adjMatrix[i][j] = 0;
|
||||
adjMatrix[i][j] = Adjacent::NON_ADJACENT_COST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTableCalculator::makeAdjMatrix(const std::list<AdjLsa>& adjLsaList, Map& pMap)
|
||||
RoutingTableCalculator::makeAdjMatrix(const Lsdb& lsdb, Map& pMap)
|
||||
{
|
||||
// For each LSA represented in the map
|
||||
for (const auto& adjLsa : adjLsaList) {
|
||||
ndn::optional<int32_t> row = pMap.getMappingNoByRouterName(adjLsa.getOrigRouter());
|
||||
auto lsaRange = lsdb.getLsdbIterator<AdjLsa>();
|
||||
for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
|
||||
auto adjLsa = std::static_pointer_cast<AdjLsa>(*lsaIt);
|
||||
auto row = pMap.getMappingNoByRouterName(adjLsa->getOriginRouter());
|
||||
|
||||
std::list<Adjacent> adl = adjLsa.getAdl().getAdjList();
|
||||
std::list<Adjacent> adl = adjLsa->getAdl().getAdjList();
|
||||
// For each adjacency represented in the LSA
|
||||
for (const auto& adjacent : adl) {
|
||||
ndn::optional<int32_t> col = pMap.getMappingNoByRouterName(adjacent.getName());
|
||||
auto col = pMap.getMappingNoByRouterName(adjacent.getName());
|
||||
double cost = adjacent.getLinkCost();
|
||||
|
||||
if (row && col && *row < static_cast<int32_t>(m_nRouters)
|
||||
&& *col < static_cast<int32_t>(m_nRouters))
|
||||
{
|
||||
&& *col < static_cast<int32_t>(m_nRouters)) {
|
||||
adjMatrix[*row][*col] = cost;
|
||||
}
|
||||
}
|
||||
@@ -79,8 +87,8 @@ RoutingTableCalculator::makeAdjMatrix(const std::list<AdjLsa>& adjLsaList, Map&
|
||||
// Links that do not have the same cost for both directions should
|
||||
// have their costs corrected:
|
||||
//
|
||||
// If the cost of one side of the link is 0, both sides of the
|
||||
// link should have their cost corrected to 0.
|
||||
// If the cost of one side of the link is NON_ADJACENT_COST (i.e. broken) or negative,
|
||||
// both direction of the link should have their cost corrected to NON_ADJACENT_COST.
|
||||
//
|
||||
// Otherwise, both sides of the link should use the larger of the two costs.
|
||||
//
|
||||
@@ -93,10 +101,10 @@ RoutingTableCalculator::makeAdjMatrix(const std::list<AdjLsa>& adjLsaList, Map&
|
||||
double fromCost = adjMatrix[col][row];
|
||||
|
||||
if (fromCost != toCost) {
|
||||
double correctedCost = 0.0;
|
||||
double correctedCost = Adjacent::NON_ADJACENT_COST;
|
||||
|
||||
if (toCost != 0 && fromCost != 0) {
|
||||
// If both sides of the link are up, use the larger cost
|
||||
if (toCost >= 0 && fromCost >= 0) {
|
||||
// If both sides of the link are up, use the larger cost else break the link
|
||||
correctedCost = std::max(toCost, fromCost);
|
||||
}
|
||||
|
||||
@@ -136,8 +144,13 @@ RoutingTableCalculator::writeAdjMatrixLog(const Map& map) const
|
||||
for (size_t i = 0; i < m_nRouters; i++) {
|
||||
std::string line;
|
||||
for (size_t j = 0; j < m_nRouters; j++) {
|
||||
line += boost::lexical_cast<std::string>(adjMatrix[i][j]);
|
||||
line += " ";
|
||||
if (adjMatrix[i][j] == NO_NEXT_HOP) {
|
||||
line += "0 ";
|
||||
}
|
||||
else {
|
||||
line += boost::lexical_cast<std::string>(adjMatrix[i][j]);
|
||||
line += " ";
|
||||
}
|
||||
}
|
||||
line = boost::lexical_cast<std::string>(i) + "|" + line;
|
||||
NLSR_LOG_DEBUG(line);
|
||||
@@ -152,7 +165,8 @@ RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
|
||||
adjMatrix[source][i] = linkCost;
|
||||
}
|
||||
else {
|
||||
adjMatrix[source][i] = 0;
|
||||
// if "i" is not a link to the source, set it's cost to a non adjacent value.
|
||||
adjMatrix[source][i] = Adjacent::NON_ADJACENT_COST;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +177,7 @@ RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
|
||||
int noLink = 0;
|
||||
|
||||
for (size_t i = 0; i < m_nRouters; i++) {
|
||||
if (adjMatrix[sRouter][i] > 0) {
|
||||
if (adjMatrix[sRouter][i] >= 0 && i != static_cast<size_t>(sRouter)) { // make sure "i" is not self
|
||||
noLink++;
|
||||
}
|
||||
}
|
||||
@@ -177,7 +191,7 @@ RoutingTableCalculator::getLinksFromAdjMatrix(int* links,
|
||||
int j = 0;
|
||||
|
||||
for (size_t i = 0; i < m_nRouters; i++) {
|
||||
if (adjMatrix[source][i] > 0) {
|
||||
if (adjMatrix[source][i] >= 0 && i != static_cast<size_t>(source)) {// make sure "i" is not self
|
||||
links[j] = i;
|
||||
linkCosts[j] = adjMatrix[source][i];
|
||||
j++;
|
||||
@@ -206,7 +220,6 @@ RoutingTableCalculator::allocateLinkCosts()
|
||||
linkCosts = new double[vNoLink];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RoutingTableCalculator::freeLinks()
|
||||
{
|
||||
@@ -221,15 +234,14 @@ RoutingTableCalculator::freeLinksCosts()
|
||||
void
|
||||
LinkStateRoutingTableCalculator::calculatePath(Map& pMap, RoutingTable& rt,
|
||||
ConfParameter& confParam,
|
||||
const std::list<AdjLsa>& adjLsaList)
|
||||
const Lsdb& lsdb)
|
||||
{
|
||||
NLSR_LOG_DEBUG("LinkStateRoutingTableCalculator::calculatePath Called");
|
||||
allocateAdjMatrix();
|
||||
initMatrix();
|
||||
makeAdjMatrix(adjLsaList, pMap);
|
||||
makeAdjMatrix(lsdb, pMap);
|
||||
writeAdjMatrixLog(pMap);
|
||||
ndn::optional<int32_t> sourceRouter =
|
||||
pMap.getMappingNoByRouterName(confParam.getRouterPrefix());
|
||||
auto sourceRouter = pMap.getMappingNoByRouterName(confParam.getRouterPrefix());
|
||||
allocateParent(); // These two matrices are used in Dijkstra's algorithm.
|
||||
allocateDistance(); //
|
||||
// We only bother to do the calculation if we have a router by that name.
|
||||
@@ -290,7 +302,7 @@ LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
|
||||
// Iterate over the adjacent nodes to u.
|
||||
for (v = 0 ; v < static_cast<int>(m_nRouters); v++) {
|
||||
// If the current node is accessible.
|
||||
if (adjMatrix[u][v] > 0) {
|
||||
if (adjMatrix[u][v] >= 0) {
|
||||
// And we haven't visited it yet.
|
||||
if (isNotExplored(Q, v, head + 1, m_nRouters)) {
|
||||
// And if the distance to this node + from this node to v
|
||||
@@ -328,21 +340,18 @@ LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(AdjacencyList& a
|
||||
|
||||
// Obtain the next hop that was determined by the algorithm
|
||||
nextHopRouter = getLsNextHop(i, sourceRouter);
|
||||
|
||||
// If this router is accessible at all
|
||||
if (nextHopRouter != NO_NEXT_HOP) {
|
||||
|
||||
// Fetch its distance
|
||||
double routeCost = m_distance[i];
|
||||
// Fetch its actual name
|
||||
ndn::optional<ndn::Name> nextHopRouterName= pMap.getRouterNameByMappingNo(nextHopRouter);
|
||||
auto nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
|
||||
if (nextHopRouterName) {
|
||||
std::string nextHopFace =
|
||||
adjacencies.getAdjacent(*nextHopRouterName).getFaceUri().toString();
|
||||
auto nextHopFace = adjacencies.getAdjacent(*nextHopRouterName).getFaceUri();
|
||||
// Add next hop to routing table
|
||||
NextHop nh(nextHopFace, routeCost);
|
||||
rt.addNextHop(*(pMap.getRouterNameByMappingNo(i)), nh);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -416,22 +425,17 @@ void LinkStateRoutingTableCalculator::freeDistance()
|
||||
delete [] m_distance;
|
||||
}
|
||||
|
||||
const double HyperbolicRoutingCalculator::MATH_PI = boost::math::constants::pi<double>();
|
||||
|
||||
const double HyperbolicRoutingCalculator::UNKNOWN_DISTANCE = -1.0;
|
||||
const double HyperbolicRoutingCalculator::UNKNOWN_RADIUS = -1.0;
|
||||
|
||||
void
|
||||
HyperbolicRoutingCalculator::calculatePath(Map& map, RoutingTable& rt,
|
||||
Lsdb& lsdb, AdjacencyList& adjacencies)
|
||||
{
|
||||
NLSR_LOG_TRACE("Calculating hyperbolic paths");
|
||||
|
||||
ndn::optional<int32_t> thisRouter = map.getMappingNoByRouterName(m_thisRouterName);
|
||||
auto thisRouter = map.getMappingNoByRouterName(m_thisRouterName);
|
||||
|
||||
// Iterate over directly connected neighbors
|
||||
std::list<Adjacent> neighbors = adjacencies.getAdjList();
|
||||
for (std::list<Adjacent>::iterator adj = neighbors.begin(); adj != neighbors.end(); ++adj) {
|
||||
for (auto adj = neighbors.begin(); adj != neighbors.end(); ++adj) {
|
||||
|
||||
// Don't calculate nexthops using an inactive router
|
||||
if (adj->getStatus() == Adjacent::STATUS_INACTIVE) {
|
||||
@@ -446,13 +450,10 @@ HyperbolicRoutingCalculator::calculatePath(Map& map, RoutingTable& rt,
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string srcFaceUri = adj->getFaceUri().toString();
|
||||
|
||||
// Install nexthops for this router to the neighbor; direct neighbors have a 0 cost link
|
||||
addNextHop(srcRouterName, srcFaceUri, 0, rt);
|
||||
|
||||
ndn::optional<int32_t> src = map.getMappingNoByRouterName(srcRouterName);
|
||||
addNextHop(srcRouterName, adj->getFaceUri(), 0, rt);
|
||||
|
||||
auto src = map.getMappingNoByRouterName(srcRouterName);
|
||||
if (!src) {
|
||||
NLSR_LOG_WARN(adj->getName() << " does not exist in the router map!");
|
||||
continue;
|
||||
@@ -463,18 +464,17 @@ HyperbolicRoutingCalculator::calculatePath(Map& map, RoutingTable& rt,
|
||||
// Don't calculate nexthops to this router or from a router to itself
|
||||
if (thisRouter && dest != *thisRouter && dest != *src) {
|
||||
|
||||
ndn::optional<ndn::Name> destRouterName = map.getRouterNameByMappingNo(dest);
|
||||
auto destRouterName = map.getRouterNameByMappingNo(dest);
|
||||
if (destRouterName) {
|
||||
double distance = getHyperbolicDistance(lsdb, srcRouterName, *destRouterName);
|
||||
|
||||
// Could not compute distance
|
||||
if (distance == UNKNOWN_DISTANCE) {
|
||||
NLSR_LOG_WARN("Could not calculate hyperbolic distance from " << srcRouterName << " to " <<
|
||||
*destRouterName);
|
||||
NLSR_LOG_WARN("Could not calculate hyperbolic distance from " << srcRouterName
|
||||
<< " to " << *destRouterName);
|
||||
continue;
|
||||
}
|
||||
|
||||
addNextHop(*destRouterName, srcFaceUri, distance, rt);
|
||||
addNextHop(*destRouterName, adj->getFaceUri(), distance, rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,15 +488,8 @@ HyperbolicRoutingCalculator::getHyperbolicDistance(Lsdb& lsdb, ndn::Name src, nd
|
||||
|
||||
double distance = UNKNOWN_DISTANCE;
|
||||
|
||||
ndn::Name srcLsaKey = src;
|
||||
srcLsaKey.append(std::to_string(Lsa::Type::COORDINATE));
|
||||
|
||||
CoordinateLsa* srcLsa = lsdb.findCoordinateLsa(srcLsaKey);
|
||||
|
||||
ndn::Name destLsaKey = dest;
|
||||
destLsaKey.append(std::to_string(Lsa::Type::COORDINATE));
|
||||
|
||||
CoordinateLsa* destLsa = lsdb.findCoordinateLsa(destLsaKey);
|
||||
auto srcLsa = lsdb.findLsa<CoordinateLsa>(src);
|
||||
auto destLsa = lsdb.findLsa<CoordinateLsa>(dest);
|
||||
|
||||
// Coordinate LSAs do not exist for these routers
|
||||
if (srcLsa == nullptr || destLsa == nullptr) {
|
||||
@@ -548,6 +541,7 @@ HyperbolicRoutingCalculator::calculateAngularDistance(std::vector<double> angleV
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (angleVectorI[angleVectorI.size()-1] > 2.*M_PI ||
|
||||
angleVectorI[angleVectorI.size()-1] < 0.0) {
|
||||
NLSR_LOG_ERROR("Angle not within [0, 2PI]");
|
||||
@@ -621,7 +615,7 @@ HyperbolicRoutingCalculator::calculateHyperbolicDistance(double rI, double rJ,
|
||||
}
|
||||
|
||||
void
|
||||
HyperbolicRoutingCalculator::addNextHop(ndn::Name dest, std::string faceUri,
|
||||
HyperbolicRoutingCalculator::addNextHop(const ndn::Name& dest, const ndn::FaceUri& faceUri,
|
||||
double cost, RoutingTable& rt)
|
||||
{
|
||||
NextHop hop(faceUri, cost);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2019, 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,22 +16,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
**/
|
||||
*/
|
||||
|
||||
#ifndef NLSR_ROUTING_TABLE_CALCULATOR_HPP
|
||||
#define NLSR_ROUTING_TABLE_CALCULATOR_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "lsa/lsa.hpp"
|
||||
#include "lsa/adj-lsa.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "conf-parameter.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <ndn-cxx/name.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
class Map;
|
||||
@@ -40,29 +35,31 @@ class RoutingTable;
|
||||
class RoutingTableCalculator
|
||||
{
|
||||
public:
|
||||
RoutingTableCalculator()
|
||||
{
|
||||
}
|
||||
RoutingTableCalculator(size_t nRouters)
|
||||
{
|
||||
m_nRouters = nRouters;
|
||||
}
|
||||
|
||||
protected:
|
||||
/*! \brief Allocate the space needed for the adj. matrix. */
|
||||
void
|
||||
allocateAdjMatrix();
|
||||
|
||||
/*! \brief Zero every cell of the matrix to ensure that the memory is safe. */
|
||||
/*! \brief set NON_ADJACENT_COST i.e. -12345 to every cell of the matrix to
|
||||
ensure that the memory is safe. This is also to incorporate zero cost links */
|
||||
void
|
||||
initMatrix();
|
||||
|
||||
/*! \brief Constructs an adj. matrix to calculate with.
|
||||
\param adjLsaList The Adjacency Lsa list.
|
||||
\param lsdb Reference to the Lsdb
|
||||
\param pMap The map to populate with the adj. data.
|
||||
*/
|
||||
void
|
||||
makeAdjMatrix(const std::list<AdjLsa>& adjLsaList, Map& pMap);
|
||||
makeAdjMatrix(const Lsdb& lsdb, Map& pMap);
|
||||
|
||||
/*! \brief Writes a formated adjacent matrix to DEBUG log
|
||||
\param map The map containing adjacent matrix data
|
||||
*/
|
||||
void
|
||||
writeAdjMatrixLog(const Map& map) const;
|
||||
|
||||
@@ -90,8 +87,8 @@ protected:
|
||||
Obtains a sparse list of adjacencies and link costs for some
|
||||
router. Since this is sparse, that means while generating these
|
||||
arrays, if there is no adjacency at i in the matrix, these
|
||||
temporary variables will not contain a 0 at i, but rather will
|
||||
contain the values for the next valid adjacency.
|
||||
temporary variables will not contain a NON_ADJACENT_COST (-12345) at i,
|
||||
but rather will contain the values for the next valid adjacency.
|
||||
*/
|
||||
void
|
||||
getLinksFromAdjMatrix(int* links, double* linkCosts, int source);
|
||||
@@ -122,6 +119,7 @@ protected:
|
||||
int vNoLink;
|
||||
int* links;
|
||||
double* linkCosts;
|
||||
|
||||
};
|
||||
|
||||
class LinkStateRoutingTableCalculator: public RoutingTableCalculator
|
||||
@@ -129,16 +127,12 @@ class LinkStateRoutingTableCalculator: public RoutingTableCalculator
|
||||
public:
|
||||
LinkStateRoutingTableCalculator(size_t nRouters)
|
||||
: RoutingTableCalculator(nRouters)
|
||||
, EMPTY_PARENT(-12345)
|
||||
, INF_DISTANCE(2147483647)
|
||||
, NO_MAPPING_NUM(-1)
|
||||
, NO_NEXT_HOP(-12345)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
calculatePath(Map& pMap, RoutingTable& rt, ConfParameter& confParam,
|
||||
const std::list<AdjLsa>& adjLsaList);
|
||||
const Lsdb& lsdb);
|
||||
|
||||
private:
|
||||
/*! \brief Performs a Dijkstra's calculation over the adjacency matrix.
|
||||
@@ -155,6 +149,9 @@ private:
|
||||
|
||||
Sorts the list based on distance. The distances are indexed by
|
||||
their mappingNo in dist. Currently uses an insertion sort.
|
||||
|
||||
The cost between two nodes can be zero or greater than zero.
|
||||
|
||||
*/
|
||||
void
|
||||
sortQueueByDistance(int* Q, double* dist, int start, int element);
|
||||
@@ -194,12 +191,6 @@ private:
|
||||
private:
|
||||
int* m_parent;
|
||||
double* m_distance;
|
||||
|
||||
const int EMPTY_PARENT;
|
||||
const double INF_DISTANCE;
|
||||
const int NO_MAPPING_NUM;
|
||||
const int NO_NEXT_HOP;
|
||||
|
||||
};
|
||||
|
||||
class AdjacencyList;
|
||||
@@ -223,7 +214,7 @@ private:
|
||||
getHyperbolicDistance(Lsdb& lsdb, ndn::Name src, ndn::Name dest);
|
||||
|
||||
void
|
||||
addNextHop(ndn::Name destinationRouter, std::string faceUri, double cost, RoutingTable& rt);
|
||||
addNextHop(const ndn::Name& destinationRouter, const ndn::FaceUri& faceUri, double cost, RoutingTable& rt);
|
||||
|
||||
double
|
||||
calculateHyperbolicDistance(double rI, double rJ, double deltaTheta);
|
||||
@@ -236,10 +227,6 @@ private:
|
||||
const size_t m_nRouters;
|
||||
const bool m_isDryRun;
|
||||
const ndn::Name m_thisRouterName;
|
||||
|
||||
static const double MATH_PI;
|
||||
static const double UNKNOWN_DISTANCE;
|
||||
static const double UNKNOWN_RADIUS;
|
||||
};
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, The University of Memphis,
|
||||
/*
|
||||
* Copyright (c) 2014-2022, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -16,21 +16,89 @@
|
||||
*
|
||||
* 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 "routing-table-entry.hpp"
|
||||
#include "nexthop-list.hpp"
|
||||
#include "tlv-nlsr.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
template<ndn::encoding::Tag TAG>
|
||||
size_t
|
||||
RoutingTableEntry::wireEncode(ndn::EncodingImpl<TAG>& block) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
for (auto it = m_nexthopList.rbegin(); it != m_nexthopList.rend(); ++it) {
|
||||
totalLength += it->wireEncode(block);
|
||||
}
|
||||
|
||||
totalLength += m_destination.wireEncode(block);
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(nlsr::tlv::RoutingTableEntry);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(RoutingTableEntry);
|
||||
|
||||
const ndn::Block&
|
||||
RoutingTableEntry::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
|
||||
RoutingTableEntry::wireDecode(const ndn::Block& wire)
|
||||
{
|
||||
m_nexthopList.clear();
|
||||
|
||||
m_wire = wire;
|
||||
|
||||
if (m_wire.type() != nlsr::tlv::RoutingTableEntry) {
|
||||
NDN_THROW(Error("RoutingTableEntry", m_wire.type()));
|
||||
}
|
||||
|
||||
m_wire.parse();
|
||||
auto val = m_wire.elements_begin();
|
||||
|
||||
if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
|
||||
m_destination.wireDecode(*val);
|
||||
++val;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Missing required Name field"));
|
||||
}
|
||||
|
||||
for (; val != m_wire.elements_end(); ++val) {
|
||||
if (val->type() == nlsr::tlv::NextHop) {
|
||||
m_nexthopList.addNextHop(NextHop(*val));
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("NextHop", val->type()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const RoutingTableEntry& rte)
|
||||
{
|
||||
os << "RoutingTableEntry("
|
||||
<< "Destination: " << rte.getDestination()
|
||||
<< "Next hop list: " << rte.getNexthopList() << ")";
|
||||
|
||||
return os;
|
||||
return os << " Destination: " << rte.getDestination() << "\n"
|
||||
<< rte.getNexthopList() << "\n";
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
Loaded 100 of 213 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user