Compare commits
57
Commits
ndn-cxx-0.7.0
...
qsccp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58b423fe00 | ||
|
|
e72ce81d2b | ||
|
|
bdfb53aa09 | ||
|
|
287a7faad9 | ||
|
|
fa33f8d532 | ||
|
|
1caa634dca | ||
|
|
e36aae1eb8 | ||
|
|
670a52f2a3 | ||
|
|
97ee811129 | ||
|
|
599623c303 | ||
|
|
483087f56d | ||
|
|
81bd696ed9 | ||
|
|
17d7c47ca9 | ||
|
|
933a567c8a | ||
|
|
f2c4c53208 | ||
|
|
6b2cb79748 | ||
|
|
b74bbdab84 | ||
|
|
6d024bad65 | ||
|
|
8afba42296 | ||
|
|
2ca5e79633 | ||
|
|
905d40fad9 | ||
|
|
355fd789c8 | ||
|
|
75c3af824a | ||
|
|
46cdf909a5 | ||
|
|
9d1089aa29 | ||
|
|
6e262f0f1e | ||
|
|
09236c2b8d | ||
|
|
f601e1988b | ||
|
|
ab9d7ed25a | ||
|
|
3de8aac22d | ||
|
|
f165bb4e77 | ||
|
|
78ffc635cc | ||
|
|
14c56cd8bd | ||
|
|
bc2e78e074 | ||
|
|
a3c8bd1772 | ||
|
|
40ebaad603 | ||
|
|
3ad8923060 | ||
|
|
25d4f1c95e | ||
|
|
71c622bb68 | ||
|
|
394977c2f2 | ||
|
|
fbb6990abc | ||
|
|
702467b816 | ||
|
|
4c68b6e62c | ||
|
|
78338c5ee8 | ||
|
|
9603325ba6 | ||
|
|
ab7300b747 | ||
|
|
52a803cb9d | ||
|
|
2349e28c6d | ||
|
|
d776a93c9c | ||
|
|
ce9c1952ff | ||
|
|
53533947d1 | ||
|
|
97242f78e9 | ||
|
|
bc17d950e0 | ||
|
|
d247d49469 | ||
|
|
8d6d10ae53 | ||
|
|
9c8f00e3fb | ||
|
|
3b9a2c8b74 |
No files matched your search
+1
-1
@@ -26,4 +26,4 @@ __pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# Other
|
||||
/VERSION
|
||||
/VERSION.info
|
||||
@@ -1,9 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
source .jenkins.d/util.sh
|
||||
|
||||
export CACHE_DIR=${CACHE_DIR:-/tmp}
|
||||
export WAF_JOBS=${WAF_JOBS:-1}
|
||||
[[ $JOB_NAME == *"code-coverage" ]] && export DISABLE_ASAN=yes
|
||||
|
||||
nanos() {
|
||||
# Cannot use date(1) because macOS does not support %N format specifier
|
||||
python -c 'import time; print(int(time.time() * 1e9))'
|
||||
python3 -c 'import time; print(int(time.time() * 1e9))'
|
||||
}
|
||||
|
||||
for file in .jenkins.d/*; do
|
||||
|
||||
+20
-35
@@ -1,53 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
set -ex
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
FORMULAE=(boost pkg-config)
|
||||
if [[ -n $USE_OPENSSL_1_1 ]]; then
|
||||
FORMULAE+=(openssl@1.1)
|
||||
else
|
||||
FORMULAE+=(openssl)
|
||||
FORMULAE=(boost openssl pkg-config)
|
||||
if has OSX-10.13 $NODE_LABELS || has OSX-10.14 $NODE_LABELS; then
|
||||
FORMULAE+=(python)
|
||||
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
|
||||
# Travis images come with a large number of pre-installed
|
||||
# brew packages, don't waste time upgrading all of them
|
||||
brew list --versions "${FORMULAE[@]}" || brew update
|
||||
for FORMULA in "${FORMULAE[@]}"; do
|
||||
brew outdated $FORMULA || brew upgrade $FORMULA
|
||||
brew list --versions "$FORMULA" || brew install "$FORMULA"
|
||||
done
|
||||
# Ensure /usr/local/opt/openssl exists
|
||||
brew reinstall openssl
|
||||
else
|
||||
brew update
|
||||
brew upgrade
|
||||
brew install "${FORMULAE[@]}"
|
||||
brew cleanup
|
||||
fi
|
||||
brew install "${FORMULAE[@]}"
|
||||
brew cleanup
|
||||
fi
|
||||
|
||||
if has Ubuntu $NODE_LABELS; then
|
||||
elif has Ubuntu $NODE_LABELS; then
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qy install build-essential pkg-config libboost-all-dev \
|
||||
libsqlite3-dev libssl-dev
|
||||
sudo apt-get -qy install g++ pkg-config python3-minimal \
|
||||
libboost-all-dev libssl-dev libsqlite3-dev
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
sudo apt-get -qy install gcovr lcov libgd-perl
|
||||
sudo apt-get -qy install gcovr lcov
|
||||
fi
|
||||
fi
|
||||
|
||||
if has CentOS-7 $NODE_LABELS; then
|
||||
sudo yum -y install yum-utils pkgconfig \
|
||||
openssl-devel libtranslit-icu \
|
||||
python-devel sqlite-devel \
|
||||
devtoolset-7-libasan-devel \
|
||||
devtoolset-7-liblsan-devel
|
||||
sudo yum -y groupinstall 'Development Tools'
|
||||
|
||||
svn checkout https://github.com/cmscaltech/sandie-ndn/trunk/packaging/RPMS/x86_64/boost1_58_0
|
||||
pushd boost1_58_0 >/dev/null
|
||||
sudo rpm -Uv --replacepkgs --replacefiles boost-devel* boost-license* libboost_*
|
||||
popd >/dev/null
|
||||
elif has CentOS-8 $NODE_LABELS; then
|
||||
sudo dnf -y install gcc-c++ libasan pkgconf-pkg-config python3 \
|
||||
boost-devel openssl-devel sqlite-devel
|
||||
fi
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
sudo rm -f /usr/local/bin/ndnsec*
|
||||
sudo rm -fr /usr/local/include/ndn-cxx
|
||||
sudo rm -f /usr/local/lib{,64}/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
|
||||
+27
-33
@@ -1,54 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -ex
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
git submodule sync
|
||||
git submodule update --init
|
||||
|
||||
set -x
|
||||
|
||||
sudo rm -f /usr/local/bin/ndnsec*
|
||||
sudo rm -fr /usr/local/include/ndn-cxx
|
||||
sudo rm -f /usr/local/lib{,64}/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
elif [[ -z $DISABLE_ASAN ]]; then
|
||||
if [[ -z $DISABLE_ASAN ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
fi
|
||||
if [[ -n $USE_OPENSSL_1_1 ]] && has OSX $NODE_LABELS; then
|
||||
OPENSSL="--with-openssl=/usr/local/opt/openssl@1.1"
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
fi
|
||||
if has CentOS-8 $NODE_LABELS; then
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1721553
|
||||
PCH="--without-pch"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
|
||||
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
|
||||
# Configure/build static library in optimized mode with tests
|
||||
./waf --color=yes configure --enable-static --disable-shared --with-tests $OPENSSL
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build static library in release mode with tests and without precompiled headers
|
||||
./waf --color=yes configure --enable-static --disable-shared --with-tests --without-pch
|
||||
./waf --color=yes build -j$WAF_JOBS
|
||||
|
||||
# Cleanup
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
|
||||
# Configure/build static and shared library in optimized mode without tests
|
||||
./waf --color=yes configure --enable-static --enable-shared $OPENSSL
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build static and shared library in release mode without tests
|
||||
./waf --color=yes configure --enable-static --enable-shared $PCH
|
||||
./waf --color=yes build -j$WAF_JOBS
|
||||
|
||||
# Cleanup
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
fi
|
||||
|
||||
# Configure/build shared library in debug mode with tests/examples and without precompiled headers
|
||||
./waf --color=yes configure --disable-static --enable-shared --debug --with-tests \
|
||||
--with-examples --without-pch $ASAN $COVERAGE $OPENSSL
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build shared library in debug mode with tests and examples
|
||||
./waf --color=yes configure --disable-static --enable-shared --debug --with-tests --with-examples $ASAN $COVERAGE $PCH
|
||||
./waf --color=yes build -j$WAF_JOBS
|
||||
|
||||
# (tests will be run against debug version)
|
||||
# (tests will be run against the debug version)
|
||||
|
||||
# Install
|
||||
sudo_preserve_env PATH -- ./waf --color=yes install
|
||||
|
||||
if has CentOS-8 $NODE_LABELS; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if has Linux $NODE_LABELS; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
+11
-29
@@ -1,13 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
set -ex
|
||||
|
||||
# Prepare environment
|
||||
rm -Rf ~/.ndn
|
||||
rm -rf ~/.ndn
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
security unlock-keychain -p named-data
|
||||
@@ -15,33 +10,20 @@ fi
|
||||
|
||||
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
|
||||
|
||||
BOOST_VERSION=$(python -c "import sys; sys.path.append('build/c4che'); import _cache; print(_cache.BOOST_VERSION_NUMBER);")
|
||||
|
||||
ut_log_args() {
|
||||
if (( BOOST_VERSION >= 106200 )); then
|
||||
echo --logger=HRF,test_suite,stdout:XML,all,build/xunit-${1:-report}.xml
|
||||
else
|
||||
if [[ -n $XUNIT ]]; then
|
||||
echo --log_level=all $( (( BOOST_VERSION >= 106000 )) && echo -- ) \
|
||||
--log_format2=XML --log_sink2=build/xunit-${1:-report}.xml
|
||||
else
|
||||
echo --log_level=test_suite
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 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+=":strip_path_prefix=${PWD}/"
|
||||
export ASAN_OPTIONS
|
||||
|
||||
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
|
||||
|
||||
# Run unit tests
|
||||
./build/unit-tests $(ut_log_args)
|
||||
./build/unit-tests
|
||||
@@ -1,10 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
set -ex
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
gcovr --object-directory=build \
|
||||
@@ -28,7 +23,6 @@ if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
|
||||
genhtml --branch-coverage \
|
||||
--demangle-cpp \
|
||||
--frames \
|
||||
--legend \
|
||||
--output-directory build/coverage \
|
||||
--title "ndn-cxx unit tests" \
|
||||
|
||||
@@ -5,9 +5,18 @@
|
||||
# It's intentional not to use `set -e`, because this script wants to check all headers
|
||||
# (similar to running all test cases), instead of failing at the first error.
|
||||
|
||||
if [[ -n $DISABLE_HEADERS_CHECK ]]; then
|
||||
echo 'Skipping headers check.'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if has CentOS-8 $NODE_LABELS; then
|
||||
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
|
||||
fi
|
||||
|
||||
CXX=${CXX:-g++}
|
||||
STD=-std=c++14
|
||||
CXXFLAGS="-O2 -Wall -Wno-unused-const-variable -Wno-unused-local-typedef $(pkg-config --cflags libndn-cxx)"
|
||||
CXXFLAGS="-O2 -Wall -Wno-unneeded-internal-declaration -Wno-unused-const-variable $(pkg-config --cflags libndn-cxx)"
|
||||
INCLUDEDIR="$(pkg-config --variable=includedir libndn-cxx)"/ndn-cxx
|
||||
|
||||
echo "Using: $CXX $STD $CXXFLAGS"
|
||||
@@ -15,14 +24,14 @@ echo "Using: $CXX $STD $CXXFLAGS"
|
||||
NCHECKED=0
|
||||
NERRORS=0
|
||||
while IFS= read -r -d '' H; do
|
||||
echo "Verifying standalone header compilation for ${H#${INCLUDEDIR}/}"
|
||||
echo "Checking header ${H#${INCLUDEDIR}/}"
|
||||
"$CXX" -xc++ $STD $CXXFLAGS -c -o /dev/null "$H"
|
||||
[[ $? -eq 0 ]] || ((NERRORS++))
|
||||
((NCHECKED++))
|
||||
done < <(find "$INCLUDEDIR" -name '*.hpp' -type f -print0 2>/dev/null)
|
||||
|
||||
if [[ $NCHECKED -eq 0 ]]; then
|
||||
echo 'No header found. Is ndn-cxx installed?'
|
||||
echo 'No headers found. Is ndn-cxx installed?'
|
||||
exit 1
|
||||
else
|
||||
echo "$NCHECKED headers checked."
|
||||
+17
-22
@@ -1,33 +1,28 @@
|
||||
CONTINUOUS INTEGRATION SCRIPTS
|
||||
==============================
|
||||
# CONTINUOUS INTEGRATION SCRIPTS
|
||||
|
||||
Environment Variables Used in Build Scripts
|
||||
-------------------------------------------
|
||||
## Environment Variables Used in Build Scripts
|
||||
|
||||
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
|
||||
build scripts to select proper behavior for different OS.
|
||||
- `NODE_LABELS`: space-separated list of platform properties. The included values are used by
|
||||
the build scripts to select the proper behavior for different operating systems and versions.
|
||||
|
||||
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
|
||||
The list should normally contain `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
|
||||
|
||||
Possible values for Linux:
|
||||
Example values:
|
||||
|
||||
* `[OS_TYPE]`: `Linux`
|
||||
* `[DISTRO_TYPE]`: `Ubuntu`
|
||||
* `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`
|
||||
- `[OS_TYPE]`: `Linux`, `OSX`
|
||||
- `[DISTRO_TYPE]`: `Ubuntu`, `CentOS`
|
||||
- `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`, `CentOS-8`, `OSX-10.14`, `OSX-10.15`
|
||||
|
||||
Possible values for macOS:
|
||||
|
||||
* `[OS_TYPE]`: `OSX`
|
||||
* `[DISTRO_TYPE]`: `OSX` (can be absent)
|
||||
* `[DISTRO_VERSION]`: `OSX-10.12`, `OSX-10.13`, `OSX-10.14`
|
||||
|
||||
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
|
||||
- `JOB_NAME`: optional variable that defines the type of build job. Depending on the job type,
|
||||
the build scripts can perform different tasks.
|
||||
|
||||
Possible values:
|
||||
|
||||
* 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
|
||||
- empty: default build task
|
||||
- `code-coverage`: debug build with tests and code coverage analysis (Ubuntu Linux is assumed)
|
||||
- `limited-build`: only a single debug build with tests
|
||||
|
||||
- `WAF_JOBS`: number of parallel build jobs used by waf, defaults to 1.
|
||||
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled version
|
||||
of ndn-cxx. If not set, `/tmp` is used.
|
||||
|
||||
- `WAF_JOBS`: number of parallel build threads used by waf, defaults to 1.
|
||||
@@ -16,6 +16,7 @@ has() {
|
||||
set ${saved_xtrace}
|
||||
return ${ret}
|
||||
}
|
||||
export -f has
|
||||
|
||||
sudo_preserve_env() {
|
||||
local saved_xtrace
|
||||
@@ -35,3 +36,4 @@ sudo_preserve_env() {
|
||||
set ${saved_xtrace}
|
||||
sudo env "${vars[@]}" "$@"
|
||||
}
|
||||
export -f sudo_preserve_env
|
||||
@@ -6,3 +6,4 @@ Teng Liang <philoliang2011@gmail.com>
|
||||
<lybmath2009@gmail.com> <lybmath@ucla.edu>
|
||||
Hila Ben Abraham <hilata@gmail.com>
|
||||
Laqin Fan <flq12021@gmail.com>
|
||||
Jeremy Clark <jrclark2@memphis.edu>
|
||||
+79
-75
@@ -1,112 +1,116 @@
|
||||
version: ~> 1.0
|
||||
language: cpp
|
||||
os: linux
|
||||
dist: bionic
|
||||
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
- ppc64le
|
||||
- s390x
|
||||
|
||||
env:
|
||||
global:
|
||||
- JOB_NAME=limited-build
|
||||
- WAF_JOBS=2
|
||||
- COMPILER=g++-7
|
||||
- COMPILER=g++-9
|
||||
- COMPILER=clang++-6.0
|
||||
- COMPILER=clang++-9
|
||||
|
||||
matrix:
|
||||
jobs:
|
||||
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
|
||||
# disable AddressSanitizer with gcc 9 due to
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90570
|
||||
- os: linux
|
||||
env: COMPILER=g++-9 DISABLE_ASAN=yes
|
||||
# Linux
|
||||
- env: COMPILER=g++-5
|
||||
- env: COMPILER=g++-6
|
||||
- env: COMPILER=g++-8
|
||||
- env: COMPILER=clang++-4.0
|
||||
- env: COMPILER=clang++-5.0
|
||||
- env: COMPILER=clang++-7
|
||||
- env: COMPILER=clang++-8
|
||||
- env: COMPILER=clang++-10
|
||||
- env: COMPILER=clang++-11
|
||||
- env: COMPILER=clang++-12
|
||||
|
||||
# Linux/clang
|
||||
# https://apt.llvm.org/
|
||||
- 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
|
||||
# disable AddressSanitizer with clang 7 and 8
|
||||
# due to https://bugs.llvm.org/show_bug.cgi?id=40808
|
||||
- os: linux
|
||||
env: COMPILER=clang++-7 DISABLE_ASAN=yes
|
||||
- os: linux
|
||||
env: COMPILER=clang++-8 DISABLE_ASAN=yes
|
||||
- os: linux
|
||||
env: COMPILER=clang++-9
|
||||
- os: linux
|
||||
env: COMPILER=clang++-10
|
||||
|
||||
# macOS/clang
|
||||
# https://docs.travis-ci.com/user/reference/osx/#macos-version
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
env: OSX_VERSION=10.12
|
||||
# macOS
|
||||
- os: osx
|
||||
osx_image: xcode9.4
|
||||
env: OSX_VERSION=10.13
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
env: OSX_VERSION=10.13
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
env: OSX_VERSION=10.13 USE_OPENSSL_1_1=yes
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode10.3
|
||||
env: OSX_VERSION=10.14
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode10.3
|
||||
env: OSX_VERSION=10.14 USE_OPENSSL_1_1=yes
|
||||
osx_image: xcode11.3
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
env: OSX_VERSION=10.14
|
||||
osx_image: xcode11.6
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
env: OSX_VERSION=10.14 USE_OPENSSL_1_1=yes
|
||||
osx_image: xcode12
|
||||
env: # default compiler
|
||||
|
||||
allow_failures:
|
||||
- env: COMPILER=clang++-10
|
||||
- env: COMPILER=g++-5
|
||||
- env: COMPILER=g++-6
|
||||
- env: COMPILER=clang++-4.0
|
||||
- env: COMPILER=clang++-12
|
||||
|
||||
fast_finish: true
|
||||
|
||||
before_install: |
|
||||
before_install:
|
||||
- |
|
||||
: Adding apt repositories
|
||||
case ${COMPILER} in
|
||||
g++-[567]|clang++-[3456].*)
|
||||
;;
|
||||
g++-*)
|
||||
g++-9)
|
||||
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
|
||||
travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
travis_retry sudo apt-get -qq update
|
||||
;;
|
||||
clang++-*)
|
||||
clang++-1?)
|
||||
# https://apt.llvm.org/
|
||||
LLVM_REPO=${COMPILER/clang++/llvm-toolchain-${TRAVIS_DIST}}
|
||||
travis_retry wget -nv -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/${TRAVIS_DIST}/ ${LLVM_REPO%-10} main"
|
||||
travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/${TRAVIS_DIST}/ ${LLVM_REPO%-12} main"
|
||||
travis_retry sudo apt-get -qq update
|
||||
;;
|
||||
esac
|
||||
|
||||
install:
|
||||
- if [[ -n ${COMPILER} ]]; then travis_retry sudo apt-get -qy install "${COMPILER/clang++/clang}"; fi
|
||||
- |
|
||||
: Installing C++ compiler
|
||||
if [[ -n ${COMPILER} ]]; then
|
||||
travis_retry sudo apt-get -qy install ${COMPILER/clang++/clang}
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-18.04"; fi
|
||||
- if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi
|
||||
# do not waste time upgrading useless packages
|
||||
- if [[ ${TRAVIS_OS_NAME} == osx ]]; then brew pin cgal gdal numpy postgis sfcgal || true; fi
|
||||
- if [[ ${OSX_VERSION} == 10.12 ]]; then brew update; fi
|
||||
# workaround for https://github.com/Homebrew/homebrew-core/issues/26358
|
||||
- if [[ ${OSX_VERSION} == 10.12 ]]; then brew outdated python || brew upgrade python; fi
|
||||
# workaround for https://github.com/travis-ci/travis-ci/issues/6688
|
||||
- if [[ ${OSX_VERSION} == 10.12 ]]; then /usr/bin/yes | pip2 uninstall numpy || true; fi
|
||||
- if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi
|
||||
- |
|
||||
: Setting environment variables
|
||||
if [[ -n ${COMPILER} ]]; then
|
||||
export CXX=${COMPILER}
|
||||
fi
|
||||
case ${TRAVIS_OS_NAME} in
|
||||
linux) export NODE_LABELS="Linux Ubuntu Ubuntu-18.04" ;;
|
||||
osx) export NODE_LABELS="OSX OSX-$(sw_vers -productVersion | cut -d . -f -2)" ;;
|
||||
esac
|
||||
export JOB_NAME=limited-build
|
||||
export WAF_JOBS=2
|
||||
- |
|
||||
: Enabling workarounds
|
||||
case "${TRAVIS_CPU_ARCH},${COMPILER}" in
|
||||
arm64,g++*)
|
||||
# Avoid exceeding the per-job time limit
|
||||
export DISABLE_HEADERS_CHECK=yes
|
||||
;;
|
||||
ppc64le,g++-7)
|
||||
# AddressSanitizer does not seem to be working
|
||||
export DISABLE_ASAN=yes
|
||||
;;
|
||||
*,clang++-8)
|
||||
# https://bugs.llvm.org/show_bug.cgi?id=40808
|
||||
export DISABLE_ASAN=yes
|
||||
;;
|
||||
esac
|
||||
- ${CXX:-c++} --version
|
||||
- python --version
|
||||
|
||||
script:
|
||||
- ./.jenkins
|
||||
@@ -1,10 +1,11 @@
|
||||
# -*- 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')
|
||||
@@ -17,15 +18,21 @@ def configure(conf):
|
||||
if cxx == 'gcc':
|
||||
if ccver < (5, 3, 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 7.4.0.')
|
||||
elif ccver < (7, 4, 0):
|
||||
warnmsg = ('Using a version of gcc older than 7.4.0 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' and ccver < (9, 0, 0):
|
||||
errmsg = ('The version of Xcode you are using is too old.\n'
|
||||
'The minimum supported Xcode version is 9.0.')
|
||||
elif ccver < (4, 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 4.0.')
|
||||
conf.flags = ClangFlags()
|
||||
else:
|
||||
warnmsg = 'Note: %s compiler is unsupported' % cxx
|
||||
warnmsg = '%s compiler is unsupported' % cxx
|
||||
conf.flags = CompilerFlags()
|
||||
|
||||
if errmsg:
|
||||
@@ -33,7 +40,7 @@ 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)
|
||||
|
||||
@@ -137,13 +144,14 @@ class GccBasicFlags(CompilerFlags):
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O0',
|
||||
'-Og', # gcc >= 4.8, clang >= 4.0
|
||||
flags['CXXFLAGS'] += ['-Og',
|
||||
'-g3',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Werror',
|
||||
'-Wcatch-value=2',
|
||||
'-Wextra-semi',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
@@ -159,6 +167,8 @@ class GccBasicFlags(CompilerFlags):
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wcatch-value=2',
|
||||
'-Wextra-semi',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
@@ -168,49 +178,50 @@ class GccBasicFlags(CompilerFlags):
|
||||
class GccFlags(GccBasicFlags):
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color',
|
||||
'-Wredundant-tags',
|
||||
]
|
||||
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color',
|
||||
'-Wredundant-tags',
|
||||
]
|
||||
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
class ClangFlags(GccBasicFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getGeneralFlags(conf)
|
||||
if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0):
|
||||
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
|
||||
elif Utils.unversioned_sys_platform() == 'freebsd':
|
||||
# Bug #4790
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
|
||||
return flags
|
||||
|
||||
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):
|
||||
if self.getCompilerVersion(conf) < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
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):
|
||||
if self.getCompilerVersion(conf) < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
return flags
|
||||
+57
-39
@@ -1,43 +1,61 @@
|
||||
ndn-cxx authors
|
||||
===============
|
||||
# ndn-cxx Authors
|
||||
|
||||
## The primary authors are (and/or have been):
|
||||
The following lists maintainers, primary developers, and all much-appreciated contributors to ndn-cxx in alphabetic order.
|
||||
The specific contributions of individual authors can be obtained from the git history of the [official ndn-cxx repository](https://github.com/named-data/ndn-cxx).
|
||||
If you would like to become a contributor to the official repository, please follow the recommendations in https://github.com/named-data/.github/blob/master/CONTRIBUTING.md.
|
||||
|
||||
* Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
* Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
|
||||
* Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
|
||||
* Jeff Thompson <jefft0@remap.ucla.edu>
|
||||
* Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
|
||||
* Sepehr Abdous <https://sepehrabdous.github.io>
|
||||
* ***(Maintainer)*** Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
|
||||
* Syed Obaid Amin <http://obaidamin.weebly.com>
|
||||
* Hila Ben Abraham <https://sites.wustl.edu/hbabraham>
|
||||
* Shuo Chen <https://github.com/chenatu>
|
||||
* Muktadir R. Chowdhury <https://github.com/alvyC>
|
||||
* Jeremy Clark <https://github.com/jrandallclark>
|
||||
* Damian Coomes <https://github.com/dmcoomes>
|
||||
* Stephanie DiBenedetto
|
||||
* Qiuhan Ding <https://irl.cs.ucla.edu/~qiuhanding>
|
||||
* Chengyu Fan <https://github.com/chengyu>
|
||||
* Laqin Fan <https://github.com/laqinfan>
|
||||
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
|
||||
* Chavoosh Ghasemi <https://chavoosh.github.io>
|
||||
* Mathias Gibbens <https://calenhad.com>
|
||||
* Nick Gordon <https://github.com/gorgonical>
|
||||
* Xiaoke Jiang <http://netarchlab.tsinghua.edu.cn/~shock>
|
||||
* Marcin Juszkiewicz <https://marcin.juszkiewicz.com.pl>
|
||||
* Luca Keidel <https://lucakeidel.de>
|
||||
* Spencer Lee <https://wwsw.linkedin.com/in/spenlee>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
* Yanbiao Li <https://www.linkedin.com/pub/yanbiao-li/24/7a1/4ba>
|
||||
* Teng Liang <https://cs.arizona.edu/~philoliang>
|
||||
* Weiwei Liu <https://www.linkedin.com/in/weiweiliu10>
|
||||
* Tianxing Ma <https://github.com/matianxing1992>
|
||||
* Xingyu Ma <https://www.linkedin.com/pub/xingyu-ma/1a/384/5a8>
|
||||
* Spyridon Mastorakis <https://sites.google.com/site/spyridonmastorakis>
|
||||
* Ernest McCracken <https://github.com/emccrckn>
|
||||
* Stephen McQuistin <https://smcquistin.uk>
|
||||
* Ilya Moiseenko <https://www.linkedin.com/in/ilya-moiseenko-52884317>
|
||||
* Alex Nano <http://alexnano.net>
|
||||
* Eric Newberry <https://ericnewberry.com>
|
||||
* Arthi Padmanabhan <https://github.com/arthipadmanabhan>
|
||||
* Ju Pan <https://cs-jupan.com>
|
||||
* João Pereira <http://website.jpereira.co.uk>
|
||||
* Davide Pesavento <https://github.com/Pesa>
|
||||
* José Quevedo <http://atnog.av.it.pt/members/jquevedo>
|
||||
* Md Ashiqur Rahman <https://ashiqrahman.com>
|
||||
* Niv Sardi <http://core.evilgiggle.com>
|
||||
* Wentao Shang <https://irl.cs.ucla.edu/~wentao>
|
||||
* Susmit Shannigrahi <https://susm.it>
|
||||
* Junxiao Shi <https://cs.arizona.edu/~shijunxiao>
|
||||
* Michael Sweatt <https://www.linkedin.com/in/michaelsweatt>
|
||||
* Jiewen Tan <https://github.com/alanwaketan>
|
||||
* ***(Former Maintainer)*** Jeff Thompson <https://remap.ucla.edu/jeff-thompson>
|
||||
* Yukai Tu <https://irl.cs.ucla.edu/~yukai>
|
||||
* Yingdi Yu <https://irl.cs.ucla.edu/~yingdi>
|
||||
* Zhiyi Zhang <https://zhiyi-zhang.com>
|
||||
* Zhenkai Zhu <https://irl.cs.ucla.edu/~zhenkai>
|
||||
|
||||
## All project authors and contributors
|
||||
## Technical Advisors
|
||||
|
||||
The following is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS,
|
||||
people who have reported bugs, submitted patches, and implemented new features
|
||||
in the library:
|
||||
|
||||
* Wentao Shang <http://irl.cs.ucla.edu/~wentao/>
|
||||
* Steve DiBenedetto <http://www.cs.colostate.edu/~dibenede/>
|
||||
* Davide Pesavento <https://www.linkedin.com/in/davidepesavento>
|
||||
* Syed Obaid Amin <http://obaidamin.weebly.com/>
|
||||
* Shuo Chen <chenatu2006@gmail.com>
|
||||
* Hila Ben Abraham <http://research.engineering.wustl.edu/~abrahamh/>
|
||||
* Xingyu Ma <http://www.linkedin.com/pub/xingyu-ma/1a/384/5a8>
|
||||
* Michael Sweatt <https://www.linkedin.com/in/michaelsweatt>
|
||||
* Lixia Zhang <http://www.cs.ucla.edu/~lixia/home.html>
|
||||
* Jeff Burke <http://remap.ucla.edu/jburke/>
|
||||
* Xiaoke Jiang <http://netarchlab.tsinghua.edu.cn/~shock/>
|
||||
* Jiewen Tan <alanwake@ucla.edu>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
* Mathias Gibbens <gibmat@cs.arizona.edu>
|
||||
* Chengyu Fan <chengyu@cs.colostate.edu>
|
||||
* Qiuhan Ding <http://irl.cs.ucla.edu/~qiuhanding/>
|
||||
* Spyridon Mastorakis <http://cs.ucla.edu/~mastorakis/>
|
||||
* Eric Newberry <http://cs.arizona.edu/~enewberry/>
|
||||
* João Pereira <http://website.jpereira.co.uk>
|
||||
* Mickey Sweatt <https://www.linkedin.com/in/michaelsweatt>
|
||||
* Yanbiao Li <https://www.linkedin.com/pub/yanbiao-li/24/7a1/4ba>
|
||||
* Marcin Juszkiewicz <http://marcin.juszkiewicz.com.pl/>
|
||||
* Susmit Shannigrahi <https://www.linkedin.com/in/susmit-shannigrahi-90433b8>
|
||||
* José Quevedo <http://atnog.av.it.pt/members/jquevedo>
|
||||
* Zhiyi Zhang <http://irl.cs.ucla.edu/~zhiyi/>
|
||||
* Chavoosh Ghasemi <https://www.linkedin.com/in/chavoosh-ghasemi-421327117/>
|
||||
* Jeff Burke <https://jeff-burke.com>
|
||||
* Beichuan Zhang <https://cs.arizona.edu/~bzhang>
|
||||
* Lixia Zhang <https://cs.ucla.edu/~lixia>
|
||||
@@ -12,6 +12,9 @@ ndn-cxx relies on third-party software, licensed under the following licenses:
|
||||
- optional-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/optional-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- scope-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/scope-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- variant-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/variant-lite/blob/master/LICENSE.txt)
|
||||
|
||||
|
||||
+4
-5
@@ -2,7 +2,7 @@ Notes for ndn-cxx developers
|
||||
============================
|
||||
|
||||
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).
|
||||
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md).
|
||||
|
||||
Code style
|
||||
----------
|
||||
@@ -62,7 +62,7 @@ The simplest way to run the tests is to launch the compiled binary without any p
|
||||
|
||||
./build/unit-tests
|
||||
|
||||
[Boost.Test framework](https://www.boost.org/doc/libs/1_58_0/libs/test/doc/html/index.html)
|
||||
The [Boost.Test framework](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html)
|
||||
is very flexible and allows a number of run-time customization of what tests should be run.
|
||||
For example, it is possible to choose to run only a specific test suite, only a specific
|
||||
test case within a suite, or specific test cases within specific test suites:
|
||||
@@ -94,9 +94,8 @@ or `-p` to show a progress bar:
|
||||
./build/unit-tests -p
|
||||
|
||||
There are many more command line options available, information about which can be obtained
|
||||
either from the command line using `--help` switch, or online on
|
||||
[Boost.Test library](https://www.boost.org/doc/libs/1_58_0/libs/test/doc/html/index.html)
|
||||
website.
|
||||
either from the command line using the `--help` switch, or online on the
|
||||
[Boost.Test website](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html).
|
||||
|
||||
**Warning:** If you have customized parameters for NDN platform using `client.conf` in
|
||||
`/etc/ndn` or `/usr/local/etc/ndn` (or other `@SYSCONFDIR@/etc` if it was configured to custom
|
||||
|
||||
@@ -11,8 +11,8 @@ used by the following projects:
|
||||
* [NFD - NDN Forwarding Daemon](https://github.com/named-data/NFD)
|
||||
* [NLSR - Named-data Link-State Routing protocol](https://github.com/named-data/NLSR)
|
||||
* [ndn-tools - Essential NDN command-line tools](https://github.com/named-data/ndn-tools)
|
||||
* [repo-ng - Next generation of NDN repository](https://github.com/named-data/repo-ng)
|
||||
* [ChronoSync - Sync library for multiuser realtime applications](https://github.com/named-data/ChronoSync)
|
||||
* [repo-ng - Next generation NDN repository](https://github.com/named-data/repo-ng)
|
||||
* [ChronoSync - Sync library for multi-user real-time applications](https://github.com/named-data/ChronoSync)
|
||||
* [PSync - Partial and full synchronization library](https://github.com/named-data/PSync)
|
||||
* [ndn-traffic-generator - Traffic generator for NDN](https://github.com/named-data/ndn-traffic-generator)
|
||||
* [NAC - Name-based Access Control](https://github.com/named-data/name-based-access-control)
|
||||
@@ -31,8 +31,10 @@ Please submit any bugs or feature requests to the
|
||||
|
||||
## Contributing
|
||||
|
||||
You're encouraged to contribute to ndn-cxx! Check out the
|
||||
[Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md) to get started.
|
||||
We greatly appreciate contributions to the ndn-cxx code base.
|
||||
If you are new to the NDN software community, please read the
|
||||
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md)
|
||||
to get started.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+4
-1
@@ -6,7 +6,10 @@
|
||||
; tcp://192.0.2.1
|
||||
; tcp4://example.com:6363
|
||||
;
|
||||
transport=unix:///var/run/nfd.sock
|
||||
; The default value of this field is platform-dependent, being unix:///run/nfd.sock on Linux and
|
||||
; unix:///var/run/nfd.sock on other platforms.
|
||||
;
|
||||
;transport=unix:///var/run/nfd.sock
|
||||
|
||||
; "pib" determines which Public Info Base (PIB) should used by default in applications.
|
||||
; If "pib" is not specified, a platform-dependent default will be used.
|
||||
|
||||
+159
-132
@@ -1,142 +1,152 @@
|
||||
.. _Getting Started with ndn-cxx:
|
||||
|
||||
Getting started with ndn-cxx
|
||||
============================
|
||||
|
||||
Supported platforms
|
||||
-------------------
|
||||
|
||||
ndn-cxx uses continuous integration and has been tested on the following
|
||||
platforms:
|
||||
ndn-cxx is built against a continuous integration system and has been tested on the
|
||||
following platforms:
|
||||
|
||||
- Ubuntu 16.04 (amd64, armhf, i386)
|
||||
- Ubuntu 18.04 (amd64)
|
||||
- Ubuntu 19.10 (amd64)
|
||||
- Ubuntu 18.04 (amd64, armhf, i386)
|
||||
- Ubuntu 20.04 (amd64)
|
||||
- macOS 10.13
|
||||
- macOS 10.14
|
||||
- macOS 10.15
|
||||
- CentOS 7 (with gcc 7 and boost 1.58.0)
|
||||
- CentOS 8
|
||||
|
||||
ndn-cxx is known to work on the following platforms, although they are not officially
|
||||
supported:
|
||||
|
||||
- Debian >= 9
|
||||
- Fedora >= 24
|
||||
- Debian 10 (Buster)
|
||||
- Fedora >= 29
|
||||
- Gentoo Linux
|
||||
- Raspbian >= 2017-08-16
|
||||
- FreeBSD 11.2
|
||||
- Raspbian >= 2019-06-20 (Buster)
|
||||
- FreeBSD >= 11.3
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Required:
|
||||
~~~~~~~~~
|
||||
Required
|
||||
~~~~~~~~
|
||||
|
||||
- GCC >= 5.3, or clang >= 3.6
|
||||
- ``python2`` >= 2.7, or ``python3`` >= 3.4
|
||||
- Boost libraries >= 1.58
|
||||
- ``pkg-config``
|
||||
- SQLite 3.x
|
||||
- GCC >= 7.4 or clang >= 4.0 (on Linux and FreeBSD)
|
||||
- Xcode >= 9.0 (on macOS)
|
||||
- Python >= 3.6
|
||||
- pkg-config
|
||||
- Boost >= 1.65.1
|
||||
- OpenSSL >= 1.0.2
|
||||
- Apple Security framework (on macOS only)
|
||||
- SQLite 3.x
|
||||
|
||||
Following are the detailed steps for each platform to install the compiler, all necessary
|
||||
development tools and libraries, and ndn-cxx prerequisites.
|
||||
To build ndn-cxx from source, one must first install a C++ compiler and all necessary
|
||||
development tools and libraries:
|
||||
|
||||
- macOS
|
||||
- On **Ubuntu**
|
||||
|
||||
* Install Xcode from the App Store, or at least the Command Line Tools
|
||||
(``xcode-select --install``)
|
||||
In a terminal, enter::
|
||||
|
||||
sudo apt install g++ pkg-config python3-minimal libboost-all-dev libssl-dev libsqlite3-dev
|
||||
|
||||
- On **CentOS** and **Fedora**
|
||||
|
||||
In a terminal, enter::
|
||||
|
||||
sudo dnf install gcc-c++ pkgconf-pkg-config python3 boost-devel openssl-devel sqlite-devel
|
||||
|
||||
- On **macOS**
|
||||
|
||||
* Install either Xcode (from the App Store) or the Command Line Tools
|
||||
(with ``xcode-select --install``)
|
||||
|
||||
* If using Homebrew (recommended), enter the following in a terminal::
|
||||
|
||||
brew install boost openssl pkg-config
|
||||
|
||||
.. note::
|
||||
.. warning::
|
||||
|
||||
If a major OS upgrade is performed after installing the dependencies
|
||||
with Homebrew, remember to reinstall all packages.
|
||||
|
||||
- Ubuntu
|
||||
- On **FreeBSD**
|
||||
|
||||
In a terminal, enter::
|
||||
|
||||
sudo apt install build-essential libboost-all-dev libssl-dev libsqlite3-dev pkg-config python-minimal
|
||||
sudo pkg install pkgconf python3 boost-libs openssl sqlite3
|
||||
|
||||
- Fedora
|
||||
Optional
|
||||
~~~~~~~~
|
||||
|
||||
In a terminal, enter::
|
||||
To build tutorials, manpages, and API documentation the following additional dependencies
|
||||
need to be installed:
|
||||
|
||||
sudo yum install gcc-g++ sqlite-devel boost-devel openssl-devel
|
||||
- doxygen
|
||||
- graphviz
|
||||
- sphinx >= 1.3
|
||||
- sphinxcontrib-doxylink
|
||||
|
||||
- FreeBSD
|
||||
The following lists the steps to install these prerequisites on various common platforms.
|
||||
|
||||
In a terminal, enter::
|
||||
- On **Ubuntu**:
|
||||
|
||||
sudo pkg install python pkgconf sqlite3 boost-libs
|
||||
|
||||
Optional:
|
||||
~~~~~~~~~
|
||||
|
||||
To build tutorials, manpages, and API documentation the following
|
||||
dependencies need to be installed:
|
||||
|
||||
- ``doxygen``
|
||||
- ``graphviz``
|
||||
- ``python-sphinx``
|
||||
- ``sphinxcontrib-doxylink``
|
||||
|
||||
The following lists steps for common platforms to install these prerequisites:
|
||||
|
||||
- On macOS with Homebrew and pip::
|
||||
|
||||
brew install doxygen graphviz
|
||||
sudo pip install sphinx sphinxcontrib-doxylink
|
||||
|
||||
- On Ubuntu::
|
||||
.. code-block:: sh
|
||||
|
||||
sudo apt install doxygen graphviz python3-pip
|
||||
sudo pip3 install sphinx sphinxcontrib-doxylink
|
||||
|
||||
- On Fedora::
|
||||
- On **CentOS** and **Fedora**:
|
||||
|
||||
sudo yum install doxygen graphviz python-sphinx
|
||||
sudo pip install sphinxcontrib-doxylink
|
||||
.. code-block:: sh
|
||||
|
||||
- On FreeBSD::
|
||||
sudo dnf config-manager --enable PowerTools # on CentOS only
|
||||
sudo dnf install doxygen graphviz python3-pip
|
||||
pip3 install --user sphinx sphinxcontrib-doxylink
|
||||
|
||||
sudo pkg install doxygen graphviz py27-sphinx
|
||||
- On **macOS**:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
.. _build:
|
||||
brew install doxygen graphviz
|
||||
sudo pip install sphinx sphinxcontrib-doxylink
|
||||
|
||||
- On **FreeBSD**:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo pkg install doxygen graphviz py37-sphinx
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
.. note::
|
||||
These are instructions for regular builds of ndn-cxx (release mode).
|
||||
To do development of ndn-cxx code itself, see "Development build" below.
|
||||
These are instructions for regular builds of ndn-cxx (release mode). If you are
|
||||
planning to develop the ndn-cxx code itself, you should do a :ref:`Development build`.
|
||||
|
||||
To build in a terminal, change directory to the ndn-cxx root, then enter::
|
||||
To build in a terminal, change directory to the ndn-cxx root, then enter:
|
||||
|
||||
./waf configure
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure # on CentOS, add --without-pch
|
||||
./waf
|
||||
sudo ./waf install
|
||||
|
||||
By default, only the shared version of ndn-cxx library is built. To build the static library,
|
||||
use ``--enable-static`` option for ``./waf configure`` command::
|
||||
By default, only the shared variant of the ndn-cxx library will be built. To build the
|
||||
static library, pass ``--enable-static`` to the ``./waf configure`` command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure --enable-static
|
||||
|
||||
To disable build of the shared library and build only the static library, use additional
|
||||
``--disable-shared`` option. Note that at least one version of the library needs to be
|
||||
enabled.
|
||||
To disable the build of the shared library and build only the static library, use the
|
||||
additional ``--disable-shared`` option. Note that at least one variant of the library
|
||||
needs to be enabled.
|
||||
|
||||
::
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure --enable-static --disable-shared
|
||||
|
||||
After the shared library is installed, on Linux it is also necessary to run::
|
||||
On Linux, it is necessary to run the following command after the shared library has
|
||||
been installed:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo ldconfig
|
||||
|
||||
@@ -146,12 +156,16 @@ After the shared library is installed, on Linux it is also necessary to run::
|
||||
additional actions may be necessary.
|
||||
|
||||
The installation path should be added to ``/etc/ld.so.conf`` (or in
|
||||
``/etc/ld.so.conf.d``) **before** running ``sudo ldconfig``. For example::
|
||||
``/etc/ld.so.conf.d``) **before** running ``sudo ldconfig``. For example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
echo /usr/local/lib | sudo tee /etc/ld.so.conf.d/ndn-cxx.conf
|
||||
|
||||
Alternatively, the ``LD_LIBRARY_PATH`` environment variable can be set to point to
|
||||
the installation directory of the shared library::
|
||||
the installation directory of the shared library:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
@@ -161,38 +175,41 @@ The ``./waf install`` command installs the following files:
|
||||
- ``<LIBPATH>/libndn-cxx.so``, ``<LIBPATH>/libndn-cxx.so.<VERSION>`` (on Linux),
|
||||
``<LIBPATH>/libndn-cxx.dylib``, ``<LIBPATH>/libndn-cxx.<VERSION>.dylib`` (on macOS):
|
||||
shared NDN C++ library (if enabled).
|
||||
- ``<LIBPATH>/pkgconfig/libndn-cxx.pc``: pkgconfig file storing all
|
||||
neccessary flags to build against the library. For example, if
|
||||
pkg-config or pkgconf package is installed and ``PKG_CONFIG_PATH`` is
|
||||
configured properly (or ``<LIBPATH>/pkgconfig`` is a default path),
|
||||
``pkgconfig --libs --clflags libndn-cxx`` will return all necessary
|
||||
compile and link flags for the library.
|
||||
- ``<LIBPATH>/pkgconfig/libndn-cxx.pc``: pkgconfig file storing all necessary flags to
|
||||
build against the library. For example, if the ``pkg-config`` or ``pkgconf-pkg-config``
|
||||
package is installed and ``PKG_CONFIG_PATH`` is configured properly (or if
|
||||
``<LIBPATH>/pkgconfig`` is a default search path), the command ``pkg-config --cflags
|
||||
--libs libndn-cxx`` will return all necessary compile and link flags for the library.
|
||||
- ``<BINPATH>/ndnsec``: tool to manage NDN keys and certificates.
|
||||
- ``<BINPATH>/ndnsec-*``: convenience aliases for ``ndnsec`` tools.
|
||||
|
||||
If configured with tests (``./waf configure --with-tests``), the above
|
||||
commands will also produce:
|
||||
If configured with tests (``./waf configure --with-tests``), the above commands
|
||||
will also produce:
|
||||
|
||||
- ``build/unit-tests``: a unit test binary for the library.
|
||||
|
||||
1.5GB available memory per CPU core is necessary for efficient compilation.
|
||||
On a multi-core machine with less than 1.5GB available memory per CPU core,
|
||||
limit the objects being compiled in parallel with ``./waf -jN`` where N is the amount
|
||||
of available memory divided by 1.5GB (eg. ``./waf -j1`` for 1.5GB memory),
|
||||
which should usually avoid memory thrashing and result in faster compilation.
|
||||
1.5 GB available memory per CPU core is necessary for efficient compilation. On a
|
||||
multi-core machine with less than 1.5 GB available memory per CPU core, limit the
|
||||
objects being compiled in parallel with ``./waf -jN``, where N is the amount of
|
||||
available memory divided by 1.5 GB (e.g., ``./waf -j2`` for 3 GB of memory). This
|
||||
should avoid memory thrashing and result in faster compilation.
|
||||
|
||||
Build with examples
|
||||
-------------------
|
||||
|
||||
By default, examples in ``examples/`` are not built. To enable them, use the
|
||||
``--with-examples`` configure option::
|
||||
By default, the examples in the ``examples/`` directory will not be built. To enable
|
||||
them, pass ``--with-examples`` during the configuration step:
|
||||
|
||||
./waf configure --with-examples
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure --with-examples # on CentOS, add --without-pch
|
||||
./waf
|
||||
sudo ./waf install
|
||||
sudo ldconfig # (on Linux only)
|
||||
sudo ldconfig # on Linux only
|
||||
|
||||
To run examples::
|
||||
To run the examples:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# trivial producer app
|
||||
./build/examples/producer
|
||||
@@ -203,79 +220,89 @@ To run examples::
|
||||
# trivial consumer app with timers
|
||||
./build/examples/consumer-with-timer
|
||||
|
||||
If you want to test out a sample application, just create a ``.cpp`` file in ``examples/``
|
||||
folder and it will be compiled on the next run on ``./waf``. For example::
|
||||
If you want to make a new sample application, just create a ``.cpp`` file inside the
|
||||
``examples/`` directory and it will be compiled during the next run of ``./waf``:
|
||||
|
||||
cp examples/consumer.cpp examples/my-new-consumer-app.cpp
|
||||
.. code-block:: sh
|
||||
|
||||
cp examples/consumer.cpp examples/my-new-app.cpp
|
||||
... # edit examples/my-new-app.cpp with your preferred editor
|
||||
./waf
|
||||
sudo ./waf install
|
||||
sudo ldconfig # (on Linux only)
|
||||
./build/examples/my-new-consumer-app
|
||||
sudo ldconfig # on Linux only
|
||||
./build/examples/my-new-app
|
||||
|
||||
Debug symbols
|
||||
~~~~~~~~~~~~~
|
||||
-------------
|
||||
|
||||
The default compiler flags enable debug symbols to be included in binaries (i.e., ``-g``
|
||||
flag for ``./waf configure`` and ``-g3`` for ``./waf configure --debug``). This
|
||||
potentially allows more meaningful debugging information if your application crashes.
|
||||
The default compiler flags include debug symbols in binaries. This should provide
|
||||
more meaningful debugging information if ndn-cxx or your application crashes.
|
||||
|
||||
The default build flags can easily be overridden::
|
||||
If this is not desired, the default flags can be overridden to disable debug symbols.
|
||||
The following example shows how to completely disable debug symbols and configure
|
||||
ndn-cxx to be installed into ``/usr`` with configuration in the ``/etc`` directory.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
CXXFLAGS="-O2" ./waf configure --prefix=/usr --sysconfdir=/etc
|
||||
./waf
|
||||
sudo ./waf install
|
||||
|
||||
Customizing the compiler
|
||||
------------------------
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
To build ndn-cxx with a different compiler (rather than the platform default), set the
|
||||
``CXX`` environment variable to point to the compiler binary. For example, to build
|
||||
with clang on Linux, use the following:
|
||||
|
||||
ndn-cxx tutorials and API documentation can be built using the following
|
||||
commands::
|
||||
.. code-block:: sh
|
||||
|
||||
CXX=clang++ ./waf configure
|
||||
|
||||
Building the documentation
|
||||
--------------------------
|
||||
|
||||
Tutorials and API documentation can be built using the following commands:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# Full set of documentation (tutorials + API) in build/docs
|
||||
./waf docs
|
||||
|
||||
# Only tutorials in `build/docs`
|
||||
# Only tutorials in build/docs
|
||||
./waf sphinx
|
||||
|
||||
# Only API docs in `build/docs/doxygen`
|
||||
# Only API docs in build/docs/doxygen
|
||||
./waf doxygen
|
||||
|
||||
Manpages are automatically created and installed during the normal build
|
||||
process (e.g., during ``./waf`` and ``./waf install``), if
|
||||
``python-sphinx`` module is detected during ``./waf configure`` stage.
|
||||
By default, manpages are installed into ``${PREFIX}/share/man`` (where
|
||||
default value for ``PREFIX`` is ``/usr/local``). This location can be
|
||||
changed during ``./waf configure`` stage using ``--prefix``,
|
||||
``--datarootdir``, or ``--mandir`` options.
|
||||
If ``sphinx-build`` is detected during ``./waf configure``, manpages will automatically
|
||||
be built and installed during the normal build process (i.e., during ``./waf`` and
|
||||
``./waf install``). By default, manpages will be installed into ``${PREFIX}/share/man``
|
||||
(the default value for ``PREFIX`` is ``/usr/local``). This location can be changed
|
||||
during the ``./waf configure`` stage using the ``--prefix``, ``--datarootdir``, or
|
||||
``--mandir`` options.
|
||||
|
||||
For more details, refer to ``./waf --help``.
|
||||
For further details, please refer to ``./waf --help``.
|
||||
|
||||
.. _Development build:
|
||||
|
||||
Development build
|
||||
-----------------
|
||||
|
||||
The following is the suggested configure command for development builds::
|
||||
The following is the suggested build procedure for development builds:
|
||||
|
||||
./waf configure --debug --with-tests
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure --debug --with-tests # on CentOS, add --without-pch
|
||||
./waf
|
||||
sudo ./waf install
|
||||
sudo ldconfig # (on Linux only)
|
||||
sudo ldconfig # on Linux only
|
||||
|
||||
In the development build most compiler optimizations are disabled by
|
||||
default and all warnings are treated as errors. The default behavior can
|
||||
be overridden by setting ``CXXFLAGS`` environment variable before
|
||||
running ``./waf configure``::
|
||||
In a development build, most compiler optimizations will be disabled and all warnings
|
||||
will be treated as errors. This default behavior can be overridden by setting the
|
||||
``CXXFLAGS`` environment variable before running ``./waf configure``, for example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
CXXFLAGS="-O1 -g3" ./waf configure --debug --with-tests
|
||||
...
|
||||
|
||||
|
||||
Customizing the compiler
|
||||
------------------------
|
||||
|
||||
To choose a custom C++ compiler for building ndn-cxx, set the ``CXX`` environment
|
||||
variable to point to the compiler binary. For example, to build with clang on
|
||||
Linux, use the following::
|
||||
|
||||
CXX=clang++ ./waf configure
|
||||
+1
-1
@@ -7,7 +7,7 @@ Based on
|
||||
The original document is available at `<http://geosoft.no/development/cppstyle.html>`_
|
||||
|
||||
* NDN Platform "C++, C, C#, Java and JavaScript Code Guidelines".
|
||||
The original document available at `<http://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`_
|
||||
The original document available at `<https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`_
|
||||
|
||||
1. Code layout
|
||||
--------------
|
||||
|
||||
+14
-19
@@ -1,10 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
@@ -12,7 +10,7 @@
|
||||
# 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.
|
||||
#
|
||||
import os
|
||||
# import os
|
||||
import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
@@ -20,13 +18,13 @@ import sys
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = u'ndn-cxx: NDN C++ library with eXperimental eXtensions'
|
||||
copyright = u'Copyright © 2013-2019 Regents of the University of California.'
|
||||
copyright = u'Copyright © 2013-2020 Regents of the University of California.'
|
||||
author = u'Named Data Networking Project'
|
||||
|
||||
# The short X.Y version
|
||||
# The short X.Y version.
|
||||
#version = ''
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
#release = ''
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
@@ -40,7 +38,7 @@ today_fmt = '%Y-%m-%d'
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
needs_sphinx = '1.1'
|
||||
needs_sphinx = '1.3'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@@ -58,12 +56,7 @@ def addExtensionIfExists(extension):
|
||||
sys.stderr.write("Extension '%s' not found. "
|
||||
"Some documentation may not build correctly.\n" % extension)
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
addExtensionIfExists('sphinxcontrib.doxylink')
|
||||
|
||||
# sphinxcontrib.googleanalytics is currently not working with the latest version of Sphinx
|
||||
# if os.getenv('GOOGLE_ANALYTICS', None):
|
||||
# addExtensionIfExists('sphinxcontrib.googleanalytics')
|
||||
addExtensionIfExists('sphinxcontrib.doxylink')
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
@@ -92,6 +85,12 @@ html_theme_path = ['.']
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
html_copy_source = False
|
||||
html_show_sourcelink = False
|
||||
|
||||
# Disable syntax highlighting of code blocks by default.
|
||||
highlight_language = 'none'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
|
||||
@@ -140,7 +139,7 @@ man_pages = [
|
||||
('manpages/ndnsec-set-default', 'ndnsec-set-default', 'change the default NDN identity, key, or certificate for the current user', None, 1),
|
||||
('manpages/ndnsec-sign-req', 'ndnsec-sign-req', 'generate an NDN certificate signing request', None, 1),
|
||||
('manpages/ndnsec-unlock-tpm', 'ndnsec-unlock-tpm', 'unlock the TPM', None, 1),
|
||||
('manpages/ndn-client.conf', 'ndn-client.conf', 'configuration file for NDN platform', None, 5),
|
||||
('manpages/ndn-client.conf', 'ndn-client.conf', 'configuration file for NDN applications', None, 5),
|
||||
('manpages/ndn-log', 'ndn-log', 'ndn-cxx logging', None, 7),
|
||||
]
|
||||
|
||||
@@ -157,7 +156,3 @@ doxylink = {
|
||||
extlinks = {
|
||||
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #'),
|
||||
}
|
||||
|
||||
if os.getenv('GOOGLE_ANALYTICS', None):
|
||||
googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
|
||||
googleanalytics_enabled = True
|
||||
+1
-16
@@ -836,7 +836,7 @@ EXCLUDE_SYMLINKS = NO
|
||||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories for example use the pattern */test/*
|
||||
|
||||
EXCLUDE_PATTERNS = */ndn-cxx/impl/* */ndn-cxx/*/impl/*
|
||||
EXCLUDE_PATTERNS = */ndn-cxx/impl/* */ndn-cxx/*/impl/* */ndn-cxx/util/nonstd/*
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
@@ -2128,12 +2128,6 @@ 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
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2147,15 +2141,6 @@ PERL_PATH = /usr/bin/perl
|
||||
|
||||
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 =
|
||||
|
||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||
# then run dia to produce the diagram and insert it in the documentation. The
|
||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||
|
||||
+9
-12
@@ -5,7 +5,7 @@ Trivial applications
|
||||
|
||||
To successfully run the following examples, please make sure that NFD is properly
|
||||
configured and running. For more information about NFD, refer to `NFD's official
|
||||
homepage <http://named-data.net/doc/NFD/>`_.
|
||||
homepage <https://named-data.net/doc/NFD/>`_.
|
||||
|
||||
Trivial consumer
|
||||
----------------
|
||||
@@ -18,8 +18,7 @@ callbacks to be called when Data/Nack is retrieved or Interest times out.
|
||||
.. literalinclude:: ../examples/consumer.cpp
|
||||
:language: c++
|
||||
:linenos:
|
||||
:emphasize-lines: 24-27,39,43-47,51,58,75
|
||||
|
||||
:emphasize-lines: 39-45,48,59,65,71
|
||||
|
||||
Trivial producer
|
||||
----------------
|
||||
@@ -42,8 +41,7 @@ using :ndn-cxx:`Face::put` method.
|
||||
.. literalinclude:: ../examples/producer.cpp
|
||||
:language: c++
|
||||
:linenos:
|
||||
:emphasize-lines: 42,55-58,61,64,67,70,76
|
||||
|
||||
:emphasize-lines: 41,50,57-59,62,70,74
|
||||
|
||||
Consumer that uses Scheduler
|
||||
----------------------------
|
||||
@@ -52,19 +50,18 @@ The following example demonstrates how to use :ndn-cxx:`Scheduler` to schedule a
|
||||
events for execution at specific points of time.
|
||||
|
||||
The library internally uses `boost::asio::io_service
|
||||
<https://www.boost.org/doc/libs/1_58_0/doc/html/boost_asio/reference/io_service.html>`_ to
|
||||
<https://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/io_service.html>`_ to
|
||||
implement fully asynchronous NDN operations (i.e., sending and receiving Interests and
|
||||
Data). In addition to network-related operations, ``boost::asio::io_service`` can be used
|
||||
to execute any arbitrary callback within the processing thread (run either explicitly via
|
||||
``io.run`` or implicitly via :ndn-cxx:`Face::processEvents` as in previous examples).
|
||||
:ndn-cxx:`Scheduler` is just a wrapper on top of ``boost::asio::io_service``,
|
||||
allowing simple interface to schedule tasks at specific times.
|
||||
``io_service::run()`` or implicitly via :ndn-cxx:`Face::processEvents` as in previous
|
||||
examples). :ndn-cxx:`Scheduler` is just a wrapper on top of ``io_service``, providing a
|
||||
simple interface to schedule tasks at specific times.
|
||||
|
||||
The highlighted lines in the example demonstrate all that is needed to express a second
|
||||
Interest approximately 2 seconds after the first one.
|
||||
Interest approximately 3 seconds after the first one.
|
||||
|
||||
.. literalinclude:: ../examples/consumer-with-timer.cpp
|
||||
:language: c++
|
||||
:linenos:
|
||||
:emphasize-lines: 39-40,51-55,59-60,62-63,108-109
|
||||
|
||||
:emphasize-lines: 39-40,56,62,93,106,114-116
|
||||
+3
-8
@@ -40,13 +40,10 @@ ndn-cxx Documentation
|
||||
releases
|
||||
|
||||
- :doc:`INSTALL`
|
||||
|
||||
- :doc:`examples`
|
||||
|
||||
- :doc:`tutorials`
|
||||
|
||||
+ `NDN Software Contributor's Guide <https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md>`_ (guide for newcomers to the NDN community of software generally)
|
||||
|
||||
+ `NDN Software Contributor's Guide <https://github.com/named-data/.github/blob/master/CONTRIBUTING.md>`_ (guide for newcomers to the NDN community of software generally)
|
||||
+ :doc:`tutorials/utils-ndn-regex`
|
||||
+ :doc:`tutorials/security-validator-config`
|
||||
|
||||
@@ -59,14 +56,12 @@ ndn-cxx Documentation
|
||||
|
||||
- :doc:`manpages`
|
||||
|
||||
**Additional documentation**
|
||||
Additional Documentation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- `API documentation (doxygen) <doxygen/annotated.html>`_
|
||||
|
||||
- :doc:`code-style`
|
||||
|
||||
- :doc:`RELEASE_NOTES`
|
||||
|
||||
- :doc:`releases`
|
||||
|
||||
License
|
||||
|
||||
@@ -6,23 +6,25 @@ System configuration of NDN platform is specified in ``client.conf``.
|
||||
The configuration file ``client.conf`` is looked up in several directories in the following order:
|
||||
|
||||
- ``$HOME/.ndn``: user-specific settings
|
||||
- ``@SYSCONFDIR@/ndn`` (``/usr/local/etc/ndn``, ``/opt/local/etc/ndn``, or other, depending how the
|
||||
library is configured): system-wide settings
|
||||
- ``SYSCONFDIR/ndn``: system-wide settings (where ``SYSCONFDIR`` can be ``/usr/local/etc``,
|
||||
``/opt/local/etc``, or other, depending on how the library is configured)
|
||||
- ``/etc/ndn``: default system-wide settings
|
||||
|
||||
Here is an example of ``client.conf`` for current ndn-cxx package:
|
||||
Here is an example of ``client.conf`` for the current ndn-cxx package:
|
||||
|
||||
.. literalinclude:: ../../client.conf.sample
|
||||
:language: ini
|
||||
|
||||
|
||||
NFD
|
||||
---
|
||||
|
||||
transport
|
||||
FaceUri for default connection toward local NDN forwarder. Only ``unix`` and ``tcp4`` FaceUris
|
||||
can be specified here.
|
||||
FaceUri for default connection toward local NDN forwarder. Only ``unix``, ``tcp``, ``tcp4``, and
|
||||
``tcp6`` FaceUris can be specified here.
|
||||
|
||||
By default, ``unix:///var/run/nfd.sock`` is used.
|
||||
By default, ``unix:///run/nfd.sock`` is used on Linux and ``unix:///var/run/nfd.sock`` is used on
|
||||
other platforms.
|
||||
|
||||
.. note::
|
||||
This value can be overridden using the ``NDN_CLIENT_TRANSPORT`` environment variable.
|
||||
|
||||
+36
-19
@@ -18,6 +18,11 @@ distinguishing prefixes (``ndn.``, ``sync.``, etc.), which can be specified when
|
||||
setting the environment variable. Wildcards can be used to enable logging for all
|
||||
modules (just ``*``) or all modules under a selected prefix (e.g., ``ndn.*``).
|
||||
|
||||
If an additional environment variable ``NDN_LOG_NOFLUSH`` is set, the automatic flushing
|
||||
after each log record will be disabled. This can improve logging performance but may
|
||||
cause the log records to appear delayed or, in case of application crash, the last
|
||||
few log records may be lost.
|
||||
|
||||
ndn-cxx logging facility provides a mechanism to manage the type of log messages
|
||||
that are written by classifying log messages by severity levels. Listed below
|
||||
are the available log levels.
|
||||
@@ -41,11 +46,13 @@ written.
|
||||
Setting NDN_LOG requires the following syntax with as many prefixes and
|
||||
corresponding loglevels as the user desires:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
export NDN_LOG="<prefix1>=<loglevel1>:<prefix2>=<loglevel2>"
|
||||
|
||||
**Examples:**
|
||||
*Example:*
|
||||
|
||||
::
|
||||
.. code-block:: sh
|
||||
|
||||
export NDN_LOG="ndn.*=DEBUG"
|
||||
export NDN_LOG="ndn.UnixTransport=INFO"
|
||||
@@ -54,30 +61,40 @@ corresponding loglevels as the user desires:
|
||||
|
||||
**Note:**
|
||||
|
||||
Shorter (general) prefixes should be placed before longer (specific) prefixes.
|
||||
Otherwise, the specific prefix's loglevel will be overwritten. For example,
|
||||
`export NDN_LOG="ndn.UnixTransport=TRACE:ndn.*=ERROR:*=INFO"` sets all modules
|
||||
to INFO; it should be written as
|
||||
`export NDN_LOG="*=INFO:ndn.*=ERROR:ndn.UnixTransport=TRACE"` for the desired effect.
|
||||
The loglevel assignments in ``NDN_LOG`` are processed left-to-right. Thus, shorter
|
||||
(more general) prefixes should be listed before longer (more specific) prefixes.
|
||||
Otherwise, the loglevel setting of a more specific prefix may be overwritten by a
|
||||
more general assignment appearing later in the string. For example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
export NDN_LOG="ndn.UnixTransport=TRACE:ndn.*=ERROR:*=INFO"
|
||||
|
||||
will set all modules to INFO. To obtain the desired effect, it should instead be
|
||||
written as:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
export NDN_LOG="*=INFO:ndn.*=ERROR:ndn.UnixTransport=TRACE"
|
||||
|
||||
**Note:**
|
||||
|
||||
Setting the environment variable with sudo requires the application to be run
|
||||
in the same command.
|
||||
|
||||
::
|
||||
.. code-block:: sh
|
||||
|
||||
Correct:
|
||||
# Correct
|
||||
sudo env NDN_LOG=logLevel ./ndn-application
|
||||
|
||||
sudo env NDN_LOG=logLevel ./ndn-application
|
||||
# Also correct
|
||||
sudo -s
|
||||
export NDN_LOG=logLevel
|
||||
./ndn-application
|
||||
|
||||
sudo -s
|
||||
export NDN_LOG=logLevel
|
||||
./ndn-application
|
||||
# Incorrect
|
||||
sudo export NDN_LOG=logLevel
|
||||
sudo ./ndn-application
|
||||
|
||||
Incorrect:
|
||||
|
||||
sudo export NDN_LOG=logLevel
|
||||
sudo ./ndn-application
|
||||
|
||||
NDN_LOG=logLevel sudo ./ndn-application
|
||||
# Incorrect
|
||||
NDN_LOG=logLevel sudo ./ndn-application
|
||||
@@ -37,9 +37,14 @@ Options
|
||||
|
||||
.. option:: -I <info>, --info <info>
|
||||
|
||||
Other information to be included in the issued certificate. For example::
|
||||
Other information to be included in the issued certificate. Must be in the
|
||||
form of key and value pairs, where the key is an arbitrary string without
|
||||
spaces, followed by one or more spaces, followed by an arbitrary string
|
||||
representing the value. This option may be repeated multiple times.
|
||||
|
||||
-I "affiliation Some Organization" -I "homepage http://home.page/"
|
||||
For example::
|
||||
|
||||
-I "affiliation Some Organization" -I "homepage https://home.page/"
|
||||
|
||||
.. option:: -s <signer>, --sign-id <signer>
|
||||
|
||||
@@ -57,21 +62,30 @@ Example
|
||||
|
||||
::
|
||||
|
||||
$ ndnsec-cert-gen -S 20140401000000 -E 20150331235959 -N "David"
|
||||
-I "2.5.4.10 'Some Organization'" -s /ndn/test request.cert
|
||||
Bv0C9wc9CANuZG4IBHRlc3QIA0tFWQgFZGF2aWQIEWtzay0xMzk2OTEzMDU4MTk2
|
||||
CAdJRC1DRVJUCAgAAAFFPp2g3hQDGAECFf0BdjCCAXIwIhgPMjAxNDA0MDEwMDAw
|
||||
MDBaGA8yMDE1MDMzMTIzNTk1OVowKDAMBgNVBCkTBURhdmlkMBgGA1UEChMRU29t
|
||||
ZSBPcmdhbml6YXRpb24wggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQC0
|
||||
urnS2nKcnXnMTESH2XqO+H8c6bCE6mmv+FMQ9hSfZVOHbX4kkiDmkcAAf8NCvwGr
|
||||
kEat0NQIhKHFLFtofC5rXLheAo/UxgFA/9bNwiEjMH/c8EN2YTSMzdCDrK6TwE7B
|
||||
623cLTsa3Bb11+BpzC1oLb3Egedgp+vIf+AFIgNQhvfwzsgsgOBB4iJBwcYegU7w
|
||||
JsO0pjY69WQU2DGjABFef6C2Qh8x0TvtnynRLbWlh928+4ilVUvLuWcV3AbPIKLe
|
||||
eZu13+v01JN6kFzNZDPMFtOFPvJ943IdYu7Q9k93PzhSk0+wFp3cHH21PfWeghWe
|
||||
3zLIER8RTWPIQhWSbxRVAgERFjMbAQEcLgcsCANuZG4IA0tFWQgEdGVzdAgRa3Nr
|
||||
LTEzOTQxMjk2OTQ3ODgIB0lELUNFUlQX/QEABUGcl7U+F8cwMHKckerv+1H2Nvsd
|
||||
OfeqX0+4RzWU+wRx2emMGMZZdHSx8M/i45hb0P5hbNEF99L35/SrSTSzhTZdOriD
|
||||
t/LQOcKBoNXY+iw3EUFM0gvRGU0kaEVBKAHtbYhtoHc48QLEyrsVaMqmrjCmpeF/
|
||||
JOcClhzJfFW3cZ/SlhcTEayF0ntogYLR2cMzIwQhhSj5L/Kl7I7uxNxZhK1DS98n
|
||||
q8oGAxHufEAluPrRpDQfI+jeQ4h/YYKcXPW3Vn7VQAGOqIi6gTlUxrmEbyCDF70E
|
||||
xj5t3wfSUmDa1N+hLRMdEAI+IjRRHDSx2Lhj/QcoPIZPWwKjBz9CBL92og==
|
||||
$ ndnsec-cert-gen -S 20200501000000 -E 20210101000000 -I "affiliation Some Organization" -I "foobar Foo Bar" -i "Universe" -s /ndn/test request.cert > signed.cert
|
||||
|
||||
$ cat signed.cert
|
||||
Bv0BcgctCAdleGFtcGxlCANLRVkICOQUmX8oloLrCAhVbml2ZXJzZQgJ/QAAAXHR
|
||||
Ak6CFAkYAQIZBAA27oAVWzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDpJsCkv
|
||||
E5RMjxRVdyK6W6z+FoCq+qREEn/sxf+n2gnsl25qm1NarCfSGf96zIJy9BRA9btu
|
||||
MMeuWlAN/ymvMFwWkBsBAxwcBxoIA25kbggEdGVzdAgDS0VZCAhJP1OaKLualf0A
|
||||
/Sb9AP4PMjAyMDA1MDFUMDAwMDAw/QD/DzIwMjEwMTAxVDAwMDAwMP0BAkH9AgAk
|
||||
/QIBC2FmZmlsaWF0aW9u/QICEVNvbWUgT3JnYW5pemF0aW9u/QIAFf0CAQZmb29i
|
||||
YXL9AgIHRm9vIEJhchdHMEUCIQDPT9Hq1kvkE0r9W1aYSBVTnHlTEzgtz+v1DwkC
|
||||
ug/vLAIgY3xJITCwf55sqey33q5GIQSk1TRCkNNl58ojvPs5sNU=
|
||||
|
||||
$ ndnsec-dump-certificate -p -f signed.cert
|
||||
Certificate name:
|
||||
/example/KEY/%E4%14%99%7F%28%96%82%EB/Universe/%FD%00%00%01q%D1%02N%82
|
||||
Validity:
|
||||
NotBefore: 20200501T000000
|
||||
NotAfter: 20210101T000000
|
||||
Additional Description:
|
||||
affiliation: Some Organization
|
||||
foobar: Foo Bar
|
||||
Public key bits:
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOkmwKS8TlEyPFFV3IrpbrP4WgKr6
|
||||
pEQSf+zF/6faCeyXbmqbU1qsJ9IZ/3rMgnL0FED1u24wx65aUA3/Ka8wXA==
|
||||
Signature Information:
|
||||
Signature Type: SignatureSha256WithEcdsa
|
||||
Key Locator: Name=/ndn/test/KEY/I%3FS%9A%28%BB%9A%95
|
||||
@@ -4,18 +4,32 @@ ndnsec-export
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
**ndnsec-export** [**-h**] [**-o** *file*] [**-P** *passphrase*] *identity*
|
||||
**ndnsec-export** [**-h**] [**-o** *file*] [**-P** *passphrase*]
|
||||
[**-i**\|\ **-k**\|\ **-c**] *name*
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
:program:`ndnsec-export` exports the default certificate of *identity* and its
|
||||
private key to a file. It will ask for a passphrase to encrypt the private key.
|
||||
:program:`ndnsec-export` exports a certificate from the **Public Info Base (PIB)** and
|
||||
its private key to a file. It will ask for a passphrase to encrypt the private key.
|
||||
The resulting file can be imported again using :program:`ndnsec-import`.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
.. option:: -i, --identity
|
||||
|
||||
Interpret *name* as an identity name. The default certificate of the identity will be exported.
|
||||
This is the default unless **-k** or **-c** is specified.
|
||||
|
||||
.. option:: -k, --key
|
||||
|
||||
Interpret *name* as a key name. The default certificate of the key will be exported.
|
||||
|
||||
.. option:: -c, --cert
|
||||
|
||||
Interpret *name* as a certificate name.
|
||||
|
||||
.. option:: -o <file>, --output <file>
|
||||
|
||||
Write to the specified output file instead of the standard output.
|
||||
@@ -34,6 +48,6 @@ Export an identity's default certificate and private key into a file::
|
||||
|
||||
$ ndnsec-export -o alice.ndnkey /ndn/test/alice
|
||||
|
||||
Export an identity's default certificate and private key to the standard output::
|
||||
Export a specific certificate and its private key to the standard output::
|
||||
|
||||
$ ndnsec-export /ndn/test/alice
|
||||
$ ndnsec-export -c /ndn/edu/ucla/alice/KEY/1%5D%A7g%90%B2%CF%AA/self/%FD%00%00%01r-%D3%DC%2A
|
||||
@@ -4,7 +4,8 @@ ndnsec-key-gen
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
**ndnsec-key-gen** [**-h**] [**-n**] [**-t** *type*] [**-k** *keyidtype*] *identity*
|
||||
**ndnsec-key-gen** [**-h**] [**-n**] [**-t** *type*]
|
||||
[**-k** *keyidtype*\|\ **--keyid** *keyid*] *identity*
|
||||
|
||||
Description
|
||||
-----------
|
||||
@@ -28,12 +29,16 @@ Options
|
||||
|
||||
.. option:: -t <type>, --type <type>
|
||||
|
||||
Type of key to generate. "r" for RSA (default), "e" for ECDSA.
|
||||
Type of key to generate. "r" for RSA, "e" for ECDSA (the default).
|
||||
|
||||
.. option:: -k <keyidtype>, --keyid-type <keyidtype>
|
||||
|
||||
Type of KeyId for the generated key. "r" for 64-bit random number (default),
|
||||
"h" for SHA256 of the public key.
|
||||
Type of KeyId for the generated key. "r" for a 64-bit random number (the default
|
||||
unless **--keyid** is specified), "h" for the SHA-256 of the public key.
|
||||
|
||||
.. option:: --keyid <keyid>
|
||||
|
||||
User-specified KeyId. Must be a non-empty generic name component.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
@@ -1,86 +1,45 @@
|
||||
{#
|
||||
named_data_theme/layout.html
|
||||
~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#}
|
||||
{% extends "basic/layout.html" %}
|
||||
{%- extends "agogo/layout.html" %}
|
||||
|
||||
{% block header %}
|
||||
<!--headercontainer-->
|
||||
<div id="header_container">
|
||||
|
||||
<!--header-->
|
||||
<div class="row">
|
||||
<div class="three columns">
|
||||
<div id="logo">
|
||||
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
|
||||
</div><!--logo end-->
|
||||
</div>
|
||||
|
||||
<!--top menu-->
|
||||
<div class="nine columns" id="menu_container" >
|
||||
<h1><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a></h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="three columns">
|
||||
<p class="logo"><a href="https://named-data.net" title="A Future Internet Architecture">
|
||||
<img class="logo" src="{{ pathto('_static/ndn-logo.svg', 1)|e }}" alt="Logo" width="210"/>
|
||||
</a></p>
|
||||
</div>
|
||||
</div><!--header container end-->
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-wrapper">
|
||||
<div class="content">
|
||||
<div class="document">
|
||||
{%- block document %}
|
||||
{{ super() }}
|
||||
{%- endblock %}
|
||||
<div id="menu_container" class="nine columns">
|
||||
<h1><a href="{{ pathto(master_doc)|e }}">{{ shorttitle|e }}</a></h1>
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
{%- block sidebartoc %}
|
||||
<h3>{{ _('Table Of Contents') }}</h3>
|
||||
{{ toctree(includehidden=True) }}
|
||||
|
||||
<h3>{{ _('Developer documentation') }}</h3>
|
||||
<ul>
|
||||
<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>
|
||||
</ul>
|
||||
{%- endblock %}
|
||||
|
||||
{%- block sidebarsearch %}
|
||||
<h3 style="margin-top: 1.5em;">{{ _('Search') }}</h3>
|
||||
<form class="search" action="{{ pathto('search') }}" method="get">
|
||||
<input type="text" name="q" />
|
||||
<input type="submit" value="{{ _('Go') }}" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
<p class="searchtip" style="font-size: 90%">
|
||||
{{ _('Enter search terms or a module, class or function name.') }}
|
||||
</p>
|
||||
{%- endblock %}
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{%- block sidebartoc %}
|
||||
<h3>{{ _('Table of Contents') }}</h3>
|
||||
{{ toctree(includehidden=True) }}
|
||||
<h3>{{ _('Developer Documentation') }}</h3>
|
||||
<ul>
|
||||
<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>
|
||||
</ul>
|
||||
{%- endblock %}
|
||||
|
||||
{% block footer %}
|
||||
<div id="footer-container">
|
||||
<!--footer container-->
|
||||
<div class="row">
|
||||
</div><!-- footer container-->
|
||||
</div>
|
||||
|
||||
<div id="footer-info">
|
||||
<!--footer container-->
|
||||
<div class="row">
|
||||
<div class="twelve columns">
|
||||
|
||||
<div id="copyright">This research is partially supported by NSF (Award <a href="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank>">CNS-1040868</a>)<br/><br/><a rel="license" href="http://creativecommons.org/licenses/by/3.0/deed.en_US" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.</div>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="twelve columns">
|
||||
<div id="copyright">
|
||||
This research is partially supported by NSF (Award <a href="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank">CNS-1040868</a>).<br/><br/>
|
||||
Licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.
|
||||
</div>
|
||||
</div>
|
||||
</div><!--footer info end-->
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block relbar1 %}{% endblock %}
|
||||
{% block relbar2 %}{% endblock %}
|
||||
@@ -1,459 +0,0 @@
|
||||
* {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
html { font-size: 62.5%; }
|
||||
|
||||
body {
|
||||
font-family: {{ theme_bodyfont }};
|
||||
background-color: {{ theme_bgcolor }};
|
||||
color: #777;
|
||||
border-top: 4px solid #fd7800;
|
||||
}
|
||||
|
||||
body { background: white; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1; color: #222222; position: relative; -webkit-font-smoothing: antialiased; }
|
||||
|
||||
/* Page layout */
|
||||
|
||||
div.header, div.content, div.footer {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
div.header-wrapper {
|
||||
background: {{ theme_headerbg }};
|
||||
border-bottom: 3px solid #2e3436;
|
||||
}
|
||||
|
||||
|
||||
/* Default body styles */
|
||||
a {
|
||||
color: {{ theme_linkcolor }};
|
||||
}
|
||||
|
||||
div.bodywrapper a, div.footer a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.clearer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.line-block {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.line-block .line-block {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: {{ theme_headerfont }};
|
||||
font-weight: normal;
|
||||
color: {{ theme_headercolor2 }};
|
||||
margin-bottom: .8em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: {{ theme_headercolor1 }};
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-bottom: .5em;
|
||||
border-bottom: 1px solid {{ theme_headercolor2 }};
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
visibility: hidden;
|
||||
color: #dddddd;
|
||||
padding-left: .3em;
|
||||
}
|
||||
|
||||
h1:hover > a.headerlink,
|
||||
h2:hover > a.headerlink,
|
||||
h3:hover > a.headerlink,
|
||||
h4:hover > a.headerlink,
|
||||
h5:hover > a.headerlink,
|
||||
h6:hover > a.headerlink,
|
||||
dt:hover > a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
div.admonition {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 2px 7px 1px 7px;
|
||||
border-left: 0.2em solid black;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
margin: 0px 10px 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dt:target, .highlighted {
|
||||
background-color: #fbe54e;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
|
||||
div.header {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
div.header .headertitle {
|
||||
font-family: {{ theme_headerfont }};
|
||||
font-weight: normal;
|
||||
font-size: 180%;
|
||||
letter-spacing: .08em;
|
||||
margin-bottom: .8em;
|
||||
}
|
||||
|
||||
div.header .headertitle a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.header div.rel {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
div.header div.rel a {
|
||||
color: {{ theme_headerlinkcolor }};
|
||||
letter-spacing: .1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
p.logo {
|
||||
float: right;
|
||||
}
|
||||
|
||||
img.logo {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
|
||||
/* Content */
|
||||
div.content-wrapper {
|
||||
background-color: white;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
div.document {
|
||||
width: 70%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.body {
|
||||
padding-right: 2em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.document h1 {
|
||||
line-height: 120%;
|
||||
}
|
||||
|
||||
div.document ul {
|
||||
margin-left: 1.5em;
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
div.document dd {
|
||||
margin-left: 1.2em;
|
||||
margin-top: .4em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div.document .section {
|
||||
margin-top: 1.7em;
|
||||
}
|
||||
div.document .section:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
div.document div.highlight {
|
||||
padding: 3px;
|
||||
background-color: #eeeeec;
|
||||
border-top: 2px solid #dddddd;
|
||||
border-bottom: 2px solid #dddddd;
|
||||
margin-bottom: .8em;
|
||||
}
|
||||
|
||||
div.document h2 {
|
||||
margin-top: .7em;
|
||||
}
|
||||
|
||||
div.document p {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
div.document li.toctree-l1 {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div.document .descname {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.document .docutils.literal {
|
||||
background-color: #eeeeec;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
div.document .docutils.xref.literal {
|
||||
background-color: transparent;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div.document ol {
|
||||
margin: 1.5em;
|
||||
}
|
||||
|
||||
|
||||
/* Sidebar */
|
||||
|
||||
div.sidebar {
|
||||
width: 20%;
|
||||
float: right;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
div.sidebar a, div.header a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div.sidebar a:hover, div.header a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div.sidebar h3 {
|
||||
color: #2e3436;
|
||||
text-transform: uppercase;
|
||||
font-size: 130%;
|
||||
letter-spacing: .1em;
|
||||
}
|
||||
|
||||
div.sidebar ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
div.sidebar li.toctree-l1 a {
|
||||
display: block;
|
||||
padding: 1px;
|
||||
border: 1px solid #dddddd;
|
||||
background-color: #eeeeec;
|
||||
margin-bottom: .4em;
|
||||
padding-left: 3px;
|
||||
color: #2e3436;
|
||||
}
|
||||
|
||||
div.sidebar li.toctree-l2 a {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
margin-left: 1em;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
|
||||
div.sidebar li.toctree-l3 a {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
margin-left: 2em;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
|
||||
div.sidebar li.toctree-l2:last-child a {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
div.sidebar li.toctree-l1.current a {
|
||||
border-right: 5px solid {{ theme_headerlinkcolor }};
|
||||
}
|
||||
|
||||
div.sidebar li.toctree-l1.current li.toctree-l2 a {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
div.sidebar input[type="text"] {
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
div.sidebar input[type="submit"] {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
|
||||
/* Footer */
|
||||
|
||||
div.footer-wrapper {
|
||||
background: {{ theme_footerbg }};
|
||||
border-top: 4px solid #babdb6;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
div.footer, div.footer a {
|
||||
color: #888a85;
|
||||
}
|
||||
|
||||
div.footer .right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.footer .left {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
|
||||
/* Styles copied from basic theme */
|
||||
|
||||
img.align-left, .figure.align-left, object.align-left {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
img.align-right, .figure.align-right, object.align-right {
|
||||
clear: right;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
img.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.search li div.context {
|
||||
color: #888;
|
||||
margin: 2px 0 0 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.keywordmatches li.goodmatch a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- index page ------------------------------------------------------------ */
|
||||
|
||||
table.contentstable {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
table.contentstable p.biglink {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
a.biglink {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
span.linkdescr {
|
||||
font-style: italic;
|
||||
padding-top: 5px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
/* -- general index --------------------------------------------------------- */
|
||||
|
||||
table.indextable td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.indextable dl, table.indextable dd {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
table.indextable tr.pcap {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
table.indextable tr.cap {
|
||||
margin-top: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
img.toggler {
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* -- viewcode extension ---------------------------------------------------- */
|
||||
|
||||
.viewcode-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.viewcode-back {
|
||||
float: right;
|
||||
font-family:: {{ theme_bodyfont }};
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
margin: -1px -3px;
|
||||
padding: 0 3px;
|
||||
background-color: #f4debf;
|
||||
border-top: 1px solid #ac9;
|
||||
border-bottom: 1px solid #ac9;
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
padding: 5px 0px;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #aaa;
|
||||
margin-top: -10pt;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
@import url("agogo.css");
|
||||
|
||||
pre {
|
||||
padding: 10px;
|
||||
background-color: #fafafa;
|
||||
color: #222;
|
||||
line-height: 1.2em;
|
||||
border: 2px solid #C6C9CB;
|
||||
font-size: 1.1em;
|
||||
/* margin: 1.5em 0 1.5em 0; */
|
||||
margin: 0;
|
||||
border-right-style: none;
|
||||
border-left-style: none;
|
||||
}
|
||||
+26
-3
@@ -123,10 +123,10 @@ ul.large li { line-height: 21px; }
|
||||
ol li ul, ol li ol { margin-left: 20px; margin-bottom: 0; }
|
||||
|
||||
/* Blockquotes ---------------------- */
|
||||
blockquote, blockquote p { line-height: 1.5; }
|
||||
blockquote, blockquote p { line-height: 1.5; color: #6f6f6f; }
|
||||
|
||||
blockquote { margin: 0 0 17px; padding: 9px 20px 0 19px; }
|
||||
blockquote cite { display: block; font-size: 13pt; color: #555555; }
|
||||
blockquote { margin: 0 0 17px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }
|
||||
blockquote cite { display: block; font-size: 13px; color: #555555; }
|
||||
blockquote cite:before { content: "\2014 \0020"; }
|
||||
blockquote cite a, blockquote cite a:visited { color: #555555; }
|
||||
|
||||
@@ -786,3 +786,26 @@ ul.link-list li a { display: block; }
|
||||
.flex-video.widescreen { padding-bottom: 57.25%; }
|
||||
.flex-video.vimeo { padding-top: 0; }
|
||||
.flex-video iframe, .flex-video object, .flex-video embed, .flex-video video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
@media only screen and (max-device-width: 800px), only screen and (device-width: 1024px) and (device-height: 600px), only screen and (width: 1280px) and (orientation: landscape), only screen and (device-width: 800px), only screen and (max-width: 767px) { .flex-video { padding-top: 0; } }
|
||||
|
||||
/* Microformats ---------------------- */
|
||||
ul.vcard { display: inline-block; margin: 0 0 12px 0; border: 1px solid #ddd; padding: 10px; }
|
||||
ul.vcard li { margin: 0; display: block; }
|
||||
ul.vcard li.fn { font-weight: bold; font-size: 15px; font-size: 1.5rem; }
|
||||
|
||||
p.vevent span.summary { font-weight: bold; }
|
||||
p.vevent abbr { cursor: default; text-decoration: none; font-weight: bold; border: none; padding: 0 1px; }
|
||||
|
||||
/* Progress Bar ---------------------- */
|
||||
div.progress { padding: 2px; margin-bottom: 10px; border: 1px solid #cccccc; height: 25px; /* meter */ /* border radii */ }
|
||||
div.progress .meter { background: #fd7800; height: 100%; display: block; width: 50%; }
|
||||
div.progress.secondary .meter { background: #e9e9e9; }
|
||||
div.progress.success .meter { background: #5da423; }
|
||||
div.progress.alert .meter { background: #c60f13; }
|
||||
div.progress.radius { -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; }
|
||||
div.progress.radius .meter { -webkit-border-radius: 2px; -moz-border-radius: 2px; -ms-border-radius: 2px; -o-border-radius: 2px; border-radius: 2px; }
|
||||
div.progress.round { -webkit-border-radius: 1000px; -moz-border-radius: 1000px; -ms-border-radius: 1000px; -o-border-radius: 1000px; border-radius: 1000px; }
|
||||
div.progress.round .meter { -webkit-border-radius: 1000px; -moz-border-radius: 1000px; -ms-border-radius: 1000px; -o-border-radius: 1000px; border-radius: 1000px; }
|
||||
|
||||
ul li p { display: inline; }
|
||||
@@ -0,0 +1,75 @@
|
||||
@import "agogo.css";
|
||||
@import "foundation.css";
|
||||
@import "named_data_style.css";
|
||||
|
||||
body, h1, h2, h3, h4, p {
|
||||
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
||||
}
|
||||
|
||||
h1 { font-size: 26px; }
|
||||
h2 { font-size: 20px; }
|
||||
h3 { font-size: 17px; }
|
||||
h4 { font-size: 15px; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2, h3, h4 {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: none;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
p.logo {
|
||||
float: left;
|
||||
margin: 1px 0 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #666;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.document p {
|
||||
margin: 0.5em 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.document ol,
|
||||
div.document ul {
|
||||
margin: 0 0 0 2em;
|
||||
}
|
||||
|
||||
div.document pre {
|
||||
font-size: 13px;
|
||||
line-height: 1.3;
|
||||
margin: 0;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
div.document table p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.document th p {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.bodywrapper a,
|
||||
div.header a:hover,
|
||||
div.sidebar a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -0,0 +1,713 @@
|
||||
/* General */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
body {
|
||||
/* background: #ccc;
|
||||
font: normal 12px Verdana, sans-serif;
|
||||
color: #777;
|
||||
line-height:18px; */
|
||||
border-top: 4px solid #fd7800;
|
||||
}
|
||||
|
||||
a {
|
||||
/* color: #000;
|
||||
outline: 0; */
|
||||
}
|
||||
|
||||
a:link {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:active,
|
||||
a:hover {
|
||||
/* color: #ccc; */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #000;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
h1 { font-weight: normal; font-size: 24px; line-height: 24px; }
|
||||
h2 { font-weight: normal; font-size: 18px; line-height: 18px; }
|
||||
h3 { font-weight: normal; font-size: 14px; line-height: 14px; }
|
||||
h4 { font-weight: normal; font-size: 12px; line-height: 12px; }
|
||||
|
||||
hr {
|
||||
background-color: #c6c6c6;
|
||||
border:0;
|
||||
height: 1px;
|
||||
margin-bottom: 18px;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div.hr {
|
||||
height: 1px;
|
||||
background: #c6c6c6;
|
||||
}
|
||||
|
||||
div.hr2 {
|
||||
height: 1px;
|
||||
background: #c6c6c6;
|
||||
}
|
||||
|
||||
div.hr hr, div.hr2 hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0 0 0.5em;
|
||||
line-height:1.6em;
|
||||
}
|
||||
ul {
|
||||
list-style: square;
|
||||
margin: 0 0 18px 0;
|
||||
}
|
||||
ol {
|
||||
list-style: decimal;
|
||||
margin: 0 0 18px 1.5em;
|
||||
}
|
||||
ol ol {
|
||||
list-style:upper-alpha;
|
||||
}
|
||||
ol ol ol {
|
||||
list-style:lower-roman;
|
||||
}
|
||||
ol ol ol ol {
|
||||
list-style:lower-alpha;
|
||||
}
|
||||
ul ul,
|
||||
ol ol,
|
||||
ul ol,
|
||||
ol ul {
|
||||
margin-bottom:0;
|
||||
}
|
||||
dl {
|
||||
margin:0 0 24px 0;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
dd {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
strong {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
cite,
|
||||
em,
|
||||
i {
|
||||
font-style: italic;
|
||||
border: none;
|
||||
}
|
||||
big {
|
||||
font-size: 131.25%;
|
||||
}
|
||||
ins {
|
||||
background: #FFFFCC;
|
||||
border: none;
|
||||
color: #333;
|
||||
}
|
||||
del {
|
||||
text-decoration: line-through;
|
||||
color: #555;
|
||||
}
|
||||
blockquote {
|
||||
font-style: italic;
|
||||
padding: 0 3em;
|
||||
}
|
||||
blockquote cite,
|
||||
blockquote em,
|
||||
blockquote i {
|
||||
font-style: normal;
|
||||
}
|
||||
pre {
|
||||
background: #f7f7f7;
|
||||
color: #222;
|
||||
line-height: 18px;
|
||||
margin-bottom: 18px;
|
||||
padding: 1.5em;
|
||||
}
|
||||
abbr,
|
||||
acronym {
|
||||
border-bottom: 1px solid #666;
|
||||
cursor: help;
|
||||
}
|
||||
ins {
|
||||
text-decoration: none;
|
||||
}
|
||||
sup,
|
||||
sub {
|
||||
height: 0;
|
||||
line-height: 1;
|
||||
vertical-align: baseline;
|
||||
position: relative;
|
||||
font-size: 10px;
|
||||
}
|
||||
sup {
|
||||
bottom: 1ex;
|
||||
}
|
||||
sub {
|
||||
top: .5ex;
|
||||
}
|
||||
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
dd,
|
||||
pre,
|
||||
hr {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
ul ul,
|
||||
ol ol,
|
||||
ul ol,
|
||||
ol ul {
|
||||
margin-bottom:0;
|
||||
}
|
||||
pre,
|
||||
kbd,
|
||||
tt,
|
||||
var {
|
||||
font-size: 15px;
|
||||
line-height: 21px;
|
||||
}
|
||||
code {
|
||||
font-size: 13px;
|
||||
}
|
||||
strong,
|
||||
b,
|
||||
dt,
|
||||
th {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
/* main_container */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#wrapper {
|
||||
padding: 0px 0px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* header*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#search-header{
|
||||
margin-top:15px;
|
||||
padding-bottom:13px;
|
||||
}
|
||||
|
||||
#search-header #search{
|
||||
background: #222;
|
||||
|
||||
}
|
||||
|
||||
#search-header #search #s{
|
||||
background: #222;
|
||||
font-size:12px;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#header_container{
|
||||
padding-bottom: 25px;
|
||||
padding-top: 0px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#header {
|
||||
|
||||
}
|
||||
|
||||
#header2 {
|
||||
|
||||
}
|
||||
|
||||
#content_container{
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
#left-col {
|
||||
padding: 10px 20px;
|
||||
padding-left: 0px;
|
||||
background: #fff;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*footer*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
#footer {
|
||||
padding: 5px 20px;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
#footer-container{
|
||||
padding: 5px 20px;
|
||||
background: #303030;
|
||||
border-top: 8px solid #000;
|
||||
font-size:11px;
|
||||
}
|
||||
|
||||
#footer-info {
|
||||
color:#ccc;
|
||||
text-align:left;
|
||||
background: #1b1b1b;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
|
||||
#footer-info a{
|
||||
text-decoration:none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#footer-info a:hover{
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
#copyright{float: left;}
|
||||
|
||||
.scroll-top {
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
#footer-bar1 {
|
||||
padding-right: 40px;
|
||||
}
|
||||
#footer-bar2 {
|
||||
padding-right: 40px;
|
||||
}
|
||||
#footer-bar3 {
|
||||
}
|
||||
#footer-bar4 {
|
||||
}
|
||||
|
||||
span#follow-box{
|
||||
position: absolute;
|
||||
right: 100px;
|
||||
}
|
||||
|
||||
span#follow-box img{
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
/*logo*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#logo {
|
||||
margin: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
#logo2 {
|
||||
margin: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
#logo img{
|
||||
border: none;
|
||||
}
|
||||
|
||||
#logo2{
|
||||
text-decoration: none;
|
||||
font-size: 42px;
|
||||
letter-spacing: -1pt;
|
||||
font-weight: bold;
|
||||
font-family:arial, "Times New Roman", Times, serif;
|
||||
text-align: left;
|
||||
line-height: 57px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
#logo2 a, #slogan{
|
||||
color: #fd7800;
|
||||
}
|
||||
|
||||
#slogan{
|
||||
text-align: left;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
/*search*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#search {
|
||||
width:180px;
|
||||
height:28px;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#sidebar #search {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#search #searchsubmit {
|
||||
background:url(images/go-btn.png) no-repeat top right;
|
||||
width:28px;
|
||||
height:28px;
|
||||
border:0px;
|
||||
position:absolute;
|
||||
right: -35px;
|
||||
}
|
||||
|
||||
#search #s {
|
||||
width:170px;
|
||||
height:23px;
|
||||
border:0px;
|
||||
margin-left:7px;
|
||||
margin-right:10px;
|
||||
margin-top:3px;
|
||||
color:#000;
|
||||
display: inline;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/*menu bar*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#menu_container{
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
|
||||
/*responsive menu*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
/* default style */
|
||||
.selectnav { display: none; }
|
||||
|
||||
/* small screen */
|
||||
@media screen and (max-width: 600px) {
|
||||
.js #nav { display: none; }
|
||||
.js #nav2 { display: none; }
|
||||
.js .selectnav { display: block; }
|
||||
}
|
||||
|
||||
|
||||
/*homepage boxes*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#box_container{
|
||||
padding-top: 35px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.box-head {
|
||||
float: left;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.box-head img{
|
||||
|
||||
}
|
||||
|
||||
.title-head{
|
||||
padding-top:2px;
|
||||
}
|
||||
|
||||
.title-box{
|
||||
color: #333;
|
||||
line-height: 15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.title-box h1 {
|
||||
font-size: 18px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.box-content {
|
||||
float: left;
|
||||
padding-top: 10px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
/* POST */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
.post {
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
.post-shadow{
|
||||
background: url("images/post_shadow.png") no-repeat bottom;
|
||||
height: 9px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.post ol{
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.post ul {
|
||||
margin-left: 15px;
|
||||
}
|
||||
.post-entry ul { margin: 0 0 10px 10px; }
|
||||
.post-entry ul li {
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 0 0 0 20px;
|
||||
/*background: url(images/bullet.png) no-repeat 0 7px;*/
|
||||
}
|
||||
|
||||
.post-entry ol {
|
||||
list-style: decimal;
|
||||
margin: 0 0 18px 1.6em;
|
||||
}
|
||||
.post-entry ol li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.post-entry {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
.post-head {
|
||||
margin-bottom: 5px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.post-head h1 a, .post-head h1 {
|
||||
text-decoration:none;
|
||||
color:#000;
|
||||
margin: 0px;
|
||||
font-size: 27px;
|
||||
}
|
||||
|
||||
.post-head h1 a:hover {
|
||||
color:#777;
|
||||
}
|
||||
|
||||
|
||||
.post-head-notfound h1, .post-head-404 h1, .post-head-archive h1, .post-head-search h1 {
|
||||
margin-bottom: 10px;
|
||||
font-weight:normal;
|
||||
text-decoration:none;
|
||||
color:#000;
|
||||
font-size: 27px;
|
||||
}
|
||||
|
||||
.post-thumb img {
|
||||
border: 0px solid #ebebeb;
|
||||
}
|
||||
|
||||
.post-entry img{
|
||||
margin-bottom: 10px;
|
||||
height:auto;
|
||||
max-width:100% !important;
|
||||
}
|
||||
|
||||
.meta-data{
|
||||
line-height: 16px;
|
||||
padding: 6px 3px;
|
||||
margin-bottom: 3px;
|
||||
font-size: 11px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
}
|
||||
|
||||
.meta-data a{
|
||||
color: #fd7800;
|
||||
}
|
||||
|
||||
.meta-data a:hover{
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.read-more {
|
||||
color: #000;
|
||||
background: #fff;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
cursor: pointer;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.read-more:hover{
|
||||
background: #fff;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.sticky {
|
||||
|
||||
}
|
||||
|
||||
/* content */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
#content_container table {
|
||||
border: 1px solid #e7e7e7;
|
||||
margin: 0 -1px 24px 0;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
#content_container tr th,
|
||||
#content_container thead th {
|
||||
color: #888;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 18px;
|
||||
padding: 9px 10px;
|
||||
}
|
||||
#content_container tr td {
|
||||
|
||||
padding: 6px 10px;
|
||||
}
|
||||
#content_container tr.odd td {
|
||||
background: #f2f7fc;
|
||||
}
|
||||
|
||||
/* sidebar*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#sidebar {
|
||||
padding:0px 20px 20px 0px;
|
||||
}
|
||||
|
||||
#sidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#sidebar { word-wrap: break-word;}
|
||||
|
||||
/*--navigation--*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
.navigation {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
|
||||
.navigation .alignleft a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.navigation .alignright a {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#nav-single {
|
||||
overflow:hidden;
|
||||
margin-top:20px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.nav-previous {
|
||||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
.nav-next {
|
||||
float: right;
|
||||
text-align: right;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
/*--slider--*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#slider_container {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.flex-caption{
|
||||
background: #232323;
|
||||
color: #fff;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.flexslider p{
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
/*--sub head and breadcrumbs--*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#subhead_container{
|
||||
padding: 7px 0px;
|
||||
}
|
||||
|
||||
#subhead h1{
|
||||
color: #000;
|
||||
padding-top: 10px;
|
||||
padding-left: 0px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
#breadcrumbs {
|
||||
padding-left: 25px;
|
||||
margin-bottom: 15px;
|
||||
color: #9e9e9e;
|
||||
margin:0 auto;
|
||||
width: 964px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#breadcrumbs a{
|
||||
text-decoration: none;
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
/*Alignments */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
.alignleft,
|
||||
img.alignleft {
|
||||
display: inline;
|
||||
float: left;
|
||||
margin-right: 22px;
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
.alignright,
|
||||
img.alignright {
|
||||
display: inline;
|
||||
float: right;
|
||||
margin-left: 22px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.aligncenter,
|
||||
img.aligncenter {
|
||||
clear: both;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.alignleft,
|
||||
.alignright,
|
||||
.aligncenter,
|
||||
img.alignleft,
|
||||
img.alignright,
|
||||
img.aligncenter
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
a img.aligncenter {
|
||||
display:block;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
}
|
||||
@@ -1,813 +0,0 @@
|
||||
@import url("base.css");
|
||||
|
||||
@import url("foundation.css");
|
||||
|
||||
table {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 10px;
|
||||
background-color: #fafafa;
|
||||
color: #222;
|
||||
/* line-height: 1.0em; */
|
||||
border: 2px solid #C6C9CB;
|
||||
font-size: 0.9em;
|
||||
/* margin: 1.5em 0 1.5em 0; */
|
||||
margin: 0;
|
||||
border-right-style: none;
|
||||
border-left-style: none;
|
||||
}
|
||||
|
||||
/* General */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
a:link {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:active,
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #000;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
h1 { font-weight: bold; font-size: 24px; }
|
||||
h2 { font-weight: bold; font-size: 18px; }
|
||||
h3 { font-weight: bold; font-size: 16px; }
|
||||
h4 { font-weight: bold; font-size: 14px; }
|
||||
|
||||
hr {
|
||||
background-color: #c6c6c6;
|
||||
border:0;
|
||||
height: 1px;
|
||||
margin-bottom: 18px;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div.hr {
|
||||
height: 1px;
|
||||
background: #c6c6c6;
|
||||
}
|
||||
|
||||
div.hr2 {
|
||||
height: 1px;
|
||||
background: #c6c6c6;
|
||||
}
|
||||
|
||||
div.hr hr, div.hr2 hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0;
|
||||
line-height:1.6em;
|
||||
}
|
||||
ul {
|
||||
list-style: square;
|
||||
margin: 0 0 18px 0;
|
||||
}
|
||||
ol {
|
||||
list-style: decimal;
|
||||
margin: 0 0 18px 1.5em;
|
||||
}
|
||||
ol ol {
|
||||
list-style:upper-alpha;
|
||||
}
|
||||
ol ol ol {
|
||||
list-style:lower-roman;
|
||||
}
|
||||
ol ol ol ol {
|
||||
list-style:lower-alpha;
|
||||
}
|
||||
ul ul,
|
||||
ol ol,
|
||||
ul ol,
|
||||
ol ul {
|
||||
margin-bottom:0;
|
||||
}
|
||||
dl {
|
||||
margin:0 0 24px 0;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
dd {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
strong {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
cite,
|
||||
em,
|
||||
i {
|
||||
font-style: italic;
|
||||
border: none;
|
||||
}
|
||||
big {
|
||||
font-size: 131.25%;
|
||||
}
|
||||
ins {
|
||||
background: #FFFFCC;
|
||||
border: none;
|
||||
color: #333;
|
||||
}
|
||||
del {
|
||||
text-decoration: line-through;
|
||||
color: #555;
|
||||
}
|
||||
blockquote {
|
||||
padding: 0 3em;
|
||||
}
|
||||
blockquote cite,
|
||||
blockquote em,
|
||||
blockquote i {
|
||||
font-style: normal;
|
||||
}
|
||||
pre {
|
||||
background: #f7f7f7;
|
||||
color: #222;
|
||||
padding: 1.5em;
|
||||
}
|
||||
abbr,
|
||||
acronym {
|
||||
border-bottom: 1px solid #666;
|
||||
cursor: help;
|
||||
}
|
||||
ins {
|
||||
text-decoration: none;
|
||||
}
|
||||
sup,
|
||||
sub {
|
||||
height: 0;
|
||||
line-height: 1;
|
||||
vertical-align: baseline;
|
||||
position: relative;
|
||||
font-size: 10px;
|
||||
}
|
||||
sup {
|
||||
bottom: 1ex;
|
||||
}
|
||||
sub {
|
||||
top: .5ex;
|
||||
}
|
||||
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
dd,
|
||||
hr {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
ul ul,
|
||||
ol ol,
|
||||
ul ol,
|
||||
ol ul {
|
||||
margin-bottom:0;
|
||||
}
|
||||
pre,
|
||||
kbd,
|
||||
tt,
|
||||
var {
|
||||
}
|
||||
code {
|
||||
font-size: 13px;
|
||||
}
|
||||
strong,
|
||||
b,
|
||||
dt,
|
||||
th {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
/* main_container */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#wrapper {
|
||||
padding: 0px 0px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* header*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#search-header{
|
||||
margin-top:15px;
|
||||
padding-bottom:13px;
|
||||
}
|
||||
|
||||
#search-header #search{
|
||||
background: #222;
|
||||
|
||||
}
|
||||
|
||||
#search-header #search #s{
|
||||
background: #222;
|
||||
font-size:12px;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#header_container{
|
||||
padding-bottom: 25px;
|
||||
padding-top: 0px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#header {
|
||||
|
||||
}
|
||||
|
||||
#header2 {
|
||||
|
||||
}
|
||||
|
||||
#content_container{
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
#left-col {
|
||||
padding: 10px 20px;
|
||||
padding-left: 0px;
|
||||
background: #fff;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*footer*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
#footer {
|
||||
padding: 5px 20px;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
#footer-container{
|
||||
padding: 5px 20px;
|
||||
background: #303030;
|
||||
border-top: 8px solid #000;
|
||||
font-size:11px;
|
||||
}
|
||||
|
||||
#footer-info {
|
||||
color:#ccc;
|
||||
text-align:left;
|
||||
background: #1b1b1b;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
|
||||
#footer-info a{
|
||||
text-decoration:none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#footer-info a:hover{
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
#copyright{float: left;}
|
||||
|
||||
.scroll-top {
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
#footer-widget{
|
||||
padding: 8px 0px 8px 0px;
|
||||
color:#6f6f6f;
|
||||
}
|
||||
|
||||
#footer-widget #search {
|
||||
width:120px;
|
||||
height:28px;
|
||||
background: #222;
|
||||
margin-left: 0px;
|
||||
position: relative;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
#footer-widget #search #s {
|
||||
width:110px;
|
||||
height:23px;
|
||||
border:0px;
|
||||
margin-left:7px;
|
||||
margin-right:10px;
|
||||
margin-top:3px;
|
||||
color:#fff;
|
||||
display: inline;
|
||||
background: #222;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#footer-widget #calendar_wrap {
|
||||
padding: 8px 0px;
|
||||
}
|
||||
|
||||
#footer-widget #wp-calendar td{
|
||||
padding:2px;
|
||||
}
|
||||
|
||||
|
||||
#footer-widget .textwidget {
|
||||
padding: 5px 0px;
|
||||
line-height: 23px;
|
||||
}
|
||||
|
||||
|
||||
#footer-widget .widget_tag_cloud a{
|
||||
text-decoration: none;
|
||||
margin: 5px;
|
||||
line-height: 24px;
|
||||
margin-left: 0px;
|
||||
color: #6f6f6f;
|
||||
}
|
||||
|
||||
#footer-widget .widget_tag_cloud a:hover{
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#footer-widget .widget-container ul li a {
|
||||
color:#fd7800;
|
||||
}
|
||||
|
||||
#footer-widget .widget-container ul li a:hover {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
#footer-widget .widget-container h3 {
|
||||
color: #a5a5a5;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0px;
|
||||
padding-top: 10px;
|
||||
padding-left: 0px;
|
||||
font-size: 25px;
|
||||
padding-bottom: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#footer-widget .widget-container ul li {
|
||||
padding: 5px 0px;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#footer-widget ul {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
#footer-bar1 {
|
||||
padding-right: 40px;
|
||||
}
|
||||
#footer-bar2 {
|
||||
padding-right: 40px;
|
||||
}
|
||||
#footer-bar3 {
|
||||
}
|
||||
#footer-bar4 {
|
||||
}
|
||||
|
||||
span#follow-box{
|
||||
position: absolute;
|
||||
right: 100px;
|
||||
}
|
||||
|
||||
span#follow-box img{
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
/*logo*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#logo {
|
||||
margin: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
#logo2 {
|
||||
margin: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
#logo img{
|
||||
border: none;
|
||||
}
|
||||
|
||||
#logo2{
|
||||
text-decoration: none;
|
||||
font-size: 42px;
|
||||
letter-spacing: -1pt;
|
||||
font-weight: bold;
|
||||
font-family:arial, "Times New Roman", Times, serif;
|
||||
text-align: left;
|
||||
line-height: 57px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
#logo2 a, #slogan{
|
||||
color: #fd7800;
|
||||
}
|
||||
|
||||
#slogan{
|
||||
text-align: left;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
/*search*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#search {
|
||||
width:180px;
|
||||
height:28px;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#sidebar #search {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#search #searchsubmit {
|
||||
background:url(images/go-btn.png) no-repeat top right;
|
||||
width:28px;
|
||||
height:28px;
|
||||
border:0px;
|
||||
position:absolute;
|
||||
right: -35px;
|
||||
}
|
||||
|
||||
#search #s {
|
||||
width:170px;
|
||||
height:23px;
|
||||
border:0px;
|
||||
margin-left:7px;
|
||||
margin-right:10px;
|
||||
margin-top:3px;
|
||||
color:#000;
|
||||
display: inline;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/*menu bar*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#menu_container{
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
|
||||
/*responsive menu*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
/* default style */
|
||||
.selectnav { display: none; }
|
||||
|
||||
/* small screen */
|
||||
@media screen and (max-width: 600px) {
|
||||
.js #nav { display: none; }
|
||||
.js #nav2 { display: none; }
|
||||
.js .selectnav { display: block; }
|
||||
}
|
||||
|
||||
|
||||
/*welcome*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
#welcome_container h1{
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
/*homepage boxes*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#box_container{
|
||||
padding-top: 35px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.box-head {
|
||||
float: left;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.box-head img{
|
||||
|
||||
}
|
||||
|
||||
.title-head{
|
||||
padding-top:2px;
|
||||
}
|
||||
|
||||
.title-box{
|
||||
color: #333;
|
||||
line-height: 15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.title-box h1 {
|
||||
font-size: 18px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.box-content {
|
||||
float: left;
|
||||
padding-top: 10px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
/* POST */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
.post {
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
.post-shadow{
|
||||
background: url("images/post_shadow.png") no-repeat bottom;
|
||||
height: 9px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.post ol{
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.post ul {
|
||||
margin-left: 15px;
|
||||
}
|
||||
.post-entry ul { margin: 0 0 10px 10px; }
|
||||
.post-entry ul li {
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 0 0 0 20px;
|
||||
/*background: url(images/bullet.png) no-repeat 0 7px;*/
|
||||
}
|
||||
|
||||
.post-entry ol {
|
||||
list-style: decimal;
|
||||
margin: 0 0 18px 1.6em;
|
||||
}
|
||||
.post-entry ol li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.post-entry {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
.post-head {
|
||||
margin-bottom: 5px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.post-head h1 a, .post-head h1 {
|
||||
text-decoration:none;
|
||||
color:#000;
|
||||
margin: 0px;
|
||||
font-size: 27px;
|
||||
}
|
||||
|
||||
.post-head h1 a:hover {
|
||||
color:#777;
|
||||
}
|
||||
|
||||
|
||||
.post-head-notfound h1, .post-head-404 h1, .post-head-archive h1, .post-head-search h1 {
|
||||
margin-bottom: 10px;
|
||||
font-weight:normal;
|
||||
text-decoration:none;
|
||||
color:#000;
|
||||
font-size: 27px;
|
||||
}
|
||||
|
||||
.post-thumb img {
|
||||
border: 0px solid #ebebeb;
|
||||
}
|
||||
|
||||
.post-entry img{
|
||||
margin-bottom: 10px;
|
||||
height:auto;
|
||||
max-width:100% !important;
|
||||
}
|
||||
|
||||
.meta-data{
|
||||
line-height: 16px;
|
||||
padding: 6px 3px;
|
||||
margin-bottom: 3px;
|
||||
font-size: 11px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
}
|
||||
|
||||
.meta-data a{
|
||||
color: #fd7800;
|
||||
}
|
||||
|
||||
.meta-data a:hover{
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.read-more {
|
||||
color: #000;
|
||||
background: #fff;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
cursor: pointer;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.read-more:hover{
|
||||
background: #fff;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.sticky {
|
||||
|
||||
}
|
||||
|
||||
/* content */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
#content_container table {
|
||||
border: 1px solid #e7e7e7;
|
||||
margin: 0 -1px 24px 0;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
#content_container tr th,
|
||||
#content_container thead th {
|
||||
color: #888;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 18px;
|
||||
padding: 9px 10px;
|
||||
}
|
||||
#content_container tr td {
|
||||
|
||||
padding: 6px 10px;
|
||||
}
|
||||
#content_container tr.odd td {
|
||||
background: #f2f7fc;
|
||||
}
|
||||
|
||||
/* sidebar*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#sidebar {
|
||||
padding:0px 20px 20px 0px;
|
||||
}
|
||||
|
||||
#sidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#sidebar { word-wrap: break-word;}
|
||||
|
||||
|
||||
/*--navigation--*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
.navigation {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
|
||||
.navigation .alignleft a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.navigation .alignright a {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#nav-single {
|
||||
overflow:hidden;
|
||||
margin-top:20px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.nav-previous {
|
||||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
.nav-next {
|
||||
float: right;
|
||||
text-align: right;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
/*--slider--*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#slider_container {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.flex-caption{
|
||||
background: #232323;
|
||||
color: #fff;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.flexslider p{
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
/*--sub head and breadcrumbs--*/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#subhead_container{
|
||||
padding: 7px 0px;
|
||||
}
|
||||
|
||||
#subhead h1{
|
||||
color: #000;
|
||||
padding-top: 10px;
|
||||
padding-left: 0px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
#breadcrumbs {
|
||||
padding-left: 25px;
|
||||
margin-bottom: 15px;
|
||||
color: #9e9e9e;
|
||||
margin:0 auto;
|
||||
width: 964px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#breadcrumbs a{
|
||||
text-decoration: none;
|
||||
color: #9e9e9e;
|
||||
}
|
||||
|
||||
/*Alignments */
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
.alignleft,
|
||||
img.alignleft {
|
||||
display: inline;
|
||||
float: left;
|
||||
margin-right: 22px;
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
.alignright,
|
||||
img.alignright {
|
||||
display: inline;
|
||||
float: right;
|
||||
margin-left: 22px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.aligncenter,
|
||||
img.aligncenter {
|
||||
clear: both;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.alignleft,
|
||||
.alignright,
|
||||
.aligncenter,
|
||||
img.alignleft,
|
||||
img.alignright,
|
||||
img.aligncenter
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
a img.aligncenter {
|
||||
display:block;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
padding: 5px;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 152.13 43.86"><defs><style>.cls-1{fill:#dc9610;}.cls-2{fill:#fff;}.cls-3{fill:#bf4818;}</style></defs><rect class="cls-1" width="87.68" height="22.95" rx="5"/><rect class="cls-1" x="89.93" width="62.2" height="22.95" rx="5"/><path class="cls-2" d="M94.88,4.14h5.28c3.16,0,4.82.55,6.22,2.11a8.1,8.1,0,0,1,1.92,5.47,8.41,8.41,0,0,1-2,5.71c-1.35,1.42-3.08,2-6,2h-5.4Zm5.87,12.37A3.29,3.29,0,0,0,104,15a6.14,6.14,0,0,0,.77-3.24A5.94,5.94,0,0,0,104,8.62a3.09,3.09,0,0,0-3-1.54H98.39v9.43Z" transform="translate(-0.18)"/><path class="cls-2" d="M113.7,16.37l-1,3.08h-3.81l5.45-15.31h4.37l5,15.31h-4l-.84-3.08Zm2.76-8.81-1.89,6h3.53Z" transform="translate(-0.18)"/><path class="cls-2" d="M131,19.45h-3.5V7.08h-4.73V4.14h13V7.08H131Z" transform="translate(-0.18)"/><path class="cls-2" d="M139.37,16.37l-1,3.08h-3.81L140,4.14h4.37l4.95,15.31h-4l-.84-3.08Zm2.76-8.81-1.89,6h3.53Z" transform="translate(-0.18)"/><path class="cls-3" d="M10.82,43.52,6.4,35.69l-1.61-3c0,.8,0,1.38,0,1.83,0,.83,0,1.72,0,2.69v6.29H1.66V28.21H5.3l4.3,7.62c.61,1.15,1,2,1.59,3.1,0-.62,0-1,0-1.49l0-1.15V28.21h3.2V43.52Z" transform="translate(-0.18)"/><path class="cls-3" d="M29.23,31.15H21.12v3H28.2v2.71H21.12v3.74h8.25v2.94H17.61V28.21H29.23Z" transform="translate(-0.18)"/><path class="cls-3" d="M39,43.52H35.53V31.15H30.81V28.21H43.75v2.94H39Z" transform="translate(-0.18)"/><path class="cls-3" d="M49,43.52l-4.2-15.31h3.48L50,35.07c.3,1.29.47,2,.86,3.81.26-1.74.42-2.66.66-3.81L53,28.21h3.36l1.45,7c.31,1.51.47,2.34.68,3.69.14-.66.4-1.9.79-3.69l1.73-7h3.48L60.11,43.52H56.84l-1.43-6.38c-.35-1.59-.67-3.24-.77-4-.3,1.65-.49,2.64-.79,4l-1.47,6.38Z" transform="translate(-0.18)"/><path class="cls-3" d="M80.76,36c0,4.66-3.15,7.87-7.71,7.87s-7.73-3.21-7.73-8a7.92,7.92,0,0,1,2.4-6A7.73,7.73,0,0,1,73,27.87C77.72,27.87,80.76,31.06,80.76,36ZM69,35.85C69,39,70.5,41,73.05,41s4-1.91,4-5S75.6,30.78,73,30.78,69,32.68,69,35.85Z" transform="translate(-0.18)"/><path class="cls-3" d="M86.88,43.52H83.45V28.21h6.79c2,0,3.13.25,4.07.92a3.81,3.81,0,0,1,1.49,3.21A3.59,3.59,0,0,1,93.21,36c1.54.48,2.08,1.28,2.2,3.3l.11,2.18a3.24,3.24,0,0,0,.63,2H92.72c-.42-.32-.54-.55-.58-1.33L92,40.1c-.14-1.88-1-2.71-2.78-2.71H86.88Zm3.43-8.84c1.29,0,2-.64,2-1.77s-.7-1.76-2-1.76H86.88v3.53Z" transform="translate(-0.18)"/><path class="cls-3" d="M112.65,43.52h-4.21l-4.72-6.93L102.27,38v5.49H98.84V28.21h3.43v5.65l5.26-5.65h4.6l-6.07,6Z" transform="translate(-0.18)"/><path class="cls-3" d="M117.83,43.52h-3.5V28.21h3.5Z" transform="translate(-0.18)"/><path class="cls-3" d="M130.28,43.52l-4.41-7.83-1.61-3c0,.8,0,1.38,0,1.83,0,.83,0,1.72,0,2.69v6.29h-3.2V28.21h3.64l4.3,7.62c.61,1.15,1,2,1.59,3.1,0-.62,0-1,0-1.49l0-1.15V28.21h3.2V43.52Z" transform="translate(-0.18)"/><path class="cls-3" d="M151,35.05v8.47h-2.1l-.49-2c-1.08,1.65-2.41,2.29-4.67,2.29-4.42,0-7.13-3-7.13-7.89s3-8.1,7.57-8.1a6.48,6.48,0,0,1,6.71,5l-3.39.2a3.13,3.13,0,0,0-3.3-2.27c-2.52,0-4.08,1.88-4.08,5,0,3.3,1.51,5.28,4.06,5.28A3.71,3.71,0,0,0,148,37.87h-3.81V35.05Z" transform="translate(-0.18)"/><path class="cls-2" d="M14.72,19.45,10.3,11.62l-1.61-3c.05.8.05,1.38.05,1.84,0,.82,0,1.72,0,2.68v6.29H5.56V4.14H9.2l4.3,7.62c.61,1.15,1,2,1.59,3.1,0-.62,0-1,0-1.49l0-1.15V4.14h3.21V19.45Z" transform="translate(-0.18)"/><path class="cls-2" d="M24.82,16.37l-1,3.08H20L25.47,4.14h4.38L34.8,19.45h-4L30,16.37Zm2.76-8.81-1.89,6h3.52Z" transform="translate(-0.18)"/><path class="cls-2" d="M42.43,19.45,40.27,11.3c-.16-.69-.3-1.17-.39-1.49-.12-.48-.14-.57-.28-1,0,.55,0,.94,0,1.19l0,1.47v8H36.46V4.14H41.4l2,8c.31,1.19.57,2.46.75,3.47a4.72,4.72,0,0,0,.1-.49l.25-1c.05-.28.14-.62.24-1s.23-1,.23-1l2-8h4.89V19.45h-3.2v-8l0-1.47a11.79,11.79,0,0,1,.05-1.19c-.26.92-.42,1.54-.49,1.74-.14.42-.21.72-.24.74l-2.13,8.17Z" transform="translate(-0.18)"/><path class="cls-2" d="M66.81,7.08H58.7v3h7.08v2.71H58.7v3.74H67v2.94H55.19V4.14H66.81Z" transform="translate(-0.18)"/><path class="cls-2" d="M69.53,4.14h5.28c3.15,0,4.81.55,6.22,2.11a8.09,8.09,0,0,1,1.91,5.47,8.41,8.41,0,0,1-2,5.71c-1.36,1.42-3.09,2-6,2H69.53Zm5.86,12.37A3.29,3.29,0,0,0,78.59,15a6,6,0,0,0,.78-3.24,6,6,0,0,0-.75-3.16,3.11,3.11,0,0,0-3-1.54H73v9.43Z" transform="translate(-0.18)"/></svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -1,15 +1,12 @@
|
||||
[theme]
|
||||
inherit = agogo
|
||||
stylesheet = named_data_style.css
|
||||
# pygments_style = sphinx
|
||||
|
||||
theme_bodyfont = "normal 12px Verdana, sans-serif"
|
||||
theme_bgcolor = "#ccc"
|
||||
|
||||
theme_documentwidth = "100%"
|
||||
theme_textalign = "left"
|
||||
stylesheet = named_data.css
|
||||
|
||||
[options]
|
||||
|
||||
stickysidebar = true
|
||||
collapsiblesidebar = true
|
||||
pagewidth = 90%
|
||||
documentwidth = 70%
|
||||
sidebarwidth = 20%
|
||||
bgcolor = white
|
||||
headerbg = none
|
||||
footerbg = none
|
||||
textalign = left
|
||||
@@ -1 +1 @@
|
||||
release-notes/release-notes-0.7.0.rst
|
||||
release-notes/release-notes-0.7.1.rst
|
||||
@@ -17,17 +17,17 @@ The current features include:
|
||||
- **Base**
|
||||
|
||||
+ Fully asynchronous, event-driven communication model, which is implemented using `Boost.Asio
|
||||
<http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio.html>`_
|
||||
<https://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio.html>`_
|
||||
+ Single-threaded, but thread-safe Face operations
|
||||
|
||||
A single Face object can be safely used in multiple threads to express Interests and
|
||||
publish Data packets
|
||||
|
||||
+ Explicit time management for NDN operations using `Boost.Chrono
|
||||
<http://www.boost.org/doc/libs/1_48_0/doc/html/chrono.html>`_
|
||||
<https://www.boost.org/doc/libs/1_48_0/doc/html/chrono.html>`_
|
||||
+ Simplified and extended `NDN API <doxygen/annotated.html>`_
|
||||
+ Extensive set of unit-tests based on `Boost.Test framework
|
||||
<http://www.boost.org/doc/libs/1_48_0/libs/test/doc/html/index.html>`_
|
||||
<https://www.boost.org/doc/libs/1_48_0/libs/test/doc/html/index.html>`_
|
||||
|
||||
- Continuous integration using an in-house installation of Jenkins build bots and the
|
||||
hosted `Travis CI <https://travis-ci.org/named-data/ndn-cxx>`_ continuous
|
||||
@@ -35,7 +35,7 @@ The current features include:
|
||||
|
||||
- **Wire format**
|
||||
|
||||
+ Full support of `NDN-TLV packet format v0.1 <http://named-data.net/doc/NDN-TLV/0.1/>`_
|
||||
+ Full support of `NDN-TLV packet format v0.1 <https://named-data.net/doc/NDN-packet-spec/0.1/>`_
|
||||
+ Pure C++ implementation of wire encoding/decoding with simple access to wire format
|
||||
of all NDN packet abstractions via ``wireEncode`` and ``wireDecode`` methods
|
||||
|
||||
|
||||
@@ -5,25 +5,26 @@ Release date: August 25, 2014
|
||||
|
||||
Changes since version 0.1.0:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- **Base**
|
||||
|
||||
+ The license under which the library is released is changed to **Lesser GNU Public
|
||||
License version 3.0**.
|
||||
+ The license under which the library is released is changed to the **GNU Lesser
|
||||
General Public License version 3.0**
|
||||
|
||||
+ New ways to use incoming Interest dispatching:
|
||||
|
||||
* New :ndn-cxx:`InterestFilter` abstraction that supports filtering based on name
|
||||
prefixes and regular expressions.
|
||||
|
||||
* Separated :ndn-cxx:`Face::registerPrefix()` and :ndn-cxx:`Face::setInterestFilter()`
|
||||
methods allow distinct operations of registering with the local NDN forwarder and setting
|
||||
* Separate ``Face::registerPrefix()`` and ``Face::setInterestFilter()`` methods
|
||||
allow distinct operations of registering with the local NDN forwarder and setting
|
||||
up application-specific ``OnInterest`` call dispatch using InterestFilters.
|
||||
|
||||
+ Add support for new `NDN naming conventions
|
||||
<http://named-data.net/doc/tech-memos/naming-conventions.pdf>`_ (:issue:`1761`)
|
||||
+ Add support for the `NDN naming conventions (revision 1)
|
||||
<https://named-data.net/publications/techreports/ndn-tr-22-ndn-memo-naming-conventions/>`_
|
||||
(:issue:`1761`)
|
||||
|
||||
- **Security**
|
||||
|
||||
@@ -37,26 +38,25 @@ New features:
|
||||
+ New :ndn-cxx:`SignatureSha256WithEcdsa` signature type
|
||||
|
||||
+ Updates in :ndn-cxx:`Signature` data structure to reflect changes in `NDN-TLV spec
|
||||
0.1.1 <http://named-data.net/doc/NDN-TLV/0.1.1/>`_
|
||||
0.1.1 <https://named-data.net/doc/NDN-packet-spec/0.1.1/>`_
|
||||
|
||||
- **Wire encoding**
|
||||
|
||||
+ :ndn-cxx:`Data::getFullName() <getFullName()>` method to get :ndn-cxx:`Data` packet
|
||||
name with implicit digest
|
||||
+ ``Data::getFullName()`` method to get the Data packet name including the implicit digest
|
||||
|
||||
+ New :ndn-cxx:`Name::getSuccessor()` method to get name successor (:issue:`1677`)
|
||||
+ ``Name::getSuccessor()`` method to get name successor (:issue:`1677`)
|
||||
|
||||
+ New in-wire refreshing of Interest's nonce (:issue:`1758`)
|
||||
|
||||
- **Management**
|
||||
|
||||
+ Support for :ndn-cxx:`ChannelStatus`, :ndn-cxx:`StrategyChoice` datasets
|
||||
+ Support for :ndn-cxx:`ChannelStatus` and :ndn-cxx:`StrategyChoice` datasets
|
||||
|
||||
+ Defining new common Route Origins for NFD RIB management protocol (:issue:`1719`)
|
||||
|
||||
+ New RibEntry and Route data structures for RIB management protocol (:issue:`1764`)
|
||||
+ New ``RibEntry`` and ``Route`` data structures for RIB management protocol (:issue:`1764`)
|
||||
|
||||
+ Add support for RIB flags for setInterestFilter and registerPrefix (:issue:`1842`)
|
||||
+ Add support for RIB flags in ``setInterestFilter()`` and ``registerPrefix()`` (:issue:`1842`)
|
||||
|
||||
- **Miscellaneous tools**
|
||||
|
||||
@@ -71,10 +71,10 @@ New features:
|
||||
|
||||
- **Build**
|
||||
|
||||
+ enabled support of precompiled headers for clang and gcc compilers to speed up compilation
|
||||
+ Enabled support of precompiled headers for clang and gcc compilers to speed up compilation
|
||||
|
||||
Updates and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
Updates and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- **Base**
|
||||
|
||||
@@ -84,13 +84,13 @@ Updates and bug fixes:
|
||||
:ndn-cxx:`Face::put` methods (:issue:`1774`)
|
||||
|
||||
+ Cleaning up transport state on communication failure, so Face can try to reconnect
|
||||
in the future.
|
||||
in the future
|
||||
|
||||
+ Fix bug with Face::removePendingInterest (:issue:`1917`)
|
||||
+ Fix bug in ``Face::removePendingInterest`` (:issue:`1917`)
|
||||
|
||||
- **Wire encoding**
|
||||
|
||||
+ Nonce field is now encoded as 4-byte uint8_t value, as defined by NDN-TLV spec.
|
||||
+ The Nonce field is now encoded as a 4-byte value, as defined by NDN-TLV spec
|
||||
|
||||
+ Optimized Data packet signing
|
||||
|
||||
@@ -104,27 +104,27 @@ Updates and bug fixes:
|
||||
|
||||
- **Management**
|
||||
|
||||
+ Add link-layer byte counts in FaceStatus data structure (:issue:`1765`)
|
||||
+ Add link-layer byte counts in ``FaceStatus`` data structure (:issue:`1765`)
|
||||
|
||||
- **Security**
|
||||
|
||||
+ Allow user to explicitly specify the cert name prefix before 'KEY' component in
|
||||
``ndnsec-certgen``
|
||||
|
||||
+ ``SignatureSha256`` has been renamed to :ndn-cxx:`DigestSha256` to conform with
|
||||
`NDN-TLV specification <http://named-data.net/doc/ndn-tlv/>`_.
|
||||
+ ``SignatureSha256`` has been renamed to :ndn-cxx:`DigestSha256` to conform to
|
||||
`NDN-TLV specification <https://named-data.net/doc/NDN-packet-spec/0.1.1/>`_
|
||||
|
||||
+ Add checking of ``Timestamp`` and ``Nonce`` fields in signed Interest within
|
||||
+ Add checking of Timestamp and Nonce fields in signed Interest within
|
||||
:ndn-cxx:`ValidatorConfig`
|
||||
|
||||
+ Allow validator customization using hooks:
|
||||
+ Allow validator customization using hooks.
|
||||
|
||||
Sub-classes of :ndn-cxx:`Validator` class can use the following hooks to fine-tune the
|
||||
validation process:
|
||||
|
||||
* ``preCertificateValidation`` to process received certificate before validation.
|
||||
* ``preCertificateValidation`` to process received certificate before validation
|
||||
* ``onTimeout`` to process interest timeout
|
||||
* ``afterCheckPolicy`` to process validation requests.
|
||||
* ``afterCheckPolicy`` to process validation requests
|
||||
|
||||
+ Fix memory issues in ``SecPublicInfoSqlite3``
|
||||
|
||||
@@ -136,8 +136,8 @@ Updates and bug fixes:
|
||||
|
||||
- Other minor fixes and corrections
|
||||
|
||||
Deprecated:
|
||||
^^^^^^^^^^^
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- ``SignatureSha256`` class, use :ndn-cxx:`DigestSha256` instead.
|
||||
|
||||
@@ -161,10 +161,10 @@ Deprecated:
|
||||
- ``CommandInterestGenerator`` and ``CommandInterestValidator`` utility classes.
|
||||
:ndn-cxx:`ValidatorConfig` should be used instead.
|
||||
|
||||
Removed:
|
||||
^^^^^^^^
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- support of ndnd-tlv (only NFD management protocol is supported now)
|
||||
- Support for ndnd-tlv (only NFD management protocol is supported now)
|
||||
|
||||
- ``SecPublicInfoMemory`` and ``SecTpmMemory`` classes that were no longer used
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ Release date: February 2, 2015
|
||||
|
||||
Changes since version 0.2.0:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- **Build**
|
||||
|
||||
@@ -85,8 +85,8 @@ New features:
|
||||
|
||||
+ New NetworkMonitor helper to detect network state changes (:issue:`2443`)
|
||||
|
||||
Updates and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
Updates and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- **Base**
|
||||
|
||||
@@ -198,8 +198,8 @@ Updates and bug fixes:
|
||||
|
||||
- Other minor fixes and corrections
|
||||
|
||||
Deprecated:
|
||||
^^^^^^^^^^^
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- ``ndn::ptr_lib`` and ``ndn::func_lib`` namespace aliases
|
||||
|
||||
@@ -216,8 +216,8 @@ Deprecated:
|
||||
|
||||
- ``EventEmitter`` is deprecated in favor of ``Signal``
|
||||
|
||||
Removed:
|
||||
^^^^^^^^
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- FaceFlags APIs (:issue:`1992`)
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ Release date: March 3, 2015
|
||||
|
||||
Changes since version 0.3.0:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- **Management**
|
||||
|
||||
@@ -17,8 +17,8 @@ New features:
|
||||
|
||||
- Add CachingPolicy to ``LocalControlHeader`` (:issue:`2183`)
|
||||
|
||||
Updates and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
Updates and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- **Wire encoding**
|
||||
|
||||
@@ -51,8 +51,8 @@ Updates and bug fixes:
|
||||
- Explicitly define ``_GLIBCXX_USE_NANOSLEEP``, necessary for gcc < 4.8 in some environments
|
||||
(:issue:`2499`)
|
||||
|
||||
Removed:
|
||||
^^^^^^^^
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- Delete deprecated ``Block(std::istream&)`` constructor (:issue:`2241`)
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ Release date: May 12, 2015
|
||||
|
||||
Changes since version 0.3.1:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Add Link abstraction (:issue:`2587`)
|
||||
|
||||
@@ -18,8 +18,8 @@ New features:
|
||||
* In-memory PIB implementation
|
||||
* Define new abstraction for identity, key, and certificate
|
||||
|
||||
Updates and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
Updates and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Enable decoding Exclude containing ImplicitSha256DigestComponent (:issue:`2629`)
|
||||
|
||||
@@ -35,13 +35,13 @@ Updates and bug fixes:
|
||||
|
||||
- Disable precompiled headers on OS X with clang < 6.1.0 (:issue:`2804`)
|
||||
|
||||
Deprecated:
|
||||
^^^^^^^^^^^
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- `Block::fromBuffer` overloads with output parameter (:issue:`2553`)
|
||||
|
||||
Removed:
|
||||
^^^^^^^^
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- Delete deprecated Controller functions:
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ Release date: July 1, 2015
|
||||
|
||||
Changes since version 0.3.2:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Allow compilation of ndn-cxx as a shared library (:issue:`2243`)
|
||||
|
||||
@@ -41,8 +41,8 @@ New features:
|
||||
* ``makeStringBlock``
|
||||
* ``readString``
|
||||
|
||||
Improvements and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Use C++11 lambda expression and smart pointers in Face implementation (:issue:`2112`)
|
||||
|
||||
@@ -72,8 +72,8 @@ Improvements and bug fixes:
|
||||
restrictive move operation (`move_if_noexcept`) is used (e.g., in STL library's containers)
|
||||
(:issue:`2966`)
|
||||
|
||||
Deprecated:
|
||||
^^^^^^^^^^^
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- The following ``KeyChain::sign*`` methods, in favor of generalized ``KeyChain::sign(..., SigningInfo)``
|
||||
|
||||
@@ -101,21 +101,21 @@ Deprecated:
|
||||
* ``CommandOptions::setSigningIdentity``
|
||||
* ``CommandOptions::setSigningCertificate``
|
||||
|
||||
Removed:
|
||||
^^^^^^^^
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- Remove SCOPE from Interests and all references to it in the related code (:issue:`2345`)
|
||||
|
||||
- Direct FIB management in Face class (:issue:`2533`)
|
||||
- Direct FIB management in Face class (:issue:`2533`).
|
||||
|
||||
``Face::register`` and ``Face::setInterestFilter`` methods now only support NFD RIB management
|
||||
protocol.
|
||||
|
||||
For special needs, FIB management can be implemented using ``nfd::Controller``
|
||||
(``start<FibAddNextHopCommand>``, and ``start<FibRemoveNextHopCommand>``)
|
||||
(``start<FibAddNextHopCommand>`` and ``start<FibRemoveNextHopCommand>``).
|
||||
|
||||
Upcoming features (partially finished in development branches):
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Upcoming features (partially finished in development branches)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- NDNLPv2 (https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2, :issue:`2520`,
|
||||
:issue:`2879`, :issue:`2763`, :issue:`2883`, :issue:`2841`, :issue:`2866`)
|
||||
|
||||
@@ -5,8 +5,8 @@ Release date: August 31, 2015
|
||||
|
||||
Changes since version 0.3.3:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- By default, library is now compiled as a shared library (:issue:`2867`)
|
||||
|
||||
@@ -26,8 +26,8 @@ New features:
|
||||
- New Dispatcher class to simplify server-side implementation of NFD management protocol
|
||||
(:issue:`2107`)
|
||||
|
||||
Improvements and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Fix compilation error with Boost 1.59 (:issue:`3128`)
|
||||
|
||||
@@ -44,8 +44,8 @@ Improvements and bug fixes:
|
||||
|
||||
- Add ability to create ``util::Digest`` object from ``std::istream&`` (:issue:`3022`)
|
||||
|
||||
Deprecated:
|
||||
^^^^^^^^^^^
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- The following methods of ``CommandOptions`` class in favor of ``getSigningInfo`` and
|
||||
``setSigningInfo`` methods (:issue:`2893`):
|
||||
@@ -61,8 +61,8 @@ Deprecated:
|
||||
- Overloads of ``Face::registerPrefix`` and ``Face::setInterestFilter`` that do not accept
|
||||
SigningInfo parameter (:issue:`2932`)
|
||||
|
||||
Upcoming features (partially implemented in development branches):
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Upcoming features (partially implemented in development branches)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Introduce new API to simplify security transformations (:issue:`3009`)
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ Release date: December 31, 2015
|
||||
|
||||
Changes since version 0.3.4:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- **(breaking change)** LocalControlHeader for special signaling between application and NFD has
|
||||
been replaced with NDNLPv2 signaling (:issue:`2879`, :issue:`2930`)
|
||||
@@ -32,8 +32,8 @@ New features:
|
||||
|
||||
- Ability to create Face with custom IO service and default transport (:issue:`2500`)
|
||||
|
||||
Improvements and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- **(breaking change)** SegmentFetcher helper changed to use asynchronous data validation (:issue:`2734`)
|
||||
|
||||
@@ -46,8 +46,8 @@ Improvements and bug fixes:
|
||||
|
||||
- Minor documentation updates (:issue:`3207`, :issue:`3210`, :issue:`3221`)
|
||||
|
||||
Deprecated:
|
||||
^^^^^^^^^^^
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- Overloads of ``Face::registerPrefix`` and ``Face::setInterestFilter`` that do not accept
|
||||
SigningInfo parameter (:issue:`2932`)
|
||||
@@ -61,13 +61,13 @@ Deprecated:
|
||||
- ndn::util::DummyClientFace::sentDatas, use ndn::util::DummyClientFace.sentData instead
|
||||
(:issue:`3146`)
|
||||
|
||||
Removed:
|
||||
^^^^^^^^
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- Deprecated EventEmitter class (:issue:`2351`)
|
||||
|
||||
Planned features for future releases:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Planned features for future releases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Introduce new API to simplify security transformations (:issue:`3009`)
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ Release date: March 25, 2016
|
||||
|
||||
Changes since version 0.4.0:
|
||||
|
||||
Improvements and bug fixes:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Improved support for ECDSA signatures (:issue:`3438`, :issue:`3439`)
|
||||
|
||||
@@ -15,14 +15,14 @@ Improvements and bug fixes:
|
||||
- Use InMemoryStorage for StatusDataset and Notification produced by managers based on
|
||||
Dispatcher class (:issue:`2182`)
|
||||
|
||||
Removed:
|
||||
^^^^^^^^
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- Deprecated ``tlvdump`` command-line tool (use ``ndn-dissect`` tool from `NDN Essential Tools
|
||||
<https://github.com/named-data/ndn-tools>`__ instead
|
||||
|
||||
Planned features for future releases:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Planned features for future releases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Introduce new API to simplify security transformations (:issue:`3009`)
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ Release date: October 4, 2016
|
||||
|
||||
Changes since version 0.4.1:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- New transformation API (:issue:`3009`)
|
||||
|
||||
@@ -104,7 +104,7 @@ Deprecated
|
||||
- ``ndn::crypto::sha256`` in favor of ``ndn::crypto::computeSha256Digest``
|
||||
|
||||
- ``security/cryptopp.hpp`` header. Use ``security/v1/cryptopp.hpp`` when needed, avoid direct
|
||||
include as CryptoPP dependency may be removed from future versions of the library.
|
||||
include as CryptoPP dependency will be removed from future versions of the library.
|
||||
|
||||
- ``security/identity-certificate.hpp`` header. Use ``security/v1/identity-certificate.hpp`` instead.
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ Release date: January 25, 2017
|
||||
|
||||
Changes since version 0.5.0:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Add version 2 of the security framework (introduced in ``security::v2`` namespace)
|
||||
|
||||
|
||||
@@ -5,18 +5,18 @@ Release date: October 16, 2017
|
||||
|
||||
Changes since version 0.5.1:
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- **breaking change** Security framework version 2 (:issue:`3098`, :issue:`3920`,
|
||||
:issue:`3644`, :issue:`4085`, :issue:`4323`, :issue:`4339`)
|
||||
- **(breaking change)** Security framework version 2 (:issue:`3098`, :issue:`3920`,
|
||||
:issue:`3644`, :issue:`4085`, :issue:`4323`, :issue:`4339`).
|
||||
|
||||
The released version of the library only supports the new version of the security (v2
|
||||
certificate format) and features a number of updates of KeyChain and Validator
|
||||
interfaces. At the same time, management APIs for :ndn-cxx:`ValidatorConfig` remained
|
||||
intact; transition to the new framework would require only adjusting
|
||||
:ndn-cxx:`Validator::validate` calls and updating configuration files to follow the new
|
||||
naming conventions of :ref:`NDN Certificate Format Version 2.0`.
|
||||
The released version of the library only supports the new version of the security (v2
|
||||
certificate format) and features a number of updates of KeyChain and Validator
|
||||
interfaces. At the same time, management APIs for :ndn-cxx:`ValidatorConfig` remained
|
||||
intact; transition to the new framework would require only adjusting
|
||||
:ndn-cxx:`Validator::validate` calls and updating configuration files to follow the new
|
||||
naming conventions of :ref:`NDN Certificate Format Version 2.0`.
|
||||
|
||||
- Integration of fetching certificates using Certificate Bundle as part of specialized
|
||||
``CertificateFetcher`` (:issue:`3891`)
|
||||
|
||||
@@ -3,8 +3,8 @@ ndn-cxx version 0.6.1
|
||||
|
||||
Release date: February 19, 2018
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- (potentially breaking change) :ndn-cxx:`expressInterest` now by default loopbacks Interests to
|
||||
producer callbacks on the same :ndn-cxx:`Face`. When undesired, use
|
||||
@@ -13,50 +13,40 @@ New features:
|
||||
- New signal in :ndn-cxx:`SegmentFetcher` to notify retrieval of Data segments
|
||||
(:issue:`4438`)
|
||||
|
||||
- Initial support for the Content Store management protocol
|
||||
(:issue:`4050`)
|
||||
- Initial support for the Content Store management protocol (:issue:`4050`)
|
||||
|
||||
- Literal operators for ``time::duration`` types, such as ``1_s``, ``42_ms``, ``30_days``
|
||||
(:issue:`4468`)
|
||||
|
||||
- Support for BLAKE2 hash function (requires OpenSSL >= 1.1.0)
|
||||
|
||||
- A ``escape()`` helper function complementing the existing ``unescape()`` (:issue:`4484`)
|
||||
- An ``escape()`` helper function complementing the existing ``unescape()`` (:issue:`4484`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- ``ndnsec key-gen`` command line now allows customization of key ID (:issue:`4294`)
|
||||
|
||||
- Fixed encoding of ``'~'`` and ``'+'`` in :ndn-cxx:`Component::toUri()`
|
||||
(:issue:`4484`)
|
||||
- Fixed encoding of ``'~'`` and ``'+'`` in ``name::Component::toUri()`` (:issue:`4484`)
|
||||
|
||||
- Fixed handling of large dates when converting to/from string
|
||||
(:issue:`4478`, :issue:`3915`)
|
||||
- Fixed handling of large dates when converting to/from string (:issue:`4478`, :issue:`3915`)
|
||||
|
||||
- Fixed error handling in :ndn-cxx:`KeyChain::importSafeBag()`
|
||||
(:issue:`4359`)
|
||||
- Fixed error handling in ``KeyChain::importSafeBag()`` (:issue:`4359`)
|
||||
|
||||
- Fixed parsing of IPv6 addresses with scope-id
|
||||
(:issue:`4474`)
|
||||
- Fixed parsing of IPv6 addresses with scope-id (:issue:`4474`)
|
||||
|
||||
- :ndn-cxx:`io::load()` now handles empty files properly
|
||||
(:issue:`4434`)
|
||||
- ``io::load()`` now handles empty files properly (:issue:`4434`)
|
||||
|
||||
- Switched to using `boost::asio::basic_waitable_timer`
|
||||
(:issue:`4431`)
|
||||
- Switched to using ``boost::asio::basic_waitable_timer`` (:issue:`4431`)
|
||||
|
||||
- Allow linking multiple :ndn-cxx:`DummyClientFace` instances together to emulate a broadcast medium
|
||||
(:issue:`3913`)
|
||||
- Allow linking multiple :ndn-cxx:`DummyClientFace` instances together to emulate a broadcast
|
||||
medium (:issue:`3913`)
|
||||
|
||||
- Fixed build when ``std::to_string`` is not available
|
||||
(:issue:`4393`)
|
||||
- Fixed build when ``std::to_string`` is not available (:issue:`4393`)
|
||||
|
||||
- Avoid undefined behavior when casting to :ndn-cxx:`tlv::SignatureTypeValue`
|
||||
(:issue:`4370`)
|
||||
- Avoid undefined behavior when casting to :ndn-cxx:`tlv::SignatureTypeValue` (:issue:`4370`)
|
||||
|
||||
- Fixed compilation with Boost 1.66.0
|
||||
(:issue:`4422`)
|
||||
- Fixed compilation with Boost 1.66.0 (:issue:`4422`)
|
||||
|
||||
- Various documentation updates
|
||||
(:issue:`3918`, :issue: `4184`, :issue: `4275`)
|
||||
@@ -64,6 +54,4 @@ Improvements and bug fixes
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
- Removed obsolete TLV-TYPE constants
|
||||
(:issue:`4055`, :issue:`3098`, :issue: `3755`)
|
||||
|
||||
- Removed obsolete TLV-TYPE constants (:issue:`4055`, :issue:`3098`, :issue: `3755`)
|
||||
@@ -3,11 +3,11 @@ ndn-cxx version 0.6.2
|
||||
|
||||
Release date: May 4, 2018
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Initial support for [NDN packet format version
|
||||
0.3](https://named-data.net/doc/NDN-packet-spec/0.3/) (:issue:`4527`)
|
||||
- Initial support for `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
|
||||
* Recognize typed name components, allow typed name component in ``FinalBlockId``
|
||||
(:issue:`4526`)
|
||||
@@ -41,7 +41,7 @@ Improvements and bug fixes
|
||||
- Logging system improvements (:issue:`4552`)
|
||||
|
||||
Deprecated
|
||||
~~~~~~~~~~
|
||||
^^^^^^^^^^
|
||||
|
||||
- Selectors (:issue:`4527`)
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@ that use distribution-provided compilers and packages.
|
||||
|
||||
The compilation now uses the C++14 standard.
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- More support for `NDN packet format version
|
||||
0.3 <https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
- More support for `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
|
||||
- Allow applications to declare a default ``CanBePrefix`` setting (:issue:`4581`)
|
||||
|
||||
@@ -67,7 +67,7 @@ Improvements and bug fixes
|
||||
- Correct and improve documentation
|
||||
|
||||
Deprecated
|
||||
~~~~~~~~~~
|
||||
^^^^^^^^^^
|
||||
|
||||
- ``SegmentFetcher::fetch()`` static functions in favor of ``start()`` (:issue:`4464`)
|
||||
|
||||
@@ -83,6 +83,6 @@ Deprecated
|
||||
- ``Data::get/setFinalBlockId()`` in favor of ``Data::get/setFinalBlock()``
|
||||
|
||||
Removed
|
||||
~~~~~~~
|
||||
^^^^^^^
|
||||
|
||||
- Dependency on Boost.Regex in favor of ``std::regex``
|
||||
@@ -3,8 +3,8 @@ ndn-cxx version 0.6.5
|
||||
|
||||
Release date: February 4, 2019
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- More support for `NDN packet format version
|
||||
0.3 <https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
@@ -58,7 +58,7 @@ Improvements and bug fixes
|
||||
- Reimplement ``scheduler::EventId`` with ``CancelHandle`` (:issue:`4698`)
|
||||
|
||||
Deprecated
|
||||
~~~~~~~~~~
|
||||
^^^^^^^^^^
|
||||
|
||||
- ``ndn-cxx/util/scheduler-scoped-event-id.hpp`` header as it is now sufficient to use
|
||||
``ndn-cxx/util/scheduler.hpp`` header (:issue:`4698`)
|
||||
@@ -66,7 +66,7 @@ Deprecated
|
||||
- Implicit conversion from nullptr to ``scheduler::EventId`` (:issue:`4698`)
|
||||
|
||||
Removed
|
||||
~~~~~~~
|
||||
^^^^^^^
|
||||
|
||||
- ``ndn::ip::address{,V6}FromString``
|
||||
|
||||
|
||||
@@ -3,16 +3,17 @@ ndn-cxx version 0.6.6
|
||||
|
||||
Release date: April 27, 2019
|
||||
|
||||
Note that this is the last release that encodes to `NDN packet format version 0.2.1
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.2.1/>`__. A future release will continue to
|
||||
decode v0.2.1 format, but will encode to `v0.3 format
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__.
|
||||
.. note::
|
||||
This is the last release to support the `NDN packet format version 0.2.1
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.2.1/>`__.
|
||||
The next release will be able to encode and decode only the `v0.3 packet format
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__.
|
||||
|
||||
New features:
|
||||
^^^^^^^^^^^^^
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- More support for `NDN packet format version
|
||||
0.3 <https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
- More support for `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
|
||||
* Support new naming conventions to encode/decode segment numbers, byte offsets, versions,
|
||||
timestamps, and sequence numbers based on typed name components (:issue:`4777`)
|
||||
@@ -34,7 +35,8 @@ Improvements and bug fixes
|
||||
``ApplicationParameters`` and to change its number to be a non-critical element type
|
||||
(:issue:`4658`, :issue:`4780`)
|
||||
|
||||
- Add option to disable infrastructure interest in ``CertificateFetcherDirectFetch`` (:issue:`4879`)
|
||||
- Add an option to disable the infrastructure Interest in ``CertificateFetcherDirectFetch``
|
||||
(:issue:`4879`)
|
||||
|
||||
- Fix compilation against recent versions of Boost libraries and issues with Xcode 10.2 and
|
||||
older versions of Boost libraries (:issue:`4890`, :issue:`4923`, :issue:`4860`)
|
||||
@@ -44,7 +46,7 @@ Improvements and bug fixes
|
||||
- Improve documentation
|
||||
|
||||
Deprecated
|
||||
~~~~~~~~~~
|
||||
^^^^^^^^^^
|
||||
|
||||
- ``PendingInterestId``, ``RegisteredPrefixId``, and ``InterestFilterId`` types in favor of
|
||||
``PendingInterestHandle``, ``RegisteredPrefixHandle``, and ``InterestFilterHandle``
|
||||
|
||||
@@ -8,9 +8,9 @@ Release date: January 13, 2020
|
||||
This release features support of only `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`, :issue:`4567`,
|
||||
:issue:`4709`, :issue:`4913`). The library encodes and interprets Interest and Data
|
||||
packets only in 0.3 format; support for version 0.2 has been completely removed. In
|
||||
addition, the URI representation of Interest packets has also been changed following the
|
||||
packet format updates.
|
||||
packets only in 0.3 format; support for version 0.2 has been completely removed. In
|
||||
addition, the URI representation of Interest packets has been updated to follow the
|
||||
packet format changes.
|
||||
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
ndn-cxx version 0.7.1
|
||||
---------------------
|
||||
|
||||
Release date: October 8, 2020
|
||||
|
||||
The build requirements have been increased to require Clang >= 4.0, Xcode >= 9.0, and Python >= 3.6.
|
||||
Meanwhile, it is *recommended* to use GCC >= 7.4.0 and Boost >= 1.65.1.
|
||||
This effectively drops official support for Ubuntu 16.04 when using distribution-provided Boost
|
||||
packages -- ndn-cxx may still work on this platform, but we provide no official support for it.
|
||||
Additionally, this release drops support for CentOS 7 and adds support for CentOS 8.
|
||||
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Signed Interests according to Packet Specification v0.3 (:issue:`4804`)
|
||||
|
||||
- Add "in-order" mode to ``SegmentFetcher`` and a corresponding signal that is emitted after each
|
||||
segment is received and validated in segment order. Segments that arrive out-of-order will be
|
||||
buffered internally until all earlier segments have arrived and passed validation.
|
||||
|
||||
- Allow ``KeyLocator`` to either identify the full name of a certificate, an unversioned certificate
|
||||
prefix, or the name of a public key (without issuer and version) (:issue:`5115`)
|
||||
|
||||
- Allow face MTU to be changed via management (:issue:`5056`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Change default key type generated by ndnsec to ECDSA
|
||||
|
||||
- Use named curve when encoding ECDSA public keys (:issue:`5037`)
|
||||
|
||||
- Allow non-default key to be exported for an identity via ``ndnsec-export`` (:issue:`5043`)
|
||||
|
||||
- Fix spurious error message from ``ndnsec-key-gen`` when ``key-id`` is specified (:issue:`5057`)
|
||||
|
||||
- Provide more fine-grained choices for ``name::UriFormat`` (:issue:`4777`)
|
||||
|
||||
- Allow automatic log flushing to be disabled (:issue:`3668`)
|
||||
|
||||
- Avoid unnecessarily invalidating cached wire encodings of Data packets
|
||||
|
||||
- Correct extraction of signed portion of Data packets to be compatible with Packet Specification
|
||||
v0.3 (:issue:`4583`)
|
||||
|
||||
- Fix regression in ``CertificateBundleFetcher`` with ``FinalBlockId`` handling
|
||||
|
||||
- Improve error handling during TPM signing (:issue:`4585`, :issue:`5086`)
|
||||
|
||||
- Correctly handle non-existent identity in ``PibImpl::setDefaultIdentity``
|
||||
|
||||
- Fix incompatibility with ``time::toIsoString`` in Boost 1.73.0+
|
||||
|
||||
- Fix incompatibility with ``<version>`` header in C++20
|
||||
|
||||
- Various fixes for Android
|
||||
|
||||
- Various improvements to documentation, test suite structure, and authors list
|
||||
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Deprecate old Signed Interest and Command Interest formats (:issue:`4804`)
|
||||
|
||||
- Deprecate ``Signature`` in favor of ``SignatureInfo`` in Data packets and certificates (:issue:`4804`)
|
||||
|
||||
- ``SignatureInfo::unsetKeyLocator`` and ``SignatureInfo::unsetValidityPeriod`` have been deprecated
|
||||
|
||||
- Header files under ``ndn/security/v2`` have been moved into the main ``ndn/security`` directory
|
||||
|
||||
Removals
|
||||
^^^^^^^^
|
||||
|
||||
- Remove deprecated ``PendingInterestId``, ``InterestFilterId``, and ``RegisteredPrefixId``
|
||||
(:issue:`4885`)
|
||||
|
||||
- Remove a number of long-deprecated functions and enums
|
||||
@@ -5,6 +5,7 @@ All ndn-cxx Releases
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
|
||||
release-notes/release-notes-0.7.1
|
||||
release-notes/release-notes-0.7.0
|
||||
release-notes/release-notes-0.6.6
|
||||
release-notes/release-notes-0.6.5
|
||||
@@ -24,6 +25,12 @@ All ndn-cxx Releases
|
||||
release-notes/release-notes-0.2.0
|
||||
release-notes/release-notes-0.1.0
|
||||
|
||||
* **ndn-cxx version 0.7.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.7.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.7.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.7.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.7.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.7.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.7.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.7.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.7.0/>`__)
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
NDN Certificate Format Version 2.0
|
||||
==================================
|
||||
|
||||
.. contents::
|
||||
|
||||
Since signature verification is a common operation in NDN applications, it is
|
||||
important to define a common certificate format to standardize the public key
|
||||
authentication procedure. As every NDN data packet is signed, a data packet
|
||||
@@ -46,27 +44,26 @@ specification.
|
||||
| SignatureValue |
|
||||
+--------------------------+
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
CertificateV2 = DATA-TYPE TLV-LENGTH
|
||||
Name ; /<NameSpace>/KEY/[KeyId]/[IssuerId]/[Version]
|
||||
MetaInfo ; ContentType = KEY, FreshnessPeriod required
|
||||
Content ; X509PublicKey
|
||||
CertificateV2SignatureInfo
|
||||
SignatureValue
|
||||
CertificateV2 = DATA-TYPE TLV-LENGTH
|
||||
Name ; /<NameSpace>/KEY/[KeyId]/[IssuerId]/[Version]
|
||||
MetaInfo ; ContentType == KEY, FreshnessPeriod required
|
||||
Content ; X509PublicKey
|
||||
CertificateV2SignatureInfo
|
||||
SignatureValue
|
||||
|
||||
CertificateV2SignatureInfo = SIGNATURE-INFO-TYPE TLV-LENGTH
|
||||
SignatureType
|
||||
KeyLocator
|
||||
ValidityPeriod
|
||||
*CertificateV2Extension
|
||||
CertificateV2SignatureInfo = SIGNATURE-INFO-TYPE TLV-LENGTH
|
||||
SignatureType
|
||||
KeyLocator
|
||||
ValidityPeriod
|
||||
*CertificateV2Extension
|
||||
|
||||
|
||||
Name
|
||||
----
|
||||
|
||||
The name of a certificate consists of five parts as shown below:
|
||||
|
||||
::
|
||||
The name of a certificate consists of five parts as shown below::
|
||||
|
||||
/<SubjectName>/KEY/[KeyId]/[IssuerId]/[Version]
|
||||
|
||||
@@ -82,17 +79,13 @@ identifier.
|
||||
controlled by the certificate issuer and, similar to KeyId, can be an 8-byte random number,
|
||||
SHA-256 digest of the issuer's public key, or a simple numerical identifier.
|
||||
|
||||
|
||||
For example,
|
||||
|
||||
::
|
||||
For example::
|
||||
|
||||
/edu/ucla/cs/yingdi/KEY/%03%CD...%F1/%9F%D3...%B7/%FD%d2...%8E
|
||||
\_________________/ \___________/ \___________/\___________/
|
||||
Certificate Namespace Key Id Issuer Id Version
|
||||
(Identity)
|
||||
|
||||
|
||||
MetaInfo
|
||||
--------
|
||||
|
||||
@@ -120,7 +113,7 @@ certificate expires.
|
||||
Using ISO style string is the convention of specifying the validity period of certificate,
|
||||
which has been adopted by many certificate systems, such as X.509, PGP, and DNSSEC.
|
||||
|
||||
::
|
||||
.. code-block:: abnf
|
||||
|
||||
ValidityPeriod = VALIDITY-PERIOD-TYPE TLV-LENGTH
|
||||
NotBefore
|
||||
@@ -180,7 +173,7 @@ key-value pairs. Both key and value are UTF-8 strings, e.g.,
|
||||
``("Organization", "UCLA")``. The issuer of a certificate can specify arbitrary
|
||||
key-value pair to provide additional description about the certificate.
|
||||
|
||||
::
|
||||
.. code-block:: abnf
|
||||
|
||||
CertificateV2Extension = AdditionalDescription
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
Export/Import Credentials
|
||||
=========================
|
||||
SafeBag Format for Exported Credentials
|
||||
=======================================
|
||||
|
||||
Sometimes, one may need to export credentials (e.g., certificate and private key) from
|
||||
one machine, and import them into another machine. This requires a secured container for
|
||||
sensitive information. We define **SafeBag**, which contains both an NDN certificate
|
||||
(:doc:`version 2.0 <certificate-format>`) and the corresponding private
|
||||
key which is encrypted in `PKCS#8 format <https://tools.ietf.org/html/rfc5208>`_.
|
||||
key, which is encrypted in `PKCS #8 format <https://tools.ietf.org/html/rfc5208>`_.
|
||||
|
||||
The format of **SafeBag** is defined as:
|
||||
|
||||
::
|
||||
.. code-block:: abnf
|
||||
|
||||
SafeBag = SAFE-BAG-TYPE TLV-LENGTH
|
||||
CertificateV2 ; a data packet following certificate format spec
|
||||
CertificateV2
|
||||
EncryptedKeyBag
|
||||
|
||||
EncryptedKeyBag = ENCRYPTED-KEY-BAG-TYPE TLV-LENGTH
|
||||
*OCTET ; private key encrypted in PKCS#8 format
|
||||
*OCTET ; private key encrypted in PKCS #8 format
|
||||
|
||||
All TLV-TYPE codes are application specific:
|
||||
All TLV-TYPE numbers are application specific:
|
||||
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| TLV-TYPE | Assigned number | Assigned number|
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
.. _Signed Interest:
|
||||
|
||||
Signed Interest
|
||||
===============
|
||||
Signed Interest Version 0.2 (DEPRECATED)
|
||||
========================================
|
||||
|
||||
.. warning::
|
||||
This document describes a deprecated format for signed Interest packets. The current format can
|
||||
be found in the
|
||||
`NDN Packet Specification <https://named-data.net/doc/NDN-packet-spec/current/signed-interest.html>`__.
|
||||
|
||||
**Signed Interest** is a mechanism to issue an authenticated interest.
|
||||
|
||||
@@ -13,7 +18,7 @@ penultimate name component TLV:
|
||||
|
||||
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||
| Interest | Interest | +------+--------+--------------------------------------------------+ +----------+ |
|
||||
| Type (0x01) | length | | Name | Name | +---------+-- --+---------+---------+---------+| | Other | |
|
||||
| Type (0x05) | length | | Name | Name | +---------+-- --+---------+---------+---------+| | Other | |
|
||||
| | | | Type | Length | |Component| ... |Component|Component|Component|| | TLVs ... | |
|
||||
| | | | | | | TLV 1 | | TLV n-2 | TLV n-1 | TLV n || | in | |
|
||||
| | | | | | +---------+-- --+---------+---------+---------+| | Interest | |
|
||||
@@ -27,14 +32,12 @@ penultimate name component TLV:
|
||||
|
||||
More specifically, the SignedInterest is defined to have four additional components:
|
||||
|
||||
- ``<timestamp>``
|
||||
- ``<nonce>``
|
||||
- ``<SignatureInfo>``
|
||||
- ``<SignatureValue>``
|
||||
- ``timestamp``
|
||||
- ``nonce``
|
||||
- ``SignatureInfo``
|
||||
- ``SignatureValue``
|
||||
|
||||
For example, for ``/signed/interest/name`` name, CommandInterest will be defined as:
|
||||
|
||||
::
|
||||
For example, for ``/signed/interest/name`` name, CommandInterest will be defined as::
|
||||
|
||||
/signed/interest/name/<timestamp>/<random-value>/<SignatureInfo>/<SignatureValue>
|
||||
|
||||
@@ -51,21 +54,21 @@ Timestamp component (n-3 *th*)
|
||||
|
||||
The value of the n-3 *th* component is the interest's timestamp (in terms of millisecond offset
|
||||
from UTC 1970-01-01 00:00:00) encoded as
|
||||
`nonNegativeInteger <http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding>`__.
|
||||
`NonNegativeInteger <https://named-data.net/doc/NDN-packet-spec/0.2.1/tlv.html#non-negative-integer-encoding>`__.
|
||||
The timestamp may be used to protect against replay attack.
|
||||
|
||||
Nonce component (n-2 *th*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The value of the n-2 *th* component is random value (encoded as
|
||||
`nonNegativeInteger <http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding>`__)
|
||||
`NonNegativeInteger <https://named-data.net/doc/NDN-packet-spec/0.2.1/tlv.html#non-negative-integer-encoding>`__)
|
||||
that adds additional assurances that the interest will be unique.
|
||||
|
||||
SignatureInfo component (n-1 *th*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The value of the n-1 *th* component is actually a
|
||||
`SignatureInfo <http://named-data.net/doc/ndn-tlv/signature.html>`__ TLV.
|
||||
`SignatureInfo <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
|
||||
|
||||
::
|
||||
|
||||
@@ -83,7 +86,7 @@ SignatureValue component (n *th*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The value of the n *th* component is actually a
|
||||
`SignatureValue <http://named-data.net/doc/ndn-tlv/signature.html>`__ TLV.
|
||||
`SignatureValue <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
|
||||
|
||||
::
|
||||
|
||||
@@ -108,7 +111,7 @@ be signed, it will be treated as invalid in the following three cases:
|
||||
missing or cannot be parsed correctly;
|
||||
- the key is not trusted for signing the Interest;
|
||||
- the signature cannot be verified with the public key pointed by the
|
||||
`KeyLocator <http://named-data.net/doc/ndn-tlv/signature.html#keylocator>`__ in
|
||||
`KeyLocator <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html#keylocator>`__ in
|
||||
SignatureInfo.
|
||||
|
||||
Recipients of a signed interest may further check the timestamp and the uniqueness of the
|
||||
|
||||
@@ -51,8 +51,7 @@ configuration file containing two rules and a trust anchor.
|
||||
file-name "testbed-trust-anchor.cert"
|
||||
}
|
||||
|
||||
.. note::
|
||||
**ATTENTION: The order of rules MATTERS!**
|
||||
.. attention:: **The order of rules MATTERS!**
|
||||
|
||||
A rule can be broken into two parts:
|
||||
|
||||
@@ -97,8 +96,7 @@ rule. The filter property is not required in a rule; if omitted, the rule will c
|
||||
packets passed to it. A rule may contain multiple filters, in this case, a packet
|
||||
is captured by the rule only if all filters are satisfied.
|
||||
|
||||
.. note::
|
||||
**ATTENTION: A packet that satisfies all the filters may not be valid**.
|
||||
.. attention:: **A packet that satisfies all the filters may not be valid.**
|
||||
|
||||
The **checker** property defines the conditions that a matched packet must fulfill to be
|
||||
treated as a valid packet. A rule must have at least one **checker** property. A packet is
|
||||
@@ -377,9 +375,9 @@ period, such as
|
||||
There is also a special trust anchor **any**. As long as such a trust-anchor is defined
|
||||
in config file, packet validation will be turned off.
|
||||
|
||||
.. note::
|
||||
**ATTENTION: This type of trust anchor is dangerous. You should used it only when you
|
||||
want to disable packet validation temporarily (e.g, debugging code, building a demo).**
|
||||
.. danger::
|
||||
This type of trust anchor is dangerous. You should used it only when you
|
||||
want to disable packet validation temporarily (e.g., debugging code, building a demo).
|
||||
|
||||
::
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ NDN regular expression is a kind of regular expression that can match NDN names.
|
||||
performed at two levels: the name level and the name component level.
|
||||
|
||||
A name component matcher, enclosed in ``<`` and ``>``, specifies the pattern of a name component. The
|
||||
component pattern is expressed with the `Perl Regular Expression Syntax
|
||||
<https://www.boost.org/doc/libs/1_58_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html>`__.
|
||||
component pattern is expressed using the `Modified ECMAScript Regular Expression Syntax
|
||||
<https://en.cppreference.com/w/cpp/regex/ecmascript>`_.
|
||||
For example, ``<ab*c>`` matches the 1st, 3rd, and 4th components of ``/ac/dc/abc/abbc``, but does
|
||||
not match the 2nd component. A special case is that ``<>`` denotes a wildcard matcher that can match
|
||||
**ANY** name component.
|
||||
|
||||
+197
-70
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -20,8 +20,9 @@
|
||||
*/
|
||||
|
||||
#include "ndn-cxx/data.hpp"
|
||||
#include "ndn-cxx/encoding/block-helpers.hpp"
|
||||
#include "ndn-cxx/signature.hpp"
|
||||
#include "ndn-cxx/util/sha256.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
@@ -34,7 +35,6 @@ static_assert(std::is_base_of<tlv::Error, Data::Error>::value,
|
||||
|
||||
Data::Data(const Name& name)
|
||||
: m_name(name)
|
||||
, m_content(tlv::Content)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -47,34 +47,51 @@ template<encoding::Tag TAG>
|
||||
size_t
|
||||
Data::wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly) const
|
||||
{
|
||||
// Data ::= DATA-TLV TLV-LENGTH
|
||||
// Name
|
||||
// MetaInfo?
|
||||
// Content?
|
||||
// SignatureInfo
|
||||
// SignatureValue
|
||||
// Data = DATA-TYPE TLV-LENGTH
|
||||
// Name
|
||||
// [MetaInfo]
|
||||
// [Content]
|
||||
// [ServiceClass]
|
||||
// [TargetRate]
|
||||
// SignatureInfo
|
||||
// SignatureValue
|
||||
// (elements are encoded in reverse order)
|
||||
|
||||
size_t totalLength = 0;
|
||||
|
||||
// SignatureValue
|
||||
if (!wantUnsignedPortionOnly) {
|
||||
if (!m_signature) {
|
||||
if (!m_signatureInfo) {
|
||||
NDN_THROW(Error("Requested wire format, but Data has not been signed"));
|
||||
}
|
||||
totalLength += encoder.prependBlock(m_signature.getValue());
|
||||
totalLength += encoder.prependBlock(m_signatureValue);
|
||||
}
|
||||
|
||||
// SignatureInfo
|
||||
totalLength += encoder.prependBlock(m_signature.getInfo());
|
||||
totalLength += m_signatureInfo.wireEncode(encoder, SignatureInfo::Type::Data);
|
||||
|
||||
// TargetRate
|
||||
if (getTargetRate()) {
|
||||
uint64_t targetRate = *getTargetRate();
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::TargetRate, reinterpret_cast<uint8_t*>(&targetRate), sizeof(targetRate));
|
||||
}
|
||||
|
||||
// ServiceClass
|
||||
if (getServiceClass()) {
|
||||
uint8_t serviceClass = *getServiceClass();
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::ServiceClass, reinterpret_cast<uint8_t*>(&serviceClass), sizeof(serviceClass));
|
||||
}
|
||||
|
||||
// Content
|
||||
totalLength += encoder.prependBlock(getContent());
|
||||
if (hasContent()) {
|
||||
totalLength += encoder.prependBlock(m_content);
|
||||
}
|
||||
|
||||
// MetaInfo
|
||||
totalLength += getMetaInfo().wireEncode(encoder);
|
||||
totalLength += m_metaInfo.wireEncode(encoder);
|
||||
|
||||
// Name
|
||||
totalLength += getName().wireEncode(encoder);
|
||||
totalLength += m_name.wireEncode(encoder);
|
||||
|
||||
if (!wantUnsignedPortionOnly) {
|
||||
totalLength += encoder.prependVarNumber(totalLength);
|
||||
@@ -121,29 +138,36 @@ Data::wireEncode() const
|
||||
void
|
||||
Data::wireDecode(const Block& wire)
|
||||
{
|
||||
// Data ::= DATA-TLV TLV-LENGTH
|
||||
// Name
|
||||
// MetaInfo?
|
||||
// Content?
|
||||
// SignatureInfo
|
||||
// SignatureValue
|
||||
|
||||
if (wire.type() != tlv::Data) {
|
||||
NDN_THROW(Error("Data", wire.type()));
|
||||
}
|
||||
m_wire = wire;
|
||||
m_wire.parse();
|
||||
|
||||
// Data = DATA-TYPE TLV-LENGTH
|
||||
// Name
|
||||
// [MetaInfo]
|
||||
// [Content]
|
||||
// [ServiceClass]
|
||||
// [TargetRate]
|
||||
// SignatureInfo
|
||||
// SignatureValue
|
||||
|
||||
auto element = m_wire.elements_begin();
|
||||
if (element == m_wire.elements_end() || element->type() != tlv::Name) {
|
||||
NDN_THROW(Error("Name element is missing or out of order"));
|
||||
}
|
||||
m_name.wireDecode(*element);
|
||||
int lastElement = 1; // last recognized element index, in spec order
|
||||
|
||||
m_metaInfo = MetaInfo();
|
||||
m_content = Block(tlv::Content);
|
||||
m_signature = Signature();
|
||||
m_metaInfo = {};
|
||||
m_content = {};
|
||||
m_signatureInfo = {};
|
||||
m_signatureValue = {};
|
||||
m_fullName.clear();
|
||||
|
||||
int lastElement = 1; // last recognized element index, in spec order
|
||||
for (++element; element != m_wire.elements_end(); ++element) {
|
||||
// std::cout << "element: " << element->type() << std::endl;
|
||||
switch (element->type()) {
|
||||
case tlv::MetaInfo: {
|
||||
if (lastElement >= 2) {
|
||||
@@ -161,34 +185,64 @@ Data::wireDecode(const Block& wire)
|
||||
lastElement = 3;
|
||||
break;
|
||||
}
|
||||
case tlv::SignatureInfo: {
|
||||
case tlv::ServiceClass: {
|
||||
if (lastElement >= 4) {
|
||||
NDN_THROW(Error("SignatureInfo element is out of order"));
|
||||
break; // ServiceClass is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
m_signature.setInfo(*element);
|
||||
if (element->value_size() != 1) {
|
||||
NDN_THROW(Error("ServiceClass element is malformed"));
|
||||
}
|
||||
m_serviceClass = *element->value();
|
||||
lastElement = 4;
|
||||
break;
|
||||
}
|
||||
case tlv::SignatureValue: {
|
||||
case tlv::TargetRate: {
|
||||
if (lastElement >= 5) {
|
||||
NDN_THROW(Error("SignatureValue element is out of order"));
|
||||
break; // TargetRate is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
m_signature.setValue(*element);
|
||||
uint64_t targetRate = 0;
|
||||
if (element->value_size() != 8) {
|
||||
NDN_THROW(Error("TargetRate element is malformed"));
|
||||
}
|
||||
std::memcpy(&targetRate, element->value(), sizeof(targetRate));
|
||||
m_targetRate = targetRate;
|
||||
lastElement = 5;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (tlv::isCriticalType(element->type())) {
|
||||
NDN_THROW(Error("unrecognized element of critical type " + to_string(element->type())));
|
||||
case tlv::SignatureInfo: {
|
||||
if (lastElement >= 6) {
|
||||
NDN_THROW(Error("SignatureInfo element is out of order"));
|
||||
}
|
||||
m_signatureInfo.wireDecode(*element);
|
||||
lastElement = 6;
|
||||
break;
|
||||
}
|
||||
case tlv::SignatureValue: {
|
||||
if (lastElement >= 7) {
|
||||
NDN_THROW(Error("SignatureValue element is out of order"));
|
||||
}
|
||||
m_signatureValue = *element;
|
||||
lastElement = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
default: { // unrecognized element
|
||||
// if the TLV-TYPE is critical, abort decoding
|
||||
if (tlv::isCriticalType(element->type())) {
|
||||
NDN_THROW(Error("Unrecognized element of critical type " + to_string(element->type())));
|
||||
}
|
||||
// otherwise, ignore it
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_signature) {
|
||||
if (!m_signatureInfo) {
|
||||
NDN_THROW(Error("SignatureInfo element is missing"));
|
||||
}
|
||||
if (!m_signatureValue.isValid()) {
|
||||
NDN_THROW(Error("SignatureValue element is missing"));
|
||||
}
|
||||
}
|
||||
|
||||
const Name&
|
||||
@@ -215,32 +269,27 @@ Data::resetWire()
|
||||
Data&
|
||||
Data::setName(const Name& name)
|
||||
{
|
||||
resetWire();
|
||||
m_name = name;
|
||||
if (name != m_name) {
|
||||
m_name = name;
|
||||
resetWire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setMetaInfo(const MetaInfo& metaInfo)
|
||||
{
|
||||
resetWire();
|
||||
m_metaInfo = metaInfo;
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Block&
|
||||
Data::getContent() const
|
||||
{
|
||||
if (!m_content.hasWire()) {
|
||||
const_cast<Block&>(m_content).encode();
|
||||
}
|
||||
return m_content;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContent(const Block& block)
|
||||
{
|
||||
resetWire();
|
||||
if (!block.isValid()) {
|
||||
NDN_THROW(std::invalid_argument("Content block must be valid"));
|
||||
}
|
||||
|
||||
if (block.type() == tlv::Content) {
|
||||
m_content = block;
|
||||
@@ -248,63 +297,138 @@ Data::setContent(const Block& block)
|
||||
else {
|
||||
m_content = Block(tlv::Content, block);
|
||||
}
|
||||
|
||||
m_content.encode();
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContent(const uint8_t* value, size_t valueSize)
|
||||
Data::setContent(const uint8_t* value, size_t length)
|
||||
{
|
||||
if (value == nullptr && length != 0) {
|
||||
NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
|
||||
}
|
||||
|
||||
m_content = makeBinaryBlock(tlv::Content, value, length);
|
||||
resetWire();
|
||||
m_content = makeBinaryBlock(tlv::Content, value, valueSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContent(ConstBufferPtr value)
|
||||
{
|
||||
resetWire();
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
|
||||
}
|
||||
|
||||
m_content = Block(tlv::Content, std::move(value));
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::unsetContent()
|
||||
{
|
||||
m_content = {};
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Signature
|
||||
Data::getSignature() const
|
||||
{
|
||||
return Signature(m_signatureInfo, m_signatureValue);
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setSignature(const Signature& signature)
|
||||
{
|
||||
m_signatureInfo = signature.getSignatureInfo();
|
||||
m_signatureValue = signature.getValue();
|
||||
resetWire();
|
||||
m_signature = signature;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setSignatureValue(const Block& value)
|
||||
Data::setSignatureInfo(const SignatureInfo& info)
|
||||
{
|
||||
m_signatureInfo = info;
|
||||
resetWire();
|
||||
m_signature.setValue(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setSignatureValue(ConstBufferPtr value)
|
||||
{
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be nullptr"));
|
||||
}
|
||||
|
||||
m_signatureValue = Block(tlv::SignatureValue, std::move(value));
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputBuffers
|
||||
Data::extractSignedRanges() const
|
||||
{
|
||||
InputBuffers bufs;
|
||||
bufs.reserve(1); // One range containing data value up to, but not including, SignatureValue
|
||||
|
||||
wireEncode();
|
||||
auto lastSignedIt = std::prev(m_wire.find(tlv::SignatureValue));
|
||||
bufs.emplace_back(m_wire.value(),
|
||||
std::distance(m_wire.value_begin(), lastSignedIt->end()));
|
||||
return bufs;
|
||||
}
|
||||
|
||||
const Data&
|
||||
Data::setServiceClass(optional<uint8_t> serviceClass) const
|
||||
{
|
||||
if (m_serviceClass != serviceClass) {
|
||||
m_serviceClass = serviceClass;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Data&
|
||||
Data::setTargetRate(optional<uint64_t> targetRate) const
|
||||
{
|
||||
if (m_targetRate != targetRate) {
|
||||
m_targetRate = targetRate;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContentType(uint32_t type)
|
||||
{
|
||||
resetWire();
|
||||
m_metaInfo.setType(type);
|
||||
if (type != m_metaInfo.getType()) {
|
||||
m_metaInfo.setType(type);
|
||||
resetWire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setFreshnessPeriod(time::milliseconds freshnessPeriod)
|
||||
{
|
||||
resetWire();
|
||||
m_metaInfo.setFreshnessPeriod(freshnessPeriod);
|
||||
if (freshnessPeriod != m_metaInfo.getFreshnessPeriod()) {
|
||||
m_metaInfo.setFreshnessPeriod(freshnessPeriod);
|
||||
resetWire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setFinalBlock(optional<name::Component> finalBlockId)
|
||||
{
|
||||
resetWire();
|
||||
m_metaInfo.setFinalBlock(std::move(finalBlockId));
|
||||
if (finalBlockId != m_metaInfo.getFinalBlock()) {
|
||||
m_metaInfo.setFinalBlock(std::move(finalBlockId));
|
||||
resetWire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -314,19 +438,22 @@ operator==(const Data& lhs, const Data& rhs)
|
||||
return lhs.getName() == rhs.getName() &&
|
||||
lhs.getMetaInfo().wireEncode() == rhs.getMetaInfo().wireEncode() &&
|
||||
lhs.getContent() == rhs.getContent() &&
|
||||
lhs.getSignature().getSignatureInfo() == rhs.getSignature().getSignatureInfo() &&
|
||||
lhs.getSignature().getValue() == rhs.getSignature().getValue();
|
||||
lhs.getSignatureInfo() == rhs.getSignatureInfo() &&
|
||||
lhs.getSignatureValue() == rhs.getSignatureValue();
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Data& data)
|
||||
{
|
||||
os << "Name: " << data.getName() << "\n";
|
||||
os << "MetaInfo: " << data.getMetaInfo() << "\n";
|
||||
os << "Content: (size: " << data.getContent().value_size() << ")\n";
|
||||
os << "Signature: (type: " << data.getSignature().getType()
|
||||
<< ", value_length: "<< data.getSignature().getValue().value_size() << ")";
|
||||
os << std::endl;
|
||||
os << "Name: " << data.getName() << "\n"
|
||||
<< "MetaInfo: [" << data.getMetaInfo() << "]\n";
|
||||
|
||||
if (data.hasContent()) {
|
||||
os << "Content: [" << data.getContent().value_size() << " bytes]\n";
|
||||
}
|
||||
|
||||
os << "Signature: [type: " << static_cast<tlv::SignatureTypeValue>(data.getSignatureType())
|
||||
<< ", length: "<< data.getSignatureValue().value_size() << "]\n";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
+170
-59
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,18 +19,22 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DATA_HPP
|
||||
#define NDN_DATA_HPP
|
||||
#ifndef NDN_CXX_DATA_HPP
|
||||
#define NDN_CXX_DATA_HPP
|
||||
|
||||
#include "ndn-cxx/meta-info.hpp"
|
||||
#include "ndn-cxx/name.hpp"
|
||||
#include "ndn-cxx/signature.hpp"
|
||||
#include "ndn-cxx/detail/packet-base.hpp"
|
||||
#include "ndn-cxx/encoding/block.hpp"
|
||||
#include "ndn-cxx/meta-info.hpp"
|
||||
#include "ndn-cxx/name.hpp"
|
||||
#include "ndn-cxx/security/security-common.hpp"
|
||||
#include "ndn-cxx/signature-info.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief Represents a Data packet.
|
||||
class Signature;
|
||||
|
||||
/** @brief Represents a %Data packet.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/data.html
|
||||
*/
|
||||
class Data : public PacketBase, public std::enable_shared_from_this<Data>
|
||||
{
|
||||
@@ -42,27 +46,29 @@ public:
|
||||
};
|
||||
|
||||
/** @brief Construct an unsigned Data packet with given @p name and empty Content.
|
||||
* @warning In certain contexts that use `Data::shared_from_this()`, Data must be created
|
||||
* using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
|
||||
* @warning In certain contexts that use `Data::shared_from_this()`, Data must be created using
|
||||
* `std::make_shared`. Otherwise, `shared_from_this()` may trigger undefined behavior.
|
||||
* One example where this is necessary is storing Data into a subclass of InMemoryStorage.
|
||||
*/
|
||||
explicit
|
||||
Data(const Name& name = Name());
|
||||
|
||||
/** @brief Construct a Data packet by decoding from @p wire.
|
||||
* @param wire @c tlv::Data element as defined in NDN Packet Format v0.2 or v0.3.
|
||||
* It may be signed or unsigned.
|
||||
* @warning In certain contexts that use `Data::shared_from_this()`, Data must be created
|
||||
* using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
|
||||
* @param wire TLV block of type tlv::Data; may be signed or unsigned.
|
||||
* @warning In certain contexts that use `Data::shared_from_this()`, Data must be created using
|
||||
* `std::make_shared`. Otherwise, `shared_from_this()` may trigger undefined behavior.
|
||||
* One example where this is necessary is storing Data into a subclass of InMemoryStorage.
|
||||
*/
|
||||
explicit
|
||||
Data(const Block& wire);
|
||||
|
||||
/** @brief Prepend wire encoding to @p encoder in NDN Packet Format v0.2.
|
||||
* @param encoder EncodingEstimator or EncodingBuffer instance
|
||||
* @param wantUnsignedPortionOnly If true, only prepends Name, MetaInfo, Content, and
|
||||
* SignatureInfo to @p encoder, but omit SignatureValue and outmost Type-Length of Data
|
||||
* element. This is intended to be used with wireEncode(encoder, signatureValue).
|
||||
* @throw Error SignatureBits are not provided and wantUnsignedPortionOnly is false.
|
||||
/** @brief Prepend wire encoding to @p encoder
|
||||
* @param encoder EncodingEstimator or EncodingBuffer instance.
|
||||
* @param wantUnsignedPortionOnly If true, prepend only Name, MetaInfo, Content, and
|
||||
* SignatureInfo to @p encoder, but omit SignatureValue and the outermost TLV
|
||||
* Type and Length of the Data element. This is intended to be used with
|
||||
* wireEncode(EncodingBuffer&, const Block&) const.
|
||||
* @throw Error %Signature is not present and @p wantUnsignedPortionOnly is false.
|
||||
*/
|
||||
template<encoding::Tag TAG>
|
||||
size_t
|
||||
@@ -70,10 +76,10 @@ public:
|
||||
|
||||
/** @brief Finalize Data packet encoding with the specified SignatureValue
|
||||
* @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
|
||||
* without SignatureValue or outmost Type-Length of Data element
|
||||
* @param signatureValue SignatureValue element
|
||||
* without SignatureValue and the outermost Type-Length of the Data element.
|
||||
* @param signatureValue SignatureValue element.
|
||||
*
|
||||
* This method is intended to be used in concert with Data::wireEncode(encoder, true)
|
||||
* This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
|
||||
* @code
|
||||
* Data data;
|
||||
* ...
|
||||
@@ -87,17 +93,13 @@ public:
|
||||
const Block&
|
||||
wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
|
||||
|
||||
/** @brief Encode to a @c Block.
|
||||
* @pre Data is signed.
|
||||
*
|
||||
* Normally, this function encodes to NDN Packet Format v0.2. However, if this instance has
|
||||
* cached wire encoding (\c hasWire() is true), the cached encoding is returned and it might
|
||||
* be in v0.3 format.
|
||||
/** @brief Encode into a Block.
|
||||
* @pre Data must be signed.
|
||||
*/
|
||||
const Block&
|
||||
wireEncode() const;
|
||||
|
||||
/** @brief Decode from @p wire in NDN Packet Format v0.2 or v0.3.
|
||||
/** @brief Decode from @p wire.
|
||||
*/
|
||||
void
|
||||
wireDecode(const Block& wire);
|
||||
@@ -105,7 +107,7 @@ public:
|
||||
/** @brief Check if this instance has cached wire encoding.
|
||||
*/
|
||||
bool
|
||||
hasWire() const
|
||||
hasWire() const noexcept
|
||||
{
|
||||
return m_wire.hasWire();
|
||||
}
|
||||
@@ -121,7 +123,7 @@ public: // Data fields
|
||||
/** @brief Get name
|
||||
*/
|
||||
const Name&
|
||||
getName() const
|
||||
getName() const noexcept
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
@@ -135,7 +137,7 @@ public: // Data fields
|
||||
/** @brief Get MetaInfo
|
||||
*/
|
||||
const MetaInfo&
|
||||
getMetaInfo() const
|
||||
getMetaInfo() const noexcept
|
||||
{
|
||||
return m_metaInfo;
|
||||
}
|
||||
@@ -146,58 +148,145 @@ public: // Data fields
|
||||
Data&
|
||||
setMetaInfo(const MetaInfo& metaInfo);
|
||||
|
||||
/** @brief Get Content
|
||||
/**
|
||||
* @brief Return whether this Data has a Content element
|
||||
*/
|
||||
bool
|
||||
hasContent() const noexcept
|
||||
{
|
||||
return m_content.isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Content element
|
||||
*
|
||||
* The Content value is accessible through value()/value_size() or value_begin()/value_end()
|
||||
* methods of the Block class.
|
||||
* If the element is not present (hasContent() == false), an invalid Block will be returned.
|
||||
*
|
||||
* The value of the returned Content Block (if valid) can be accessed through
|
||||
* Block::value() / Block::value_size() or Block::value_begin() / Block::value_end().
|
||||
*
|
||||
* @sa hasContent()
|
||||
* @sa Block::blockFromValue(), Block::parse()
|
||||
*/
|
||||
const Block&
|
||||
getContent() const;
|
||||
getContent() const noexcept
|
||||
{
|
||||
return m_content;
|
||||
}
|
||||
|
||||
/** @brief Set Content from a block
|
||||
/**
|
||||
* @brief Set Content from a Block
|
||||
* @param block TLV block to be used as Content; must be valid
|
||||
* @return a reference to this Data, to allow chaining
|
||||
*
|
||||
* If block's TLV-TYPE is Content, it will be used directly as Data's Content element.
|
||||
* If block's TLV-TYPE is not Content, it will be nested into a Content element.
|
||||
*
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* If the block's TLV-TYPE is tlv::Content, it will be used directly as this Data's
|
||||
* Content element. Otherwise, the block will be nested into a Content element.
|
||||
*/
|
||||
Data&
|
||||
setContent(const Block& block);
|
||||
|
||||
/** @brief Copy Content value from raw buffer
|
||||
* @param value pointer to the first octet of the value
|
||||
* @param valueSize size of the raw buffer
|
||||
* @return a reference to this Data, to allow chaining
|
||||
/**
|
||||
* @brief Set Content by copying from a raw buffer
|
||||
* @param value buffer with the TLV-VALUE of the content; may be nullptr if @p length is zero
|
||||
* @param length size of the buffer
|
||||
* @return a reference to this Data, to allow chaining
|
||||
*/
|
||||
Data&
|
||||
setContent(const uint8_t* value, size_t valueSize);
|
||||
setContent(const uint8_t* value, size_t length);
|
||||
|
||||
/** @brief Set Content from wire buffer
|
||||
* @param value Content value, which does not need to be a TLV element
|
||||
* @return a reference to this Data, to allow chaining
|
||||
/**
|
||||
* @brief Set Content from a shared buffer
|
||||
* @param value buffer with the TLV-VALUE of the content; must not be nullptr
|
||||
* @return a reference to this Data, to allow chaining
|
||||
*/
|
||||
Data&
|
||||
setContent(ConstBufferPtr value);
|
||||
|
||||
/** @brief Get Signature
|
||||
/**
|
||||
* @brief Remove the Content element
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @post hasContent() == false
|
||||
*/
|
||||
const Signature&
|
||||
getSignature() const
|
||||
{
|
||||
return m_signature;
|
||||
}
|
||||
Data&
|
||||
unsetContent();
|
||||
|
||||
/** @brief Get Signature
|
||||
* @deprecated Use getSignatureInfo and getSignatureValue
|
||||
*/
|
||||
[[deprecated("use getSignatureInfo and getSignatureValue")]]
|
||||
Signature
|
||||
getSignature() const;
|
||||
|
||||
/** @brief Set Signature
|
||||
* @deprecated Use setSignatureInfo and setSignatureValue
|
||||
* @return a reference to this Data, to allow chaining
|
||||
*/
|
||||
[[deprecated("use setSignatureInfo and setSignatureValue")]]
|
||||
Data&
|
||||
setSignature(const Signature& signature);
|
||||
|
||||
/** @brief Set SignatureValue
|
||||
/** @brief Get SignatureInfo
|
||||
*/
|
||||
const SignatureInfo&
|
||||
getSignatureInfo() const noexcept
|
||||
{
|
||||
return m_signatureInfo;
|
||||
}
|
||||
|
||||
/** @brief Set SignatureInfo
|
||||
*
|
||||
* This is a low-level function that should not normally be called directly by applications.
|
||||
* Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign().
|
||||
*
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign().
|
||||
* @sa SigningInfo
|
||||
*/
|
||||
Data&
|
||||
setSignatureValue(const Block& value);
|
||||
setSignatureInfo(const SignatureInfo& info);
|
||||
|
||||
/** @brief Get SignatureValue
|
||||
*/
|
||||
const Block&
|
||||
getSignatureValue() const noexcept
|
||||
{
|
||||
return m_signatureValue;
|
||||
}
|
||||
|
||||
/** @brief Set SignatureValue
|
||||
* @param value buffer containing the TLV-VALUE of the SignatureValue; must not be nullptr
|
||||
*
|
||||
* This is a low-level function that should not normally be called directly by applications.
|
||||
* Instead, use KeyChain::sign() to sign the packet.
|
||||
*
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
|
||||
*/
|
||||
Data&
|
||||
setSignatureValue(ConstBufferPtr value);
|
||||
|
||||
/** @brief Extract ranges of Data covered by the signature
|
||||
* @throw Error Data cannot be encoded or is missing ranges necessary for signing
|
||||
* @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called.
|
||||
*/
|
||||
InputBuffers
|
||||
extractSignedRanges() const;
|
||||
|
||||
|
||||
optional<uint8_t>
|
||||
getServiceClass() const noexcept
|
||||
{
|
||||
return m_serviceClass;
|
||||
}
|
||||
const Data&
|
||||
setServiceClass(optional<uint8_t> serviceClass) const;
|
||||
optional<uint64_t>
|
||||
getTargetRate() const noexcept
|
||||
{
|
||||
return m_targetRate;
|
||||
}
|
||||
const Data&
|
||||
setTargetRate(optional<uint64_t> targetRate) const;
|
||||
|
||||
public: // MetaInfo fields
|
||||
uint32_t
|
||||
@@ -227,6 +316,24 @@ public: // MetaInfo fields
|
||||
Data&
|
||||
setFinalBlock(optional<name::Component> finalBlockId);
|
||||
|
||||
public: // SignatureInfo fields
|
||||
/** @brief Get SignatureType
|
||||
* @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid
|
||||
*/
|
||||
int32_t
|
||||
getSignatureType() const noexcept
|
||||
{
|
||||
return m_signatureInfo.getSignatureType();
|
||||
}
|
||||
|
||||
/** @brief Get KeyLocator
|
||||
*/
|
||||
optional<KeyLocator>
|
||||
getKeyLocator() const noexcept
|
||||
{
|
||||
return m_signatureInfo.hasKeyLocator() ? make_optional(m_signatureInfo.getKeyLocator()) : nullopt;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** @brief Clear wire encoding and cached FullName
|
||||
* @note This does not clear the SignatureValue.
|
||||
@@ -238,7 +345,11 @@ private:
|
||||
Name m_name;
|
||||
MetaInfo m_metaInfo;
|
||||
Block m_content;
|
||||
Signature m_signature;
|
||||
SignatureInfo m_signatureInfo;
|
||||
Block m_signatureValue;
|
||||
// Add for QSCCP
|
||||
mutable optional<uint8_t> m_serviceClass;
|
||||
mutable optional<uint64_t> m_targetRate;
|
||||
|
||||
mutable Block m_wire;
|
||||
mutable Name m_fullName; ///< cached FullName computed from m_wire
|
||||
@@ -266,4 +377,4 @@ operator!=(const Data& lhs, const Data& rhs)
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_DATA_HPP
|
||||
#endif // NDN_CXX_DATA_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** \brief Represents a Delegation.
|
||||
* \sa https://named-data.net/doc/NDN-packet-spec/current/link.html
|
||||
/** \brief Represents a %Delegation.
|
||||
* \sa https://named-data.net/doc/NDN-packet-spec/0.3/link.html
|
||||
*/
|
||||
class Delegation
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -112,7 +112,7 @@ NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER(9)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
|
||||
namespace ndn {
|
||||
using boost::noncopyable;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -21,8 +21,8 @@
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_BLOCK_HPP
|
||||
#define NDN_ENCODING_BLOCK_HPP
|
||||
#ifndef NDN_CXX_ENCODING_BLOCK_HPP
|
||||
#define NDN_CXX_ENCODING_BLOCK_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/buffer.hpp"
|
||||
#include "ndn-cxx/encoding/encoding-buffer-fwd.hpp"
|
||||
@@ -36,8 +36,8 @@ class const_buffer;
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief Represents a TLV element of NDN packet format
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/
|
||||
/** @brief Represents a TLV element of the NDN packet format.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/tlv.html#tlv-encoding
|
||||
*/
|
||||
class Block
|
||||
{
|
||||
@@ -182,7 +182,7 @@ public: // wire format
|
||||
/** @brief Check if the Block is valid
|
||||
*
|
||||
* A Block is valid unless it has an invalid TLV-TYPE or is default-constructed.
|
||||
* In particular, a Block with zero-length TLV-VALUE *is* valid.
|
||||
* In particular, a Block with zero-length TLV-VALUE *is valid*.
|
||||
*/
|
||||
bool
|
||||
isValid() const noexcept
|
||||
@@ -190,19 +190,6 @@ public: // wire format
|
||||
return m_type != tlv::Invalid;
|
||||
}
|
||||
|
||||
/** @brief Check if the Block is empty
|
||||
*
|
||||
* A Block is considered empty *iff* it is not valid, i.e., isValid() returns false.
|
||||
*
|
||||
* @warning Note that an empty Block is *not* the same as a valid but zero-length Block.
|
||||
* @deprecated Use Block::isValid()
|
||||
*/
|
||||
NDN_CXX_NODISCARD bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return !isValid();
|
||||
}
|
||||
|
||||
/** @brief Reset the Block to a default-constructed state
|
||||
*
|
||||
* Equivalent to `*this = Block()`.
|
||||
@@ -518,4 +505,4 @@ operator "" _block(const char* input, std::size_t len);
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_ENCODING_BLOCK_HPP
|
||||
#endif // NDN_CXX_ENCODING_BLOCK_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "ndn-cxx/util/ostream-joiner.hpp"
|
||||
#include "ndn-cxx/util/string-helper.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <istream>
|
||||
#include <map>
|
||||
|
||||
@@ -70,6 +70,7 @@ enum {
|
||||
BaseCongestionMarkingInterval = 135,
|
||||
DefaultCongestionThreshold = 136,
|
||||
Mtu = 137,
|
||||
Bandwidth = 138,
|
||||
FaceQueryFilter = 150,
|
||||
FaceEventNotification = 192,
|
||||
FaceEventKind = 193,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -41,6 +41,8 @@ operator<<(std::ostream& os, SignatureTypeValue st)
|
||||
return os << "SignatureSha256WithEcdsa";
|
||||
case SignatureHmacWithSha256:
|
||||
return os << "SignatureHmacWithSha256";
|
||||
case NullSignature:
|
||||
return os << "NullSignature";
|
||||
}
|
||||
return os << "Unknown(" << static_cast<uint32_t>(st) << ')';
|
||||
}
|
||||
@@ -65,7 +67,7 @@ operator<<(std::ostream& os, ContentTypeValue ct)
|
||||
return os << "FLIC";
|
||||
}
|
||||
|
||||
if (ct >= 6 && ct <= 1023) {
|
||||
if (ct <= 1023) {
|
||||
os << "Reserved(";
|
||||
}
|
||||
else if (ct >= 9000 && ct <= 9999) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
@@ -74,7 +73,13 @@ enum : uint32_t {
|
||||
Nonce = 10,
|
||||
InterestLifetime = 12,
|
||||
HopLimit = 34,
|
||||
ServiceClass = 129,
|
||||
DownstreamRate = 130,
|
||||
TargetRate = 131,
|
||||
Dsz = 132,
|
||||
ApplicationParameters = 36,
|
||||
InterestSignatureInfo = 44,
|
||||
InterestSignatureValue = 46,
|
||||
MetaInfo = 20,
|
||||
Content = 21,
|
||||
SignatureInfo = 22,
|
||||
@@ -85,6 +90,9 @@ enum : uint32_t {
|
||||
SignatureType = 27,
|
||||
KeyLocator = 28,
|
||||
KeyDigest = 29,
|
||||
SignatureNonce = 38,
|
||||
SignatureTime = 40,
|
||||
SignatureSeqNum = 42,
|
||||
LinkDelegation = 31,
|
||||
LinkPreference = 30,
|
||||
|
||||
@@ -108,9 +116,6 @@ enum : uint32_t {
|
||||
Any = 19,
|
||||
};
|
||||
|
||||
[[deprecated("use GenericNameComponent")]]
|
||||
constexpr int NameComponent = GenericNameComponent;
|
||||
|
||||
/** @brief TLV-TYPE numbers for typed name components.
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/NameComponentType
|
||||
*/
|
||||
@@ -125,18 +130,20 @@ enum : uint32_t {
|
||||
|
||||
/** @brief SignatureType values
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/signature.html
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/SignatureType
|
||||
*/
|
||||
enum SignatureTypeValue : uint16_t {
|
||||
DigestSha256 = 0,
|
||||
SignatureSha256WithRsa = 1,
|
||||
SignatureSha256WithEcdsa = 3,
|
||||
SignatureHmacWithSha256 = 4,
|
||||
NullSignature = 200,
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, SignatureTypeValue st);
|
||||
|
||||
/** @brief TLV-TYPE numbers for SignatureInfo features
|
||||
/** @brief TLV-TYPE numbers for SignatureInfo extensions
|
||||
* @sa docs/specs/certificate-format.rst
|
||||
*/
|
||||
enum {
|
||||
|
||||
+67
-77
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ndn-cxx/impl/face-impl.hpp"
|
||||
#include "ndn-cxx/net/face-uri.hpp"
|
||||
#include "ndn-cxx/security/signing-helpers.hpp"
|
||||
#include "ndn-cxx/util/scope.hpp"
|
||||
#include "ndn-cxx/util/time.hpp"
|
||||
|
||||
// NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
|
||||
@@ -100,9 +101,6 @@ Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService,
|
||||
shared_ptr<Transport>
|
||||
Face::makeDefaultTransport()
|
||||
{
|
||||
// transport=unix:///var/run/nfd.sock
|
||||
// transport=tcp://localhost:6363
|
||||
|
||||
std::string transportUri;
|
||||
|
||||
const char* transportEnviron = getenv("NDN_CLIENT_TRANSPORT");
|
||||
@@ -173,25 +171,17 @@ Face::expressInterest(const Interest& interest,
|
||||
interest2->getNonce();
|
||||
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncExpressInterest(id, interest2, afterSatisfied, afterNacked, afterTimeout);
|
||||
impl->expressInterest(id, interest2, afterSatisfied, afterNacked, afterTimeout);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
|
||||
return PendingInterestHandle(*this, reinterpret_cast<const PendingInterestId*>(id));
|
||||
}
|
||||
|
||||
void
|
||||
Face::cancelPendingInterest(const PendingInterestId* pendingInterestId)
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncRemovePendingInterest(reinterpret_cast<RecordId>(pendingInterestId));
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
return PendingInterestHandle(m_impl, id);
|
||||
}
|
||||
|
||||
void
|
||||
Face::removeAllPendingInterests()
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncRemoveAllPendingInterests();
|
||||
impl->removeAllPendingInterests();
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
}
|
||||
|
||||
@@ -205,7 +195,7 @@ void
|
||||
Face::put(Data data)
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncPutData(data);
|
||||
impl->putData(data);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
}
|
||||
|
||||
@@ -213,7 +203,7 @@ void
|
||||
Face::put(lp::Nack nack)
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncPutNack(nack);
|
||||
impl->putNack(nack);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
}
|
||||
|
||||
@@ -236,7 +226,7 @@ Face::setInterestFilter(const InterestFilter& filter, const InterestCallback& on
|
||||
|
||||
auto id = m_impl->registerPrefix(filter.getPrefix(), onSuccess, onFailure, flags, options,
|
||||
filter, onInterest);
|
||||
return RegisteredPrefixHandle(*this, reinterpret_cast<const RegisteredPrefixId*>(id));
|
||||
return RegisteredPrefixHandle(m_impl, id);
|
||||
}
|
||||
|
||||
InterestFilterHandle
|
||||
@@ -245,18 +235,10 @@ Face::setInterestFilter(const InterestFilter& filter, const InterestCallback& on
|
||||
auto id = m_impl->m_interestFilterTable.allocateId();
|
||||
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncSetInterestFilter(id, filter, onInterest);
|
||||
impl->setInterestFilter(id, filter, onInterest);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
|
||||
return InterestFilterHandle(*this, reinterpret_cast<const InterestFilterId*>(id));
|
||||
}
|
||||
|
||||
void
|
||||
Face::clearInterestFilter(const InterestFilterId* interestFilterId)
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncUnsetInterestFilter(reinterpret_cast<RecordId>(interestFilterId));
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
return InterestFilterHandle(m_impl, id);
|
||||
}
|
||||
|
||||
RegisteredPrefixHandle
|
||||
@@ -270,18 +252,7 @@ Face::registerPrefix(const Name& prefix,
|
||||
options.setSigningInfo(signingInfo);
|
||||
|
||||
auto id = m_impl->registerPrefix(prefix, onSuccess, onFailure, flags, options, nullopt, nullptr);
|
||||
return RegisteredPrefixHandle(*this, reinterpret_cast<const RegisteredPrefixId*>(id));
|
||||
}
|
||||
|
||||
void
|
||||
Face::unregisterPrefixImpl(const RegisteredPrefixId* registeredPrefixId,
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->asyncUnregisterPrefix(reinterpret_cast<RecordId>(registeredPrefixId),
|
||||
onSuccess, onFailure);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
return RegisteredPrefixHandle(m_impl, id);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -291,32 +262,28 @@ Face::doProcessEvents(time::milliseconds timeout, bool keepThread)
|
||||
m_ioService.reset(); // ensure that run()/poll() will do some work
|
||||
}
|
||||
|
||||
try {
|
||||
if (timeout < time::milliseconds::zero()) {
|
||||
// do not block if timeout is negative, but process pending events
|
||||
m_ioService.poll();
|
||||
return;
|
||||
}
|
||||
auto onThrow = make_scope_fail([this] { m_impl->shutdown(); });
|
||||
|
||||
if (timeout > time::milliseconds::zero()) {
|
||||
m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.schedule(timeout,
|
||||
[&io = m_ioService, &work = m_impl->m_ioServiceWork] {
|
||||
io.stop();
|
||||
work.reset();
|
||||
});
|
||||
}
|
||||
|
||||
if (keepThread) {
|
||||
// work will ensure that m_ioService is running until work object exists
|
||||
m_impl->m_ioServiceWork = make_unique<boost::asio::io_service::work>(m_ioService);
|
||||
}
|
||||
|
||||
m_ioService.run();
|
||||
if (timeout < 0_ms) {
|
||||
// do not block if timeout is negative, but process pending events
|
||||
m_ioService.poll();
|
||||
return;
|
||||
}
|
||||
catch (...) {
|
||||
m_impl->shutdown();
|
||||
throw;
|
||||
|
||||
if (timeout > 0_ms) {
|
||||
m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.schedule(timeout,
|
||||
[&io = m_ioService, &work = m_impl->m_ioServiceWork] {
|
||||
io.stop();
|
||||
work.reset();
|
||||
});
|
||||
}
|
||||
|
||||
if (keepThread) {
|
||||
// work will ensure that m_ioService is running until work object exists
|
||||
m_impl->m_ioServiceWork = make_unique<boost::asio::io_service::work>(m_ioService);
|
||||
}
|
||||
|
||||
m_ioService.run();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -376,38 +343,61 @@ Face::onReceiveElement(const Block& blockFromDaemon)
|
||||
}
|
||||
}
|
||||
|
||||
PendingInterestHandle::PendingInterestHandle(Face& face, const PendingInterestId* id)
|
||||
: CancelHandle([&face, id] { face.cancelPendingInterest(id); })
|
||||
PendingInterestHandle::PendingInterestHandle(weak_ptr<Face::Impl> weakImpl, detail::RecordId id)
|
||||
: CancelHandle([w = std::move(weakImpl), id] {
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
impl->asyncRemovePendingInterest(id);
|
||||
}
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
RegisteredPrefixHandle::RegisteredPrefixHandle(Face& face, const RegisteredPrefixId* id)
|
||||
: CancelHandle([&face, id] { face.unregisterPrefixImpl(id, nullptr, nullptr); })
|
||||
, m_face(&face)
|
||||
RegisteredPrefixHandle::RegisteredPrefixHandle(weak_ptr<Face::Impl> weakImpl, detail::RecordId id)
|
||||
: CancelHandle([=] { unregister(weakImpl, id, nullptr, nullptr); })
|
||||
, m_weakImpl(std::move(weakImpl))
|
||||
, m_id(id)
|
||||
{
|
||||
// The lambda passed to CancelHandle constructor cannot call this->unregister,
|
||||
// because base class destructor cannot access the member fields of this subclass.
|
||||
// The lambda passed to CancelHandle constructor cannot call the non-static unregister(),
|
||||
// because the base class destructor cannot access the member fields of this subclass.
|
||||
}
|
||||
|
||||
void
|
||||
RegisteredPrefixHandle::unregister(const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
if (m_id == nullptr) {
|
||||
if (onFailure != nullptr) {
|
||||
if (m_id == 0) {
|
||||
if (onFailure) {
|
||||
onFailure("RegisteredPrefixHandle is empty");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_face->unregisterPrefixImpl(m_id, onSuccess, onFailure);
|
||||
m_face = nullptr;
|
||||
m_id = nullptr;
|
||||
unregister(m_weakImpl, m_id, onSuccess, onFailure);
|
||||
*this = {};
|
||||
}
|
||||
|
||||
InterestFilterHandle::InterestFilterHandle(Face& face, const InterestFilterId* id)
|
||||
: CancelHandle([&face, id] { face.clearInterestFilter(id); })
|
||||
void
|
||||
RegisteredPrefixHandle::unregister(const weak_ptr<Face::Impl>& weakImpl, detail::RecordId id,
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
auto impl = weakImpl.lock();
|
||||
if (impl != nullptr) {
|
||||
impl->asyncUnregisterPrefix(id, onSuccess, onFailure);
|
||||
}
|
||||
else if (onFailure) {
|
||||
onFailure("Face already closed");
|
||||
}
|
||||
}
|
||||
|
||||
InterestFilterHandle::InterestFilterHandle(weak_ptr<Face::Impl> weakImpl, detail::RecordId id)
|
||||
: CancelHandle([w = std::move(weakImpl), id] {
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
impl->asyncUnsetInterestFilter(id);
|
||||
}
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+49
-104
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -36,30 +36,31 @@ namespace ndn {
|
||||
|
||||
class Transport;
|
||||
|
||||
class PendingInterestId;
|
||||
class PendingInterestHandle;
|
||||
class RegisteredPrefixId;
|
||||
class RegisteredPrefixHandle;
|
||||
class InterestFilterId;
|
||||
class InterestFilterHandle;
|
||||
|
||||
namespace detail {
|
||||
using RecordId = uint64_t;
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when expressed Interest gets satisfied with a Data packet
|
||||
* @brief Callback invoked when an expressed Interest is satisfied by a Data packet
|
||||
*/
|
||||
typedef function<void(const Interest&, const Data&)> DataCallback;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when Nack is sent in response to expressed Interest
|
||||
* @brief Callback invoked when a Nack is received in response to an expressed Interest
|
||||
*/
|
||||
typedef function<void(const Interest&, const lp::Nack&)> NackCallback;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when expressed Interest times out
|
||||
* @brief Callback invoked when an expressed Interest times out
|
||||
*/
|
||||
typedef function<void(const Interest&)> TimeoutCallback;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when incoming Interest matches the specified InterestFilter
|
||||
* @brief Callback invoked when an incoming Interest matches the specified InterestFilter
|
||||
*/
|
||||
typedef function<void(const InterestFilter&, const Interest&)> InterestCallback;
|
||||
|
||||
@@ -74,12 +75,12 @@ typedef function<void(const Name&)> RegisterPrefixSuccessCallback;
|
||||
typedef function<void(const Name&, const std::string&)> RegisterPrefixFailureCallback;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds
|
||||
* @brief Callback invoked when unregistering a prefix succeeds
|
||||
*/
|
||||
typedef function<void()> UnregisterPrefixSuccessCallback;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when unregisterPrefix or unsetInterestFilter command fails
|
||||
* @brief Callback invoked when unregistering a prefix fails
|
||||
*/
|
||||
typedef function<void(const std::string&)> UnregisterPrefixFailureCallback;
|
||||
|
||||
@@ -236,16 +237,6 @@ public: // consumer
|
||||
const NackCallback& afterNacked,
|
||||
const TimeoutCallback& afterTimeout);
|
||||
|
||||
/**
|
||||
* @deprecated use PendingInterestHandle::cancel()
|
||||
*/
|
||||
[[deprecated]]
|
||||
void
|
||||
removePendingInterest(const PendingInterestId* pendingInterestId)
|
||||
{
|
||||
cancelPendingInterest(pendingInterestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cancel all previously expressed Interests
|
||||
*/
|
||||
@@ -312,14 +303,14 @@ public: // producer
|
||||
uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);
|
||||
|
||||
/**
|
||||
* @brief Set InterestFilter to dispatch incoming matching interest to onInterest callback
|
||||
* @brief Set an InterestFilter to dispatch matching incoming Interests to @p onInterest callback.
|
||||
*
|
||||
* @param filter Interest filter
|
||||
* @param onInterest A callback to be called when a matching interest is received
|
||||
*
|
||||
* This method modifies library's FIB only, and does not register the prefix with the
|
||||
* forwarder. It will always succeed. To register prefix with the forwarder, use
|
||||
* registerPrefix, or use the setInterestFilter overload taking two callbacks.
|
||||
* forwarder. It will always succeed. To register a prefix with the forwarder, use
|
||||
* registerPrefix() or one of the other two setInterestFilter() overloads.
|
||||
*
|
||||
* @return A handle for unsetting the Interest filter.
|
||||
*/
|
||||
@@ -350,38 +341,6 @@ public: // producer
|
||||
const security::SigningInfo& signingInfo = security::SigningInfo(),
|
||||
uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);
|
||||
|
||||
/**
|
||||
* @deprecated use RegisteredPrefixHandle::unregister()
|
||||
*/
|
||||
[[deprecated]]
|
||||
void
|
||||
unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
|
||||
{
|
||||
unregisterPrefixImpl(registeredPrefixId, nullptr, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use InterestFilterHandle::cancel()
|
||||
*/
|
||||
[[deprecated]]
|
||||
void
|
||||
unsetInterestFilter(const InterestFilterId* interestFilterId)
|
||||
{
|
||||
clearInterestFilter(interestFilterId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use RegisteredPrefixHandle::unregister()
|
||||
*/
|
||||
[[deprecated]]
|
||||
void
|
||||
unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
unregisterPrefixImpl(registeredPrefixId, onSuccess, onFailure);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publish data packet
|
||||
* @param data the Data; a copy will be made, so that the caller is not required to
|
||||
@@ -408,9 +367,9 @@ public: // IO routine
|
||||
/**
|
||||
* @brief Process any data to receive or call timeout callbacks.
|
||||
*
|
||||
* This call will block forever (default timeout == 0) to process IO on the face.
|
||||
* To exit cleanly on a producer, unset any Interest filters with unsetInterestFilter() and wait
|
||||
* for processEvents() to return. To exit after an error, one can call shutdown().
|
||||
* This call will block forever (with the default timeout of 0) to process I/O on the face.
|
||||
* To exit cleanly on a producer, clear any Interest filters and wait for processEvents() to
|
||||
* return. To exit after an error, one can call shutdown().
|
||||
* In consumer applications, processEvents() will return when all expressed Interests have been
|
||||
* satisfied, Nacked, or timed out. To terminate earlier, a consumer application should cancel
|
||||
* all previously expressed and still-pending Interests.
|
||||
@@ -442,16 +401,17 @@ public: // IO routine
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown face operations
|
||||
* @brief Shutdown face operations.
|
||||
*
|
||||
* This method cancels all pending operations and closes connection to NDN Forwarder.
|
||||
* This method cancels all pending operations and closes the connection to the NDN forwarder.
|
||||
*
|
||||
* Note that this method does not stop the io_service if it is shared between multiple Faces or
|
||||
* with other IO objects (e.g., Scheduler).
|
||||
*
|
||||
* @warning Calling this method could cause outgoing packets to be lost. Producers that shut down
|
||||
* immediately after sending a Data packet should instead use unsetInterestFilter() to
|
||||
* @warning Calling this method may cause outgoing packets to be lost. Producers that shut down
|
||||
* immediately after sending a Data packet should instead clear all Interest filters to
|
||||
* shut down cleanly.
|
||||
* @sa processEvents()
|
||||
*/
|
||||
void
|
||||
shutdown();
|
||||
@@ -488,7 +448,6 @@ private:
|
||||
|
||||
/**
|
||||
* @throw Face::Error on unsupported protocol
|
||||
* @note shared_ptr is passed by value because ownership is transferred to this function
|
||||
*/
|
||||
void
|
||||
construct(shared_ptr<Transport> transport, KeyChain& keyChain);
|
||||
@@ -496,17 +455,6 @@ private:
|
||||
void
|
||||
onReceiveElement(const Block& blockFromDaemon);
|
||||
|
||||
void
|
||||
cancelPendingInterest(const PendingInterestId* pendingInterestId);
|
||||
|
||||
void
|
||||
clearInterestFilter(const InterestFilterId* interestFilterId);
|
||||
|
||||
void
|
||||
unregisterPrefixImpl(const RegisteredPrefixId* registeredPrefixId,
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure);
|
||||
|
||||
private:
|
||||
/// the io_service owned by this Face, may be null
|
||||
unique_ptr<boost::asio::io_service> m_internalIoService;
|
||||
@@ -532,25 +480,25 @@ private:
|
||||
friend InterestFilterHandle;
|
||||
};
|
||||
|
||||
/** \brief A handle of pending Interest.
|
||||
/** \brief Handle for a pending Interest.
|
||||
*
|
||||
* \code
|
||||
* PendingInterestHandle hdl = face.expressInterest(interest, satisfyCb, nackCb, timeoutCb);
|
||||
* hdl.cancel(); // cancel the pending Interest
|
||||
* \endcode
|
||||
*
|
||||
* \warning Canceling a pending Interest after the face has been destructed may trigger undefined
|
||||
* behavior.
|
||||
*/
|
||||
class PendingInterestHandle : public detail::CancelHandle
|
||||
{
|
||||
public:
|
||||
PendingInterestHandle() noexcept = default;
|
||||
|
||||
PendingInterestHandle(Face& face, const PendingInterestId* id);
|
||||
private:
|
||||
PendingInterestHandle(weak_ptr<Face::Impl> impl, detail::RecordId id);
|
||||
|
||||
friend Face;
|
||||
};
|
||||
|
||||
/** \brief A scoped handle of pending Interest.
|
||||
/** \brief Scoped handle for a pending Interest.
|
||||
*
|
||||
* Upon destruction of this handle, the pending Interest is canceled automatically.
|
||||
* Most commonly, the application keeps a ScopedPendingInterestHandle as a class member field,
|
||||
@@ -561,13 +509,10 @@ public:
|
||||
* ScopedPendingInterestHandle hdl = face.expressInterest(interest, satisfyCb, nackCb, timeoutCb);
|
||||
* } // hdl goes out of scope, canceling the pending Interest
|
||||
* \endcode
|
||||
*
|
||||
* \warning Canceling a pending Interest after the face has been destructed may trigger undefined
|
||||
* behavior.
|
||||
*/
|
||||
using ScopedPendingInterestHandle = detail::ScopedCancelHandle<PendingInterestHandle>;
|
||||
|
||||
/** \brief A handle of registered prefix.
|
||||
/** \brief Handle for a registered prefix.
|
||||
*/
|
||||
class RegisteredPrefixHandle : public detail::CancelHandle
|
||||
{
|
||||
@@ -578,22 +523,28 @@ public:
|
||||
// see https://stackoverflow.com/a/44693603
|
||||
}
|
||||
|
||||
RegisteredPrefixHandle(Face& face, const RegisteredPrefixId* id);
|
||||
|
||||
/** \brief Unregister the prefix.
|
||||
* \warning Unregistering a prefix after the face has been destructed may trigger undefined
|
||||
* behavior.
|
||||
*/
|
||||
void
|
||||
unregister(const UnregisterPrefixSuccessCallback& onSuccess = nullptr,
|
||||
const UnregisterPrefixFailureCallback& onFailure = nullptr);
|
||||
|
||||
private:
|
||||
Face* m_face = nullptr;
|
||||
const RegisteredPrefixId* m_id = nullptr;
|
||||
RegisteredPrefixHandle(weak_ptr<Face::Impl> impl, detail::RecordId id);
|
||||
|
||||
static void
|
||||
unregister(const weak_ptr<Face::Impl>& impl, detail::RecordId id,
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure);
|
||||
|
||||
private:
|
||||
weak_ptr<Face::Impl> m_weakImpl;
|
||||
detail::RecordId m_id = 0;
|
||||
|
||||
friend Face;
|
||||
};
|
||||
|
||||
/** \brief A scoped handle of registered prefix.
|
||||
/** \brief Scoped handle for a registered prefix.
|
||||
*
|
||||
* Upon destruction of this handle, the prefix is unregistered automatically.
|
||||
* Most commonly, the application keeps a ScopedRegisteredPrefixHandle as a class member field,
|
||||
@@ -605,33 +556,30 @@ private:
|
||||
* ScopedRegisteredPrefixHandle hdl = face.registerPrefix(prefix, onSuccess, onFailure);
|
||||
* } // hdl goes out of scope, unregistering the prefix
|
||||
* \endcode
|
||||
*
|
||||
* \warning Unregistering a prefix after the face has been destructed may trigger undefined
|
||||
* behavior.
|
||||
*/
|
||||
using ScopedRegisteredPrefixHandle = detail::ScopedCancelHandle<RegisteredPrefixHandle>;
|
||||
|
||||
/** \brief A handle of registered Interest filter.
|
||||
/** \brief Handle for a registered Interest filter.
|
||||
*
|
||||
* \code
|
||||
* InterestFilterHandle hdl = face.setInterestFilter(prefix, onInterest);
|
||||
* hdl.cancel(); // unset the Interest filter
|
||||
* \endcode
|
||||
*
|
||||
* \warning Unsetting an Interest filter after the face has been destructed may trigger
|
||||
* undefined behavior.
|
||||
*/
|
||||
class InterestFilterHandle : public detail::CancelHandle
|
||||
{
|
||||
public:
|
||||
InterestFilterHandle() noexcept = default;
|
||||
|
||||
InterestFilterHandle(Face& face, const InterestFilterId* id);
|
||||
private:
|
||||
InterestFilterHandle(weak_ptr<Face::Impl> impl, detail::RecordId id);
|
||||
|
||||
friend Face;
|
||||
};
|
||||
|
||||
/** \brief A scoped handle of registered Interest filter.
|
||||
/** \brief Scoped handle for a registered Interest filter.
|
||||
*
|
||||
* Upon destruction of this handle, the Interest filter is unset automatically.
|
||||
* Upon destruction of this handle, the Interest filter is canceled automatically.
|
||||
* Most commonly, the application keeps a ScopedInterestFilterHandle as a class member field,
|
||||
* so that it can cleanup its Interest filter when the class instance is destructed.
|
||||
*
|
||||
@@ -640,9 +588,6 @@ public:
|
||||
* ScopedInterestFilterHandle hdl = face.setInterestFilter(prefix, onInterest);
|
||||
* } // hdl goes out of scope, unsetting the Interest filter
|
||||
* \endcode
|
||||
*
|
||||
* \warning Unsetting an Interest filter after the face has been destructed may trigger
|
||||
* undefined behavior.
|
||||
*/
|
||||
using ScopedInterestFilterHandle = detail::ScopedCancelHandle<InterestFilterHandle>;
|
||||
|
||||
|
||||
+16
-10
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -26,26 +26,32 @@
|
||||
// and included before anything else
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
#include "ndn-cxx/security/impl/openssl.hpp"
|
||||
|
||||
// STL headers to precompile
|
||||
#include <fstream>
|
||||
#include <atomic>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
// Boost headers to precompile
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/asio/basic_socket.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/chrono.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/log/common.hpp>
|
||||
#include <boost/log/expressions/keyword.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/range/adaptors.hpp>
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#endif // NDN_IMPL_COMMON_PCH_HPP
|
||||
+110
-89
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -23,6 +23,7 @@
|
||||
#define NDN_IMPL_FACE_IMPL_HPP
|
||||
|
||||
#include "ndn-cxx/face.hpp"
|
||||
#include "ndn-cxx/impl/interest-filter-record.hpp"
|
||||
#include "ndn-cxx/impl/lp-field-tag.hpp"
|
||||
#include "ndn-cxx/impl/pending-interest.hpp"
|
||||
#include "ndn-cxx/impl/registered-prefix.hpp"
|
||||
@@ -55,36 +56,39 @@ namespace ndn {
|
||||
|
||||
/** @brief implementation detail of Face
|
||||
*/
|
||||
class Face::Impl : noncopyable
|
||||
class Face::Impl : public std::enable_shared_from_this<Face::Impl>
|
||||
{
|
||||
public:
|
||||
using PendingInterestTable = RecordContainer<PendingInterest>;
|
||||
using InterestFilterTable = RecordContainer<InterestFilterRecord>;
|
||||
using RegisteredPrefixTable = RecordContainer<RegisteredPrefix>;
|
||||
|
||||
Impl(Face& face, KeyChain& keyChain)
|
||||
: m_face(face)
|
||||
, m_scheduler(m_face.getIoService())
|
||||
, m_nfdController(m_face, keyChain)
|
||||
{
|
||||
auto postOnEmptyPitOrNoRegisteredPrefixes = [this] {
|
||||
this->m_face.getIoService().post([this] { this->onEmptyPitOrNoRegisteredPrefixes(); });
|
||||
// without this extra "post", transport can get paused (-async_read) and then resumed
|
||||
auto onEmptyPitOrNoRegisteredPrefixes = [this] {
|
||||
// Without this extra "post", transport can get paused (-async_read) and then resumed
|
||||
// (+async_read) from within onInterest/onData callback. After onInterest/onData
|
||||
// finishes, there is another +async_read with the same memory block. A few of such
|
||||
// async_read duplications can cause various effects and result in segfault.
|
||||
m_face.getIoService().post([this] {
|
||||
if (m_pendingInterestTable.empty() && m_registeredPrefixTable.empty()) {
|
||||
m_face.m_transport->pause();
|
||||
if (!m_ioServiceWork) {
|
||||
m_processEventsTimeoutEvent.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
m_pendingInterestTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
|
||||
m_registeredPrefixTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
|
||||
m_pendingInterestTable.onEmpty.connect(onEmptyPitOrNoRegisteredPrefixes);
|
||||
m_registeredPrefixTable.onEmpty.connect(onEmptyPitOrNoRegisteredPrefixes);
|
||||
}
|
||||
|
||||
public: // consumer
|
||||
void
|
||||
asyncExpressInterest(RecordId id, shared_ptr<const Interest> interest,
|
||||
const DataCallback& afterSatisfied,
|
||||
const NackCallback& afterNacked,
|
||||
const TimeoutCallback& afterTimeout)
|
||||
expressInterest(detail::RecordId id, shared_ptr<const Interest> interest,
|
||||
const DataCallback& afterSatisfied,
|
||||
const NackCallback& afterNacked,
|
||||
const TimeoutCallback& afterTimeout)
|
||||
{
|
||||
NDN_LOG_DEBUG("<I " << *interest);
|
||||
this->ensureConnected(true);
|
||||
@@ -104,13 +108,18 @@ public: // consumer
|
||||
}
|
||||
|
||||
void
|
||||
asyncRemovePendingInterest(RecordId id)
|
||||
asyncRemovePendingInterest(detail::RecordId id)
|
||||
{
|
||||
m_pendingInterestTable.erase(id);
|
||||
m_face.getIoService().post([id, w = weak_ptr<Impl>{shared_from_this()}] { // use weak_from_this() in C++17
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
impl->m_pendingInterestTable.erase(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
asyncRemoveAllPendingInterests()
|
||||
removeAllPendingInterests()
|
||||
{
|
||||
m_pendingInterestTable.clear();
|
||||
}
|
||||
@@ -176,21 +185,21 @@ public: // consumer
|
||||
|
||||
public: // producer
|
||||
void
|
||||
asyncSetInterestFilter(RecordId id, const InterestFilter& filter,
|
||||
const InterestCallback& onInterest)
|
||||
setInterestFilter(detail::RecordId id, const InterestFilter& filter, const InterestCallback& onInterest)
|
||||
{
|
||||
NDN_LOG_INFO("setting InterestFilter: " << filter);
|
||||
m_interestFilterTable.put(id, filter, onInterest);
|
||||
}
|
||||
|
||||
void
|
||||
asyncUnsetInterestFilter(RecordId id)
|
||||
asyncUnsetInterestFilter(detail::RecordId id)
|
||||
{
|
||||
const InterestFilterRecord* record = m_interestFilterTable.get(id);
|
||||
if (record != nullptr) {
|
||||
NDN_LOG_INFO("unsetting InterestFilter: " << record->getFilter());
|
||||
m_interestFilterTable.erase(id);
|
||||
}
|
||||
m_face.getIoService().post([id, w = weak_ptr<Impl>{shared_from_this()}] { // use weak_from_this() in C++17
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
impl->unsetInterestFilter(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -202,20 +211,7 @@ public: // producer
|
||||
}
|
||||
|
||||
void
|
||||
dispatchInterest(PendingInterest& entry, const Interest& interest)
|
||||
{
|
||||
m_interestFilterTable.forEach([&] (const InterestFilterRecord& filter) {
|
||||
if (!filter.doesMatch(entry)) {
|
||||
return;
|
||||
}
|
||||
NDN_LOG_DEBUG(" matches " << filter.getFilter());
|
||||
entry.recordForwarding();
|
||||
filter.invokeInterestCallback(interest);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
asyncPutData(const Data& data)
|
||||
putData(const Data& data)
|
||||
{
|
||||
NDN_LOG_DEBUG("<D " << data.getName());
|
||||
bool shouldSendToForwarder = satisfyPendingInterests(data);
|
||||
@@ -234,7 +230,7 @@ public: // producer
|
||||
}
|
||||
|
||||
void
|
||||
asyncPutNack(const lp::Nack& nack)
|
||||
putNack(const lp::Nack& nack)
|
||||
{
|
||||
NDN_LOG_DEBUG("<N " << nack.getInterest() << '~' << nack.getHeader().getReason());
|
||||
optional<lp::Nack> outNack = nackPendingInterests(nack);
|
||||
@@ -254,7 +250,7 @@ public: // producer
|
||||
}
|
||||
|
||||
public: // prefix registration
|
||||
RecordId
|
||||
detail::RecordId
|
||||
registerPrefix(const Name& prefix,
|
||||
const RegisterPrefixSuccessCallback& onSuccess,
|
||||
const RegisterPrefixFailureCallback& onFailure,
|
||||
@@ -269,16 +265,15 @@ public: // prefix registration
|
||||
[=] (const nfd::ControlParameters&) {
|
||||
NDN_LOG_INFO("registered prefix: " << prefix);
|
||||
|
||||
RecordId filterId = 0;
|
||||
detail::RecordId filterId = 0;
|
||||
if (filter) {
|
||||
NDN_LOG_INFO("setting InterestFilter: " << *filter);
|
||||
InterestFilterRecord& filterRecord = m_interestFilterTable.insert(*filter, onInterest);
|
||||
auto& filterRecord = m_interestFilterTable.insert(*filter, onInterest);
|
||||
filterId = filterRecord.getId();
|
||||
}
|
||||
|
||||
m_registeredPrefixTable.put(id, prefix, options, filterId);
|
||||
|
||||
if (onSuccess != nullptr) {
|
||||
if (onSuccess) {
|
||||
onSuccess(prefix);
|
||||
}
|
||||
},
|
||||
@@ -292,39 +287,16 @@ public: // prefix registration
|
||||
}
|
||||
|
||||
void
|
||||
asyncUnregisterPrefix(RecordId id,
|
||||
asyncUnregisterPrefix(detail::RecordId id,
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
const RegisteredPrefix* record = m_registeredPrefixTable.get(id);
|
||||
if (record == nullptr) {
|
||||
if (onFailure != nullptr) {
|
||||
onFailure("Unrecognized RegisteredPrefixHandle");
|
||||
m_face.getIoService().post([=, w = weak_ptr<Impl>{shared_from_this()}] { // use weak_from_this() in C++17
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
impl->unregisterPrefix(id, onSuccess, onFailure);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (record->getFilterId() != 0) {
|
||||
asyncUnsetInterestFilter(record->getFilterId());
|
||||
}
|
||||
|
||||
NDN_LOG_INFO("unregistering prefix: " << record->getPrefix());
|
||||
|
||||
m_nfdController.start<nfd::RibUnregisterCommand>(
|
||||
nfd::ControlParameters().setName(record->getPrefix()),
|
||||
[=] (const nfd::ControlParameters&) {
|
||||
NDN_LOG_INFO("unregistered prefix: " << record->getPrefix());
|
||||
m_registeredPrefixTable.erase(id);
|
||||
|
||||
if (onSuccess != nullptr) {
|
||||
onSuccess();
|
||||
}
|
||||
},
|
||||
[=] (const nfd::ControlResponse& resp) {
|
||||
NDN_LOG_INFO("unregister prefix failed: " << record->getPrefix());
|
||||
onFailure(resp.getText());
|
||||
},
|
||||
record->getCommandOptions());
|
||||
});
|
||||
}
|
||||
|
||||
public: // IO routine
|
||||
@@ -341,17 +313,6 @@ public: // IO routine
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
onEmptyPitOrNoRegisteredPrefixes()
|
||||
{
|
||||
if (m_pendingInterestTable.empty() && m_registeredPrefixTable.empty()) {
|
||||
m_face.m_transport->pause();
|
||||
if (!m_ioServiceWork) {
|
||||
m_processEventsTimeoutEvent.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shutdown()
|
||||
{
|
||||
@@ -384,15 +345,75 @@ private:
|
||||
return wire;
|
||||
}
|
||||
|
||||
void
|
||||
dispatchInterest(PendingInterest& entry, const Interest& interest)
|
||||
{
|
||||
m_interestFilterTable.forEach([&] (const InterestFilterRecord& filter) {
|
||||
if (!filter.doesMatch(entry)) {
|
||||
return;
|
||||
}
|
||||
NDN_LOG_DEBUG(" matches " << filter.getFilter());
|
||||
entry.recordForwarding();
|
||||
filter.invokeInterestCallback(interest);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
unsetInterestFilter(detail::RecordId id)
|
||||
{
|
||||
const auto* record = m_interestFilterTable.get(id);
|
||||
if (record != nullptr) {
|
||||
NDN_LOG_INFO("unsetting InterestFilter: " << record->getFilter());
|
||||
m_interestFilterTable.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unregisterPrefix(detail::RecordId id,
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
const auto* record = m_registeredPrefixTable.get(id);
|
||||
if (record == nullptr) {
|
||||
if (onFailure) {
|
||||
onFailure("Unrecognized RegisteredPrefixHandle");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (record->getFilterId() != 0) {
|
||||
unsetInterestFilter(record->getFilterId());
|
||||
}
|
||||
|
||||
NDN_LOG_INFO("unregistering prefix: " << record->getPrefix());
|
||||
|
||||
m_nfdController.start<nfd::RibUnregisterCommand>(
|
||||
nfd::ControlParameters().setName(record->getPrefix()),
|
||||
[=] (const nfd::ControlParameters&) {
|
||||
NDN_LOG_INFO("unregistered prefix: " << record->getPrefix());
|
||||
m_registeredPrefixTable.erase(id);
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
},
|
||||
[=] (const nfd::ControlResponse& resp) {
|
||||
NDN_LOG_INFO("unregister prefix failed: " << record->getPrefix());
|
||||
if (onFailure) {
|
||||
onFailure(resp.getText());
|
||||
}
|
||||
},
|
||||
record->getCommandOptions());
|
||||
}
|
||||
|
||||
private:
|
||||
Face& m_face;
|
||||
Scheduler m_scheduler;
|
||||
scheduler::ScopedEventId m_processEventsTimeoutEvent;
|
||||
nfd::Controller m_nfdController;
|
||||
|
||||
PendingInterestTable m_pendingInterestTable;
|
||||
InterestFilterTable m_interestFilterTable;
|
||||
RegisteredPrefixTable m_registeredPrefixTable;
|
||||
detail::RecordContainer<PendingInterest> m_pendingInterestTable;
|
||||
detail::RecordContainer<InterestFilterRecord> m_interestFilterTable;
|
||||
detail::RecordContainer<RegisteredPrefix> m_registeredPrefixTable;
|
||||
|
||||
unique_ptr<boost::asio::io_service::work> m_ioServiceWork; // if thread needs to be preserved
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -23,32 +23,25 @@
|
||||
#define NDN_IMPL_INTEREST_FILTER_RECORD_HPP
|
||||
|
||||
#include "ndn-cxx/impl/pending-interest.hpp"
|
||||
#include "ndn-cxx/impl/record-container.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/**
|
||||
* @brief Opaque type to identify an InterestFilterRecord
|
||||
* @brief Associates an InterestFilter with an Interest callback.
|
||||
*/
|
||||
class InterestFilterId;
|
||||
|
||||
static_assert(sizeof(const InterestFilterId*) == sizeof(RecordId), "");
|
||||
|
||||
/**
|
||||
* @brief associates an InterestFilter with Interest callback
|
||||
*/
|
||||
class InterestFilterRecord : public RecordBase<InterestFilterRecord>
|
||||
class InterestFilterRecord : public detail::RecordBase<InterestFilterRecord>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct an Interest filter record
|
||||
*
|
||||
* @param filter an InterestFilter that represents what Interest should invoke the callback
|
||||
* @param interestCallback invoked when matching Interest is received
|
||||
* @param callback invoked when matching Interest is received
|
||||
*/
|
||||
InterestFilterRecord(const InterestFilter& filter,
|
||||
const InterestCallback& interestCallback)
|
||||
InterestFilterRecord(const InterestFilter& filter, const InterestCallback& callback)
|
||||
: m_filter(filter)
|
||||
, m_interestCallback(interestCallback)
|
||||
, m_interestCallback(callback)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -98,8 +98,8 @@ public:
|
||||
|
||||
/** \brief Write URI representation of \p comp to \p os.
|
||||
*
|
||||
* This base class implementation encodes the component in the plain
|
||||
* `<type-number>=<escaped-value>` syntax.
|
||||
* This base class implementation encodes the component using the plain
|
||||
* `<type-number>=<escaped-value>` syntax (aka canonical format).
|
||||
*/
|
||||
virtual void
|
||||
writeUri(std::ostream& os, const Component& comp) const
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -32,14 +32,7 @@
|
||||
namespace ndn {
|
||||
|
||||
/**
|
||||
* @brief Opaque type to identify a PendingInterest
|
||||
*/
|
||||
class PendingInterestId;
|
||||
|
||||
static_assert(sizeof(const PendingInterestId*) == sizeof(RecordId), "");
|
||||
|
||||
/**
|
||||
* @brief Indicates where a pending Interest came from
|
||||
* @brief Indicates where a pending Interest came from.
|
||||
*/
|
||||
enum class PendingInterestOrigin
|
||||
{
|
||||
@@ -60,9 +53,9 @@ operator<<(std::ostream& os, PendingInterestOrigin origin)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores a pending Interest and associated callbacks
|
||||
* @brief Stores a pending Interest and associated callbacks.
|
||||
*/
|
||||
class PendingInterest : public RecordBase<PendingInterest>
|
||||
class PendingInterest : public detail::RecordBase<PendingInterest>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -79,18 +72,16 @@ public:
|
||||
, m_dataCallback(dataCallback)
|
||||
, m_nackCallback(nackCallback)
|
||||
, m_timeoutCallback(timeoutCallback)
|
||||
, m_nNotNacked(0)
|
||||
{
|
||||
scheduleTimeoutEvent(scheduler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a pending Interest record for an Interest from NFD
|
||||
* @brief Construct a pending Interest record for an Interest from the forwarder
|
||||
*/
|
||||
PendingInterest(shared_ptr<const Interest> interest, Scheduler& scheduler)
|
||||
: m_interest(std::move(interest))
|
||||
, m_origin(PendingInterestOrigin::FORWARDER)
|
||||
, m_nNotNacked(0)
|
||||
{
|
||||
scheduleTimeoutEvent(scheduler);
|
||||
}
|
||||
@@ -121,7 +112,7 @@ public:
|
||||
/**
|
||||
* @brief Record an incoming Nack against a forwarded Interest
|
||||
* @return least severe Nack if all destinations where the Interest was forwarded have Nacked;
|
||||
* otherwise, nullopt
|
||||
* otherwise, nullopt
|
||||
*/
|
||||
optional<lp::Nack>
|
||||
recordNack(const lp::Nack& nack)
|
||||
@@ -143,7 +134,7 @@ public:
|
||||
void
|
||||
invokeDataCallback(const Data& data)
|
||||
{
|
||||
if (m_dataCallback != nullptr) {
|
||||
if (m_dataCallback) {
|
||||
m_dataCallback(*m_interest, data);
|
||||
}
|
||||
}
|
||||
@@ -155,7 +146,7 @@ public:
|
||||
void
|
||||
invokeNackCallback(const lp::Nack& nack)
|
||||
{
|
||||
if (m_nackCallback != nullptr) {
|
||||
if (m_nackCallback) {
|
||||
m_nackCallback(*m_interest, nack);
|
||||
}
|
||||
}
|
||||
@@ -188,9 +179,8 @@ private:
|
||||
NackCallback m_nackCallback;
|
||||
TimeoutCallback m_timeoutCallback;
|
||||
scheduler::ScopedEventId m_timeoutEvent;
|
||||
int m_nNotNacked; ///< number of Interest destinations that have not Nacked
|
||||
int m_nNotNacked = 0; ///< number of Interest destinations that have not Nacked
|
||||
optional<lp::Nack> m_leastSevereNack;
|
||||
std::function<void()> m_deleter;
|
||||
};
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -28,8 +28,9 @@
|
||||
#include <atomic>
|
||||
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
|
||||
using RecordId = uintptr_t;
|
||||
using RecordId = uint64_t;
|
||||
|
||||
template<typename T>
|
||||
class RecordContainer;
|
||||
@@ -194,6 +195,7 @@ private:
|
||||
std::atomic<RecordId> m_lastId{0};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_IMPL_RECORD_CONTAINER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -22,27 +22,19 @@
|
||||
#ifndef NDN_IMPL_REGISTERED_PREFIX_HPP
|
||||
#define NDN_IMPL_REGISTERED_PREFIX_HPP
|
||||
|
||||
#include "ndn-cxx/impl/interest-filter-record.hpp"
|
||||
#include "ndn-cxx/impl/record-container.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/command-options.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/control-parameters.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/**
|
||||
* @brief Opaque type to identify a RegisteredPrefix
|
||||
* @brief Stores information about a prefix registered in an NDN forwarder.
|
||||
*/
|
||||
class RegisteredPrefixId;
|
||||
|
||||
static_assert(sizeof(const RegisteredPrefixId*) == sizeof(RecordId), "");
|
||||
|
||||
/**
|
||||
* @brief stores information about a prefix registered in NDN forwarder
|
||||
*/
|
||||
class RegisteredPrefix : public RecordBase<RegisteredPrefix>
|
||||
class RegisteredPrefix : public detail::RecordBase<RegisteredPrefix>
|
||||
{
|
||||
public:
|
||||
RegisteredPrefix(const Name& prefix, const nfd::CommandOptions& options,
|
||||
RecordId filterId = 0)
|
||||
detail::RecordId filterId = 0)
|
||||
: m_prefix(prefix)
|
||||
, m_options(options)
|
||||
, m_filterId(filterId)
|
||||
@@ -61,7 +53,7 @@ public:
|
||||
return m_options;
|
||||
}
|
||||
|
||||
RecordId
|
||||
detail::RecordId
|
||||
getFilterId() const
|
||||
{
|
||||
return m_filterId;
|
||||
@@ -70,7 +62,7 @@ public:
|
||||
private:
|
||||
Name m_prefix;
|
||||
nfd::CommandOptions m_options;
|
||||
RecordId m_filterId;
|
||||
detail::RecordId m_filterId;
|
||||
};
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
+278
-25
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <boost/stacktrace/stacktrace.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -95,7 +97,6 @@ Interest::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
#endif // NDN_CXX_HAVE_TESTS
|
||||
}
|
||||
|
||||
// Encode as NDN Packet Format v0.3
|
||||
// Interest = INTEREST-TYPE TLV-LENGTH
|
||||
// Name
|
||||
// [CanBePrefix]
|
||||
@@ -104,6 +105,9 @@ Interest::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
// [Nonce]
|
||||
// [InterestLifetime]
|
||||
// [HopLimit]
|
||||
// [Dsz]
|
||||
// [ServiceClass]
|
||||
// [DownstreamRate]
|
||||
// [ApplicationParameters [InterestSignature]]
|
||||
// (elements are encoded in reverse order)
|
||||
|
||||
@@ -121,14 +125,31 @@ Interest::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
size_t totalLength = 0;
|
||||
|
||||
// ApplicationParameters and following elements (in reverse order)
|
||||
std::for_each(m_parameters.rbegin(), m_parameters.rend(), [&] (const Block& b) {
|
||||
totalLength += encoder.prependBlock(b);
|
||||
});
|
||||
for (const auto& block : m_parameters | boost::adaptors::reversed) {
|
||||
totalLength += encoder.prependBlock(block);
|
||||
}
|
||||
|
||||
// DownstreamRate
|
||||
if (getDownstreamRate()) {
|
||||
uint64_t downstreamRate = *getDownstreamRate();
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::DownstreamRate, reinterpret_cast<uint8_t*>(&downstreamRate), sizeof(downstreamRate));
|
||||
}
|
||||
|
||||
// ServiceClass
|
||||
if (getServiceClass()) {
|
||||
uint8_t serviceClass = *getServiceClass();
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::ServiceClass, reinterpret_cast<uint8_t*>(&serviceClass), sizeof(serviceClass));
|
||||
}
|
||||
|
||||
// Dsz
|
||||
if (getDsz()) {
|
||||
uint16_t dsz = *getDsz();
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::Dsz, reinterpret_cast<uint8_t*>(&dsz), sizeof(dsz));
|
||||
}
|
||||
|
||||
// HopLimit
|
||||
if (getHopLimit()) {
|
||||
uint8_t hopLimit = *getHopLimit();
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::HopLimit, &hopLimit, sizeof(hopLimit));
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::HopLimit, &*m_hopLimit, 1);
|
||||
}
|
||||
|
||||
// InterestLifetime
|
||||
@@ -138,8 +159,9 @@ Interest::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
}
|
||||
|
||||
// Nonce
|
||||
uint32_t nonce = getNonce(); // if nonce was unset, this generates a fresh nonce
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::Nonce, reinterpret_cast<uint8_t*>(&nonce), sizeof(nonce));
|
||||
getNonce(); // if nonce was unset, this generates a fresh nonce
|
||||
BOOST_ASSERT(hasNonce());
|
||||
totalLength += encoder.prependByteArrayBlock(tlv::Nonce, m_nonce->data(), m_nonce->size());
|
||||
|
||||
// ForwardingHint
|
||||
if (!getForwardingHint().empty()) {
|
||||
@@ -199,6 +221,9 @@ Interest::wireDecode(const Block& wire)
|
||||
// [Nonce]
|
||||
// [InterestLifetime]
|
||||
// [HopLimit]
|
||||
// [Dsz]
|
||||
// [ServiceClass]
|
||||
// [DownstreamRate]
|
||||
// [ApplicationParameters [InterestSignature]]
|
||||
|
||||
auto element = m_wire.elements_begin();
|
||||
@@ -223,6 +248,9 @@ Interest::wireDecode(const Block& wire)
|
||||
m_nonce.reset();
|
||||
m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
|
||||
m_hopLimit.reset();
|
||||
m_serviceClass.reset();
|
||||
m_downstreamRate.reset();
|
||||
m_dsz.reset();
|
||||
m_parameters.clear();
|
||||
|
||||
int lastElement = 1; // last recognized element index, in spec order
|
||||
@@ -262,12 +290,11 @@ Interest::wireDecode(const Block& wire)
|
||||
if (lastElement >= 5) {
|
||||
NDN_THROW(Error("Nonce element is out of order"));
|
||||
}
|
||||
uint32_t nonce = 0;
|
||||
if (element->value_size() != sizeof(nonce)) {
|
||||
if (element->value_size() != Nonce().size()) {
|
||||
NDN_THROW(Error("Nonce element is malformed"));
|
||||
}
|
||||
std::memcpy(&nonce, element->value(), sizeof(nonce));
|
||||
m_nonce = nonce;
|
||||
m_nonce.emplace();
|
||||
std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
|
||||
lastElement = 5;
|
||||
break;
|
||||
}
|
||||
@@ -290,13 +317,50 @@ Interest::wireDecode(const Block& wire)
|
||||
lastElement = 7;
|
||||
break;
|
||||
}
|
||||
case tlv::ApplicationParameters: {
|
||||
case tlv::Dsz: {
|
||||
if (lastElement >= 8) {
|
||||
break; // Dsz is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
if (element->value_size() != 2) {
|
||||
NDN_THROW(Error("Dsz element is malformed"));
|
||||
}
|
||||
uint16_t dsz = 0;
|
||||
std::memcpy(&dsz, element->value(), sizeof(dsz));
|
||||
m_dsz = dsz;
|
||||
lastElement = 8;
|
||||
break;
|
||||
}
|
||||
case tlv::ServiceClass: {
|
||||
if (lastElement >= 9) {
|
||||
break; // ServiceClass is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
if (element->value_size() != 1) {
|
||||
NDN_THROW(Error("ServiceClass element is malformed" + std::to_string(element->value_size())));
|
||||
}
|
||||
m_serviceClass = *element->value();
|
||||
lastElement = 9;
|
||||
break;
|
||||
}
|
||||
case tlv::DownstreamRate: {
|
||||
if (lastElement >= 10) {
|
||||
break; // DownstreamRate is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
uint64_t downstreamRate = 0;
|
||||
if (element->value_size() != 8) {
|
||||
NDN_THROW(Error("DownstreamRate element is malformed"));
|
||||
}
|
||||
std::memcpy(&downstreamRate, element->value(), sizeof(downstreamRate));
|
||||
m_downstreamRate = downstreamRate;
|
||||
lastElement = 10;
|
||||
break;
|
||||
}
|
||||
case tlv::ApplicationParameters: {
|
||||
if (lastElement >= 11) {
|
||||
break; // ApplicationParameters is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
BOOST_ASSERT(!hasApplicationParameters());
|
||||
m_parameters.push_back(*element);
|
||||
lastElement = 8;
|
||||
lastElement = 11;
|
||||
break;
|
||||
}
|
||||
default: { // unrecognized element
|
||||
@@ -378,6 +442,7 @@ Interest::setName(const Name& name)
|
||||
if (digestIndex == -2) {
|
||||
NDN_THROW(std::invalid_argument("Name cannot have more than one ParametersSha256DigestComponent"));
|
||||
}
|
||||
|
||||
if (name != m_name) {
|
||||
m_name = name;
|
||||
if (hasApplicationParameters()) {
|
||||
@@ -396,18 +461,58 @@ Interest::setForwardingHint(const DelegationList& value)
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
static auto
|
||||
generateNonce()
|
||||
{
|
||||
uint32_t r = random::generateWord32();
|
||||
Interest::Nonce n;
|
||||
std::memcpy(n.data(), &r, sizeof(r));
|
||||
return n;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
Interest::setServiceClass(optional<uint8_t> serviceClass) const
|
||||
{
|
||||
if (m_serviceClass != serviceClass) {
|
||||
m_serviceClass = serviceClass;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
Interest::setDownstreamRate(optional<uint64_t> downstreamRate) const
|
||||
{
|
||||
if (m_downstreamRate != downstreamRate) {
|
||||
m_downstreamRate = downstreamRate;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
Interest::setDsz(optional<uint16_t> dsz) const
|
||||
{
|
||||
if (m_dsz != dsz) {
|
||||
m_dsz = dsz;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Interest::Nonce
|
||||
Interest::getNonce() const
|
||||
{
|
||||
if (!hasNonce()) {
|
||||
m_nonce = random::generateWord32();
|
||||
m_nonce = generateNonce();
|
||||
m_wire.reset();
|
||||
}
|
||||
return *m_nonce;
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setNonce(uint32_t nonce)
|
||||
Interest::setNonce(optional<Interest::Nonce> nonce)
|
||||
{
|
||||
if (nonce != m_nonce) {
|
||||
m_nonce = nonce;
|
||||
@@ -422,9 +527,9 @@ Interest::refreshNonce()
|
||||
if (!hasNonce())
|
||||
return;
|
||||
|
||||
uint32_t oldNonce = *m_nonce;
|
||||
auto oldNonce = *m_nonce;
|
||||
while (m_nonce == oldNonce)
|
||||
m_nonce = random::generateWord32();
|
||||
m_nonce = generateNonce();
|
||||
|
||||
m_wire.reset();
|
||||
}
|
||||
@@ -435,6 +540,7 @@ Interest::setInterestLifetime(time::milliseconds lifetime)
|
||||
if (lifetime < 0_ms) {
|
||||
NDN_THROW(std::invalid_argument("InterestLifetime must be >= 0"));
|
||||
}
|
||||
|
||||
if (lifetime != m_interestLifetime) {
|
||||
m_interestLifetime = lifetime;
|
||||
m_wire.reset();
|
||||
@@ -469,9 +575,10 @@ Interest&
|
||||
Interest::setApplicationParameters(const Block& parameters)
|
||||
{
|
||||
if (!parameters.isValid()) {
|
||||
setApplicationParametersInternal(Block(tlv::ApplicationParameters));
|
||||
NDN_THROW(std::invalid_argument("ApplicationParameters block must be valid"));
|
||||
}
|
||||
else if (parameters.type() == tlv::ApplicationParameters) {
|
||||
|
||||
if (parameters.type() == tlv::ApplicationParameters) {
|
||||
setApplicationParametersInternal(parameters);
|
||||
}
|
||||
else {
|
||||
@@ -488,6 +595,7 @@ Interest::setApplicationParameters(const uint8_t* value, size_t length)
|
||||
if (value == nullptr && length != 0) {
|
||||
NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be nullptr"));
|
||||
}
|
||||
|
||||
setApplicationParametersInternal(makeBinaryBlock(tlv::ApplicationParameters, value, length));
|
||||
addOrReplaceParametersDigestComponent();
|
||||
m_wire.reset();
|
||||
@@ -500,6 +608,7 @@ Interest::setApplicationParameters(ConstBufferPtr value)
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be nullptr"));
|
||||
}
|
||||
|
||||
setApplicationParametersInternal(Block(tlv::ApplicationParameters, std::move(value)));
|
||||
addOrReplaceParametersDigestComponent();
|
||||
m_wire.reset();
|
||||
@@ -518,6 +627,142 @@ Interest::unsetApplicationParameters()
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
Interest::isSigned() const noexcept
|
||||
{
|
||||
return m_parameters.size() >= 3 &&
|
||||
getSignatureInfo().has_value() &&
|
||||
getSignatureValue().isValid() &&
|
||||
!m_name.empty() &&
|
||||
m_name[-1].type() == tlv::ParametersSha256DigestComponent;
|
||||
}
|
||||
|
||||
optional<SignatureInfo>
|
||||
Interest::getSignatureInfo() const
|
||||
{
|
||||
auto blockIt = findFirstParameter(tlv::InterestSignatureInfo);
|
||||
if (blockIt != m_parameters.end()) {
|
||||
return make_optional<SignatureInfo>(*blockIt, SignatureInfo::Type::Interest);
|
||||
}
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setSignatureInfo(const SignatureInfo& info)
|
||||
{
|
||||
// Prepend empty ApplicationParameters element if none present
|
||||
if (m_parameters.empty()) {
|
||||
m_parameters.push_back(makeEmptyBlock(tlv::ApplicationParameters));
|
||||
}
|
||||
|
||||
// Find first existing InterestSignatureInfo (if any)
|
||||
auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (const Block& block) {
|
||||
return block.type() == tlv::InterestSignatureInfo;
|
||||
});
|
||||
|
||||
Block encodedInfo = info.wireEncode(SignatureInfo::Type::Interest);
|
||||
if (infoIt != m_parameters.end()) {
|
||||
if (*infoIt == encodedInfo) {
|
||||
// New InterestSignatureInfo is the same as the old InterestSignatureInfo
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Replace existing InterestSignatureInfo
|
||||
*infoIt = std::move(encodedInfo);
|
||||
}
|
||||
else {
|
||||
// Place before first InterestSignatureValue element (if any), else at end
|
||||
auto valueIt = findFirstParameter(tlv::InterestSignatureValue);
|
||||
m_parameters.insert(valueIt, std::move(encodedInfo));
|
||||
}
|
||||
|
||||
addOrReplaceParametersDigestComponent();
|
||||
m_wire.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Block
|
||||
Interest::getSignatureValue() const
|
||||
{
|
||||
auto blockIt = findFirstParameter(tlv::InterestSignatureValue);
|
||||
if (blockIt != m_parameters.end()) {
|
||||
return *blockIt;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setSignatureValue(ConstBufferPtr value)
|
||||
{
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("InterestSignatureValue buffer cannot be nullptr"));
|
||||
}
|
||||
|
||||
// Ensure presence of InterestSignatureInfo
|
||||
auto infoIt = findFirstParameter(tlv::InterestSignatureInfo);
|
||||
if (infoIt == m_parameters.end()) {
|
||||
NDN_THROW(Error("InterestSignatureInfo must be present to set InterestSignatureValue"));
|
||||
}
|
||||
|
||||
auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (const Block& block) {
|
||||
return block.type() == tlv::InterestSignatureValue;
|
||||
});
|
||||
|
||||
Block valueBlock(tlv::InterestSignatureValue, std::move(value));
|
||||
if (valueIt != m_parameters.end()) {
|
||||
if (*valueIt == valueBlock) {
|
||||
// New InterestSignatureValue is the same as the old InterestSignatureValue
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Replace existing InterestSignatureValue
|
||||
*valueIt = std::move(valueBlock);
|
||||
}
|
||||
else {
|
||||
// Place after first InterestSignatureInfo element
|
||||
valueIt = m_parameters.insert(std::next(infoIt), std::move(valueBlock));
|
||||
}
|
||||
|
||||
// computeParametersDigest needs encoded SignatureValue
|
||||
valueIt->encode();
|
||||
|
||||
addOrReplaceParametersDigestComponent();
|
||||
m_wire.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputBuffers
|
||||
Interest::extractSignedRanges() const
|
||||
{
|
||||
InputBuffers bufs;
|
||||
bufs.reserve(2); // For Name range and parameters range
|
||||
|
||||
wireEncode();
|
||||
|
||||
// Get Interest name minus any ParametersSha256DigestComponent
|
||||
// Name is guaranteed to be non-empty if wireEncode does not throw
|
||||
BOOST_ASSERT(!m_name.empty());
|
||||
if (m_name[-1].type() != tlv::ParametersSha256DigestComponent) {
|
||||
NDN_THROW(Error("Interest Name must end with a ParametersSha256DigestComponent"));
|
||||
}
|
||||
|
||||
bufs.emplace_back(m_name[0].wire(), std::distance(m_name[0].wire(), m_name[-1].wire()));
|
||||
|
||||
// Ensure has InterestSignatureInfo field
|
||||
auto sigInfoIt = findFirstParameter(tlv::InterestSignatureInfo);
|
||||
if (sigInfoIt == m_parameters.end()) {
|
||||
NDN_THROW(Error("Interest missing InterestSignatureInfo"));
|
||||
}
|
||||
|
||||
// Get range from ApplicationParameters to InterestSignatureValue
|
||||
// or end of parameters (whichever is first)
|
||||
BOOST_ASSERT(!m_parameters.empty() && m_parameters.begin()->type() == tlv::ApplicationParameters);
|
||||
auto sigValueIt = findFirstParameter(tlv::InterestSignatureValue);
|
||||
bufs.emplace_back(m_parameters.begin()->wire(),
|
||||
std::distance(m_parameters.begin()->begin(), std::prev(sigValueIt)->end()));
|
||||
return bufs;
|
||||
}
|
||||
|
||||
// ---- ParametersSha256DigestComponent support ----
|
||||
|
||||
bool
|
||||
@@ -550,9 +795,9 @@ Interest::computeParametersDigest() const
|
||||
OBufferStream out;
|
||||
in >> digestFilter(DigestAlgorithm::SHA256) >> streamSink(out);
|
||||
|
||||
std::for_each(m_parameters.begin(), m_parameters.end(), [&] (const Block& b) {
|
||||
in.write(b.wire(), b.size());
|
||||
});
|
||||
for (const auto& block : m_parameters) {
|
||||
in.write(block.wire(), block.size());
|
||||
}
|
||||
in.end();
|
||||
|
||||
return out.buf();
|
||||
@@ -592,6 +837,14 @@ Interest::findParametersDigestComponent(const Name& name)
|
||||
return pos;
|
||||
}
|
||||
|
||||
std::vector<Block>::const_iterator
|
||||
Interest::findFirstParameter(uint32_t type) const
|
||||
{
|
||||
return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (const Block& block) {
|
||||
return block.type() == type;
|
||||
});
|
||||
}
|
||||
|
||||
// ---- operators ----
|
||||
|
||||
std::ostream&
|
||||
|
||||
+186
-41
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,14 +19,20 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_INTEREST_HPP
|
||||
#define NDN_INTEREST_HPP
|
||||
#ifndef NDN_CXX_INTEREST_HPP
|
||||
#define NDN_CXX_INTEREST_HPP
|
||||
|
||||
#include "ndn-cxx/delegation-list.hpp"
|
||||
#include "ndn-cxx/name.hpp"
|
||||
#include "ndn-cxx/detail/packet-base.hpp"
|
||||
#include "ndn-cxx/name.hpp"
|
||||
#include "ndn-cxx/security/security-common.hpp"
|
||||
#include "ndn-cxx/signature-info.hpp"
|
||||
#include "ndn-cxx/util/string-helper.hpp"
|
||||
#include "ndn-cxx/util/time.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
|
||||
namespace ndn {
|
||||
@@ -38,7 +44,8 @@ class Data;
|
||||
*/
|
||||
const time::milliseconds DEFAULT_INTEREST_LIFETIME = 4_s;
|
||||
|
||||
/** @brief Represents an Interest packet.
|
||||
/** @brief Represents an %Interest packet.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/interest.html
|
||||
*/
|
||||
class Interest : public PacketBase, public std::enable_shared_from_this<Interest>
|
||||
{
|
||||
@@ -49,6 +56,52 @@ public:
|
||||
using tlv::Error::Error;
|
||||
};
|
||||
|
||||
class Nonce final : public std::array<uint8_t, 4>
|
||||
{
|
||||
using Base = std::array<uint8_t, 4>;
|
||||
|
||||
public:
|
||||
Nonce() = default;
|
||||
|
||||
// implicit conversion from uint32_t
|
||||
Nonce(uint32_t n) noexcept
|
||||
{
|
||||
boost::endian::native_to_big_inplace(n);
|
||||
std::memcpy(data(), &n, sizeof(n));
|
||||
}
|
||||
|
||||
Nonce(uint8_t n1, uint8_t n2, uint8_t n3, uint8_t n4) noexcept
|
||||
{
|
||||
data()[0] = n1;
|
||||
data()[1] = n2;
|
||||
data()[2] = n3;
|
||||
data()[3] = n4;
|
||||
}
|
||||
|
||||
private: // non-member operators
|
||||
// NOTE: the following "hidden friend" operators are available via
|
||||
// argument-dependent lookup only and must be defined inline.
|
||||
|
||||
friend bool
|
||||
operator==(const Nonce& lhs, const Nonce& rhs) noexcept
|
||||
{
|
||||
return static_cast<const Base&>(lhs) == static_cast<const Base&>(rhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(const Nonce& lhs, const Nonce& rhs) noexcept
|
||||
{
|
||||
return static_cast<const Base&>(lhs) != static_cast<const Base&>(rhs);
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Nonce& nonce)
|
||||
{
|
||||
printHex(os, nonce.data(), nonce.size(), false);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Construct an Interest with given @p name and @p lifetime.
|
||||
*
|
||||
* @throw std::invalid_argument @p name is invalid or @p lifetime is negative
|
||||
@@ -66,18 +119,18 @@ public:
|
||||
explicit
|
||||
Interest(const Block& wire);
|
||||
|
||||
/** @brief Prepend wire encoding to @p encoder according to NDN Packet Format v0.3.
|
||||
/** @brief Prepend wire encoding to @p encoder.
|
||||
*/
|
||||
template<encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(EncodingImpl<TAG>& encoder) const;
|
||||
|
||||
/** @brief Encode into a Block according to NDN Packet Format v0.3.
|
||||
/** @brief Encode into a Block.
|
||||
*/
|
||||
const Block&
|
||||
wireEncode() const;
|
||||
|
||||
/** @brief Decode from @p wire according to NDN Packet Format v0.3.
|
||||
/** @brief Decode from @p wire.
|
||||
*/
|
||||
void
|
||||
wireDecode(const Block& wire);
|
||||
@@ -85,7 +138,7 @@ public:
|
||||
/** @brief Check if this instance has cached wire encoding.
|
||||
*/
|
||||
bool
|
||||
hasWire() const
|
||||
hasWire() const noexcept
|
||||
{
|
||||
return m_wire.hasWire();
|
||||
}
|
||||
@@ -228,13 +281,41 @@ public: // element access
|
||||
*
|
||||
* If nonce was not present, it is added and assigned a random value.
|
||||
*/
|
||||
uint32_t
|
||||
Nonce
|
||||
getNonce() const;
|
||||
|
||||
/** @brief Set nonce value.
|
||||
/** @brief Set the Interest's nonce.
|
||||
*
|
||||
* Use `setNonce(nullopt)` to remove any nonce from the Interest.
|
||||
*/
|
||||
Interest&
|
||||
setNonce(uint32_t nonce);
|
||||
setNonce(optional<Nonce> nonce);
|
||||
|
||||
optional<uint8_t>
|
||||
getServiceClass() const noexcept
|
||||
{
|
||||
return m_serviceClass;
|
||||
}
|
||||
const Interest&
|
||||
setServiceClass(optional<uint8_t> serviceClass) const;
|
||||
|
||||
optional<uint64_t>
|
||||
getDownstreamRate() const noexcept
|
||||
{
|
||||
return m_downstreamRate;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
setDownstreamRate(optional<uint64_t> downstreamRate) const;
|
||||
|
||||
optional<uint16_t>
|
||||
getDsz() const noexcept
|
||||
{
|
||||
return m_dsz;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
setDsz(optional<uint16_t> dsz) const;
|
||||
|
||||
/** @brief Change nonce value.
|
||||
*
|
||||
@@ -269,12 +350,22 @@ public: // element access
|
||||
Interest&
|
||||
setHopLimit(optional<uint8_t> hopLimit);
|
||||
|
||||
/**
|
||||
* @brief Return whether this Interest has any ApplicationParameters.
|
||||
*/
|
||||
bool
|
||||
hasApplicationParameters() const noexcept
|
||||
{
|
||||
return !m_parameters.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the ApplicationParameters.
|
||||
*
|
||||
* If the element is not present, an invalid Block will be returned.
|
||||
*
|
||||
* @sa hasApplicationParameters()
|
||||
*/
|
||||
Block
|
||||
getApplicationParameters() const
|
||||
{
|
||||
@@ -284,53 +375,100 @@ public: // element access
|
||||
return m_parameters.front();
|
||||
}
|
||||
|
||||
/** @brief Set ApplicationParameters from a Block.
|
||||
* @return a reference to this Interest
|
||||
/**
|
||||
* @brief Set ApplicationParameters from a Block.
|
||||
* @param block TLV block to be used as ApplicationParameters; must be valid
|
||||
* @return a reference to this Interest
|
||||
*
|
||||
* If the block is default-constructed, this will set a zero-length ApplicationParameters
|
||||
* element. Else, if the block's TLV-TYPE is ApplicationParameters, it will be used directly
|
||||
* as this Interest's ApplicationParameters element. Else, the block will be nested into an
|
||||
* ApplicationParameters element.
|
||||
* If the block's TLV-TYPE is tlv::ApplicationParameters, it will be used directly as
|
||||
* this Interest's ApplicationParameters element. Otherwise, the block will be nested
|
||||
* into an ApplicationParameters element.
|
||||
*
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
* Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will
|
||||
* be appended to it.
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
* Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will
|
||||
* be appended to it.
|
||||
*/
|
||||
Interest&
|
||||
setApplicationParameters(const Block& parameters);
|
||||
setApplicationParameters(const Block& block);
|
||||
|
||||
/** @brief Set ApplicationParameters by copying from a raw buffer.
|
||||
* @param value points to a buffer from which the TLV-VALUE of the parameters will be copied;
|
||||
* may be nullptr if @p length is zero
|
||||
* @param length size of the buffer
|
||||
* @return a reference to this Interest
|
||||
/**
|
||||
* @brief Set ApplicationParameters by copying from a raw buffer.
|
||||
* @param value points to a buffer from which the TLV-VALUE of the parameters will be copied;
|
||||
* may be nullptr if @p length is zero
|
||||
* @param length size of the buffer
|
||||
* @return a reference to this Interest
|
||||
*
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
* Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will
|
||||
* be appended to it.
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
* Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will
|
||||
* be appended to it.
|
||||
*/
|
||||
Interest&
|
||||
setApplicationParameters(const uint8_t* value, size_t length);
|
||||
|
||||
/** @brief Set ApplicationParameters from a shared buffer.
|
||||
* @param value buffer containing the TLV-VALUE of the parameters; must not be nullptr
|
||||
* @return a reference to this Interest
|
||||
/**
|
||||
* @brief Set ApplicationParameters from a shared buffer.
|
||||
* @param value buffer containing the TLV-VALUE of the parameters; must not be nullptr
|
||||
* @return a reference to this Interest
|
||||
*
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
* Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will
|
||||
* be appended to it.
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
* Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will
|
||||
* be appended to it.
|
||||
*/
|
||||
Interest&
|
||||
setApplicationParameters(ConstBufferPtr value);
|
||||
|
||||
/** @brief Remove the ApplicationParameters element from this Interest.
|
||||
* @post hasApplicationParameters() == false
|
||||
/**
|
||||
* @brief Remove the ApplicationParameters element from this Interest.
|
||||
* @return a reference to this Interest
|
||||
* @post hasApplicationParameters() == false
|
||||
*
|
||||
* This function will also remove any ParametersSha256DigestComponents from the Interest's name.
|
||||
* This function will also remove any InterestSignatureInfo and InterestSignatureValue elements
|
||||
* in the Interest, as well as any ParametersSha256DigestComponents in the Interest's name.
|
||||
*/
|
||||
Interest&
|
||||
unsetApplicationParameters();
|
||||
|
||||
/** @brief Return whether the Interest is signed
|
||||
* @warning This function only determines whether signature information is present in the
|
||||
* Interest and does not verify that the signature is valid.
|
||||
*/
|
||||
bool
|
||||
isSigned() const noexcept;
|
||||
|
||||
/** @brief Get the InterestSignatureInfo
|
||||
* @retval nullopt InterestSignatureInfo is not present
|
||||
*/
|
||||
optional<SignatureInfo>
|
||||
getSignatureInfo() const;
|
||||
|
||||
/** @brief Set the InterestSignatureInfo
|
||||
*/
|
||||
Interest&
|
||||
setSignatureInfo(const SignatureInfo& info);
|
||||
|
||||
/** @brief Get the InterestSignatureValue
|
||||
*
|
||||
* If the element is not present, an invalid Block will be returned.
|
||||
*/
|
||||
Block
|
||||
getSignatureValue() const;
|
||||
|
||||
/** @brief Set the InterestSignatureValue
|
||||
* @param value Buffer containing the TLV-VALUE of the InterestSignatureValue; must not be nullptr
|
||||
* @throw Error InterestSignatureInfo is unset
|
||||
*
|
||||
* InterestSignatureInfo must be set before setting InterestSignatureValue
|
||||
*/
|
||||
Interest&
|
||||
setSignatureValue(ConstBufferPtr value);
|
||||
|
||||
/** @brief Extract ranges of Interest covered by the signature in Packet Specification v0.3
|
||||
* @throw Error Interest cannot be encoded or is missing ranges necessary for signing
|
||||
* @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called.
|
||||
*/
|
||||
InputBuffers
|
||||
extractSignedRanges() const;
|
||||
|
||||
public: // ParametersSha256DigestComponent support
|
||||
static bool
|
||||
getAutoCheckParametersDigest()
|
||||
@@ -380,6 +518,9 @@ private:
|
||||
static ssize_t
|
||||
findParametersDigestComponent(const Name& name);
|
||||
|
||||
std::vector<Block>::const_iterator
|
||||
findFirstParameter(uint32_t type) const;
|
||||
|
||||
#ifdef NDN_CXX_HAVE_TESTS
|
||||
public:
|
||||
/// If true, not setting CanBePrefix results in an error in wireEncode().
|
||||
@@ -392,7 +533,11 @@ private:
|
||||
|
||||
Name m_name;
|
||||
DelegationList m_forwardingHint;
|
||||
mutable optional<uint32_t> m_nonce;
|
||||
mutable optional<Nonce> m_nonce;
|
||||
// Add for QSCCP
|
||||
mutable optional<uint8_t> m_serviceClass;
|
||||
mutable optional<uint64_t> m_downstreamRate;
|
||||
mutable optional<uint16_t> m_dsz;
|
||||
time::milliseconds m_interestLifetime;
|
||||
optional<uint8_t> m_hopLimit;
|
||||
mutable bool m_isCanBePrefixSet = false;
|
||||
@@ -417,4 +562,4 @@ operator<<(std::ostream& os, const Interest& interest);
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_INTEREST_HPP
|
||||
#endif // NDN_CXX_INTEREST_HPP
|
||||
+1
-14
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -35,19 +35,6 @@ public:
|
||||
using tlv::Error::Error;
|
||||
};
|
||||
|
||||
enum
|
||||
#ifndef DOXYGEN
|
||||
[[deprecated]] // apparently doxygen can't handle this attribute on enums
|
||||
#endif
|
||||
Type {
|
||||
/// KeyLocator is empty
|
||||
KeyLocator_None = tlv::Invalid,
|
||||
/// KeyLocator contains a Name
|
||||
KeyLocator_Name = tlv::Name,
|
||||
/// KeyLocator contains a KeyDigest
|
||||
KeyLocator_KeyDigest = tlv::KeyDigest,
|
||||
};
|
||||
|
||||
public: // constructors
|
||||
/** \brief Construct an empty KeyLocator.
|
||||
* \post `empty() == true`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -63,8 +63,8 @@ struct Field
|
||||
static_assert(std::is_base_of<field_location_tags::Base, typename X::FieldLocation>::value, "");
|
||||
static_assert(std::is_same<typename X::TlvType::value_type, uint64_t>::value, "");
|
||||
static_assert(std::is_same<typename X::IsRepeatable::value_type, bool>::value, "");
|
||||
NDN_CXX_ASSERT_DEFAULT_CONSTRUCTIBLE(typename X::ValueType);
|
||||
BOOST_CONCEPT_ASSERT((boost::CopyConstructible<typename X::ValueType>));
|
||||
static_assert(std::is_default_constructible<typename X::ValueType>::value, "");
|
||||
static_assert(std::is_copy_constructible<typename X::ValueType>::value, "");
|
||||
BOOST_CONCEPT_USAGE(Field)
|
||||
{
|
||||
Block wire;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "ndn-cxx/lp/packet.hpp"
|
||||
#include "ndn-cxx/lp/fields.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -32,14 +32,18 @@ MetadataObject::MetadataObject() = default;
|
||||
|
||||
MetadataObject::MetadataObject(const Data& data)
|
||||
{
|
||||
if (data.getContentType() != tlv::ContentType_Blob) {
|
||||
NDN_THROW(Error("Expecting ContentType Blob, got " + to_string(data.getContentType())));
|
||||
}
|
||||
|
||||
if (!isValidName(data.getName())) {
|
||||
NDN_THROW(Error("Name " + data.getName().toUri() + " is not a valid MetadataObject name"));
|
||||
}
|
||||
|
||||
if (data.getContentType() != tlv::ContentType_Blob) {
|
||||
NDN_THROW(Error("MetadataObject has invalid ContentType " + to_string(data.getContentType())));
|
||||
}
|
||||
|
||||
if (data.getContent().value_size() == 0) {
|
||||
NDN_THROW(Error("MetadataObject is empty"));
|
||||
}
|
||||
|
||||
data.getContent().parse();
|
||||
// ignore non-Name elements before the first one
|
||||
m_versionedName.wireDecode(data.getContent().get(tlv::Name));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -16,6 +16,8 @@
|
||||
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*
|
||||
* @author Chavoosh Ghasemi <chghasemi@cs.arizona.edu>
|
||||
*/
|
||||
|
||||
@@ -24,7 +26,7 @@
|
||||
|
||||
#include "ndn-cxx/data.hpp"
|
||||
#include "ndn-cxx/interest.hpp"
|
||||
#include "ndn-cxx/security/v2/key-chain.hpp"
|
||||
#include "ndn-cxx/security/key-chain.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
@@ -79,7 +81,7 @@ public:
|
||||
NDN_CXX_NODISCARD Data
|
||||
makeData(Name discoveryInterestName,
|
||||
KeyChain& keyChain,
|
||||
const ndn::security::SigningInfo& si = KeyChain::getDefaultSigningInfo(),
|
||||
const ndn::security::SigningInfo& si = security::SigningInfo(),
|
||||
optional<uint64_t> version = nullopt,
|
||||
time::milliseconds freshnessPeriod = 10_ms) const;
|
||||
|
||||
|
||||
+12
-13
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -151,17 +151,16 @@ public:
|
||||
*
|
||||
* Procedure for adding a top-level prefix:
|
||||
* 1. if the new top-level prefix overlaps with an existing top-level prefix
|
||||
* (one top-level prefix is a prefix of another top-level prefix), throw std::domain_error
|
||||
* 2. if wantRegister is true, invoke face.registerPrefix for the top-level prefix;
|
||||
* (one top-level prefix is a prefix of another top-level prefix), throw std::domain_error.
|
||||
* 2. if \p wantRegister is true, invoke Face::registerPrefix for the top-level prefix;
|
||||
* the returned RegisteredPrefixHandle shall be recorded internally, indexed by the top-level
|
||||
* prefix
|
||||
* 3. foreach relPrefix from ControlCommands and StatusDatasets,
|
||||
* join the top-level prefix with the relPrefix to obtain the full prefix,
|
||||
* and invoke non-registering overload of face.setInterestFilter,
|
||||
* prefix.
|
||||
* 3. for each `relPrefix` from ControlCommands and StatusDatasets,
|
||||
* join the top-level prefix with `relPrefix` to obtain the full prefix,
|
||||
* and invoke non-registering overload of Face::setInterestFilter,
|
||||
* with the InterestHandler set to an appropriate private method to handle incoming Interests
|
||||
* for the ControlCommand or StatusDataset;
|
||||
* the returned InterestFilterHandle shall be recorded internally, indexed by the top-level
|
||||
* prefix
|
||||
* for the ControlCommand or StatusDataset; the returned InterestFilterHandle shall be
|
||||
* recorded internally, indexed by the top-level prefix.
|
||||
*/
|
||||
void
|
||||
addTopPrefix(const Name& prefix, bool wantRegister = true,
|
||||
@@ -171,9 +170,9 @@ public:
|
||||
* \param prefix a top-level prefix, e.g., "/localhost/nfd"
|
||||
*
|
||||
* Procedure for removing a top-level prefix:
|
||||
* 1. if the top-level prefix has not been added, abort these steps
|
||||
* 2. if the top-level prefix has been added with wantRegister, unregister the prefix
|
||||
* 3. unset each Interest filter recorded during addTopPrefix,
|
||||
* 1. if the top-level prefix has not been added, abort these steps.
|
||||
* 2. if the top-level prefix has been added with `wantRegister`, unregister the prefix.
|
||||
* 3. clear all Interest filters set during addTopPrefix().
|
||||
*/
|
||||
void
|
||||
removeTopPrefix(const Name& prefix);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -106,6 +106,7 @@ FaceCreateCommand::FaceCreateCommand()
|
||||
.optional(CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL)
|
||||
.optional(CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD)
|
||||
.optional(CONTROL_PARAMETER_MTU)
|
||||
.optional(CONTROL_PARAMETER_BANDWIDTH)
|
||||
.optional(CONTROL_PARAMETER_FLAGS)
|
||||
.optional(CONTROL_PARAMETER_MASK);
|
||||
m_responseValidator
|
||||
@@ -116,6 +117,7 @@ FaceCreateCommand::FaceCreateCommand()
|
||||
.optional(CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL)
|
||||
.optional(CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD)
|
||||
.optional(CONTROL_PARAMETER_MTU)
|
||||
.optional(CONTROL_PARAMETER_BANDWIDTH)
|
||||
.required(CONTROL_PARAMETER_FLAGS);
|
||||
}
|
||||
|
||||
@@ -145,6 +147,7 @@ FaceUpdateCommand::FaceUpdateCommand()
|
||||
.optional(CONTROL_PARAMETER_FACE_PERSISTENCY)
|
||||
.optional(CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL)
|
||||
.optional(CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD)
|
||||
.optional(CONTROL_PARAMETER_MTU)
|
||||
.optional(CONTROL_PARAMETER_FLAGS)
|
||||
.optional(CONTROL_PARAMETER_MASK);
|
||||
m_responseValidator
|
||||
@@ -152,6 +155,7 @@ FaceUpdateCommand::FaceUpdateCommand()
|
||||
.required(CONTROL_PARAMETER_FACE_PERSISTENCY)
|
||||
.optional(CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL)
|
||||
.optional(CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD)
|
||||
.optional(CONTROL_PARAMETER_MTU)
|
||||
.required(CONTROL_PARAMETER_FLAGS);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ndn-cxx/encoding/tlv-nfd.hpp"
|
||||
#include "ndn-cxx/util/concepts.hpp"
|
||||
#include "ndn-cxx/util/string-helper.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace ndn {
|
||||
namespace nfd {
|
||||
@@ -51,6 +52,9 @@ ControlParameters::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
if (this->hasBandwidth()) {
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Bandwidth, m_bandwidth);
|
||||
}
|
||||
if (this->hasMtu()) {
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mtu, m_mtu);
|
||||
}
|
||||
@@ -238,6 +242,12 @@ ControlParameters::wireDecode(const Block& block)
|
||||
if (this->hasMtu()) {
|
||||
m_mtu = readNonNegativeInteger(*val);
|
||||
}
|
||||
|
||||
val = m_wire.find(tlv::nfd::Bandwidth);
|
||||
m_hasFields[CONTROL_PARAMETER_BANDWIDTH] = val != m_wire.elements_end();
|
||||
if (this->hasBandwidth()) {
|
||||
m_bandwidth = readNonNegativeInteger(*val);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -382,6 +392,10 @@ operator<<(std::ostream& os, const ControlParameters& parameters)
|
||||
os << "Mtu: " << parameters.getMtu() << ", ";
|
||||
}
|
||||
|
||||
if (parameters.hasBandwidth()) {
|
||||
os << "Bandwidth: " << parameters.getBandwidth() << ", ";
|
||||
}
|
||||
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ enum ControlParameterField {
|
||||
CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL,
|
||||
CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD,
|
||||
CONTROL_PARAMETER_MTU,
|
||||
CONTROL_PARAMETER_BANDWIDTH,
|
||||
CONTROL_PARAMETER_UBOUND
|
||||
};
|
||||
|
||||
@@ -69,7 +70,8 @@ const std::string CONTROL_PARAMETER_FIELD[CONTROL_PARAMETER_UBOUND] = {
|
||||
"FacePersistency",
|
||||
"BaseCongestionMarkingInterval",
|
||||
"DefaultCongestionThreshold",
|
||||
"Mtu"
|
||||
"Mtu",
|
||||
"Bandwidth",
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -595,6 +597,43 @@ public: // getters & setters
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool hasBandwidth() const
|
||||
{
|
||||
return m_hasFields[CONTROL_PARAMETER_BANDWIDTH];
|
||||
}
|
||||
|
||||
/** \brief get bandwidth (measured in bps)
|
||||
*
|
||||
* This value is capped at MAX_NDN_BITRATE, even if the bandwidth of the face is unlimited.
|
||||
*/
|
||||
uint64_t
|
||||
getBandwidth() const
|
||||
{
|
||||
BOOST_ASSERT(this->hasBandwidth());
|
||||
return m_bandwidth;
|
||||
}
|
||||
|
||||
/** \brief set bandwidth (measured in bps)
|
||||
*
|
||||
* This value is capped at MAX_NDN_BITRATE, even if the bandwidth of the face is unlimited.
|
||||
*/
|
||||
ControlParameters&
|
||||
setBandwidth(uint64_t bandwidth)
|
||||
{
|
||||
m_wire.reset();
|
||||
m_bandwidth = bandwidth;
|
||||
m_hasFields[CONTROL_PARAMETER_BANDWIDTH] = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ControlParameters&
|
||||
unsetBandwidth()
|
||||
{
|
||||
m_wire.reset();
|
||||
m_hasFields[CONTROL_PARAMETER_BANDWIDTH] = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::vector<bool>&
|
||||
getPresentFields() const
|
||||
{
|
||||
@@ -652,6 +691,7 @@ private: // fields
|
||||
time::nanoseconds m_baseCongestionMarkingInterval;
|
||||
uint64_t m_defaultCongestionThreshold;
|
||||
uint64_t m_mtu;
|
||||
uint64_t m_bandwidth;
|
||||
|
||||
private:
|
||||
mutable Block m_wire;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "ndn-cxx/mgmt/nfd/controller.hpp"
|
||||
#include "ndn-cxx/face.hpp"
|
||||
#include "ndn-cxx/security/v2/key-chain.hpp"
|
||||
#include "ndn-cxx/security/key-chain.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -22,14 +22,14 @@
|
||||
#ifndef NDN_MGMT_NFD_CONTROLLER_HPP
|
||||
#define NDN_MGMT_NFD_CONTROLLER_HPP
|
||||
|
||||
#include "ndn-cxx/mgmt/nfd/command-options.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/control-command.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/control-response.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/status-dataset.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/command-options.hpp"
|
||||
#include "ndn-cxx/security/command-interest-signer.hpp"
|
||||
#include "ndn-cxx/security/key-chain.hpp"
|
||||
#include "ndn-cxx/security/validator-null.hpp"
|
||||
#include "ndn-cxx/security/v2/key-chain.hpp"
|
||||
#include "ndn-cxx/security/v2/validator.hpp"
|
||||
#include "ndn-cxx/security/validator.hpp"
|
||||
#include "ndn-cxx/util/segment-fetcher.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
+28
-10
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/logic/tribool.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace name {
|
||||
|
||||
@@ -87,14 +89,31 @@ canDecodeTypedConvention()
|
||||
}
|
||||
|
||||
static bool
|
||||
chooseAltUri(UriFormat format)
|
||||
wantAltUri(UriFormat format)
|
||||
{
|
||||
if (format == UriFormat::DEFAULT) {
|
||||
static const char* env = std::getenv("NDN_NAME_ALT_URI");
|
||||
static bool defaultSetting = env == nullptr || env[0] != '0';
|
||||
return defaultSetting;
|
||||
static const auto wantAltEnv = []() -> boost::tribool {
|
||||
const char* env = std::getenv("NDN_NAME_ALT_URI");
|
||||
if (env == nullptr)
|
||||
return boost::indeterminate;
|
||||
else if (env[0] == '0')
|
||||
return false;
|
||||
else if (env[0] == '1')
|
||||
return true;
|
||||
else
|
||||
return boost::indeterminate;
|
||||
}();
|
||||
|
||||
if (format == UriFormat::ENV_OR_CANONICAL) {
|
||||
static const bool wantAlt = boost::indeterminate(wantAltEnv) ? false : bool(wantAltEnv);
|
||||
return wantAlt;
|
||||
}
|
||||
else if (format == UriFormat::ENV_OR_ALTERNATE) {
|
||||
static const bool wantAlt = boost::indeterminate(wantAltEnv) ? true : bool(wantAltEnv);
|
||||
return wantAlt;
|
||||
}
|
||||
else {
|
||||
return format == UriFormat::ALTERNATE;
|
||||
}
|
||||
return format == UriFormat::ALTERNATE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -182,7 +201,7 @@ Component::fromEscapedString(const std::string& input)
|
||||
void
|
||||
Component::toUri(std::ostream& os, UriFormat format) const
|
||||
{
|
||||
if (chooseAltUri(format)) {
|
||||
if (wantAltUri(format)) {
|
||||
detail::getComponentTypeTable().get(type()).writeUri(os, *this);
|
||||
}
|
||||
else {
|
||||
@@ -455,8 +474,7 @@ Component::equals(const Component& other) const
|
||||
{
|
||||
return type() == other.type() &&
|
||||
value_size() == other.value_size() &&
|
||||
(empty() || // needed with Apple clang < 9.0.0 due to libc++ bug
|
||||
std::equal(value_begin(), value_end(), other.value_begin()));
|
||||
std::equal(value_begin(), value_end(), other.value_begin());
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
+17
-29
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -30,24 +30,33 @@
|
||||
namespace ndn {
|
||||
namespace name {
|
||||
|
||||
/** @brief Identify a format of URI representation.
|
||||
/** @brief Format used for the URI representation of a name.
|
||||
* @sa http://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
|
||||
*/
|
||||
enum class UriFormat {
|
||||
DEFAULT, ///< ALTERNATE, unless `NDN_NAME_ALT_URI` environment variable is set to '0'
|
||||
CANONICAL, ///< always use <type-number>=<percent-encoded-value> format
|
||||
ALTERNATE, ///< prefer alternate format when available
|
||||
/// Always use `<type-number>=<percent-encoded-value>` format
|
||||
CANONICAL,
|
||||
/// Always prefer the alternate format when available
|
||||
ALTERNATE,
|
||||
/// Same as UriFormat::CANONICAL, unless `NDN_NAME_ALT_URI` environment variable is set to '1'
|
||||
ENV_OR_CANONICAL,
|
||||
/// Same as UriFormat::ALTERNATE, unless `NDN_NAME_ALT_URI` environment variable is set to '0'
|
||||
ENV_OR_ALTERNATE,
|
||||
/// Use the library's default format; currently equivalent to UriFormat::ENV_OR_ALTERNATE
|
||||
DEFAULT = ENV_OR_ALTERNATE,
|
||||
};
|
||||
|
||||
/** @brief Identify a style of NDN Naming Conventions.
|
||||
* @sa https://named-data.net/publications/techreports/ndn-tr-22-2-ndn-memo-naming-conventions/
|
||||
*/
|
||||
enum class Convention {
|
||||
MARKER = 1 << 0, ///< component markers (revision 1)
|
||||
TYPED = 1 << 1, ///< typed name components (revision 2)
|
||||
MARKER = 1 << 0, ///< Component markers (revision 1)
|
||||
TYPED = 1 << 1, ///< Typed name components (revision 2)
|
||||
EITHER = MARKER | TYPED,
|
||||
};
|
||||
|
||||
/** @brief Markers in Naming Conventions rev1
|
||||
/** @brief Name component markers defined in Naming Conventions revision 1.
|
||||
* @sa https://named-data.net/publications/techreports/ndn-tr-22-ndn-memo-naming-conventions/
|
||||
*/
|
||||
enum : uint8_t {
|
||||
SEGMENT_MARKER = 0x00,
|
||||
@@ -308,13 +317,6 @@ public: // naming conventions
|
||||
bool
|
||||
isByteOffset() const;
|
||||
|
||||
/// @deprecated use isByteOffset
|
||||
bool
|
||||
isSegmentOffset() const
|
||||
{
|
||||
return isByteOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the component is a timestamp per NDN naming conventions
|
||||
* @sa https://named-data.net/publications/techreports/ndn-tr-22-2-ndn-memo-naming-conventions/
|
||||
@@ -383,13 +385,6 @@ public: // naming conventions
|
||||
uint64_t
|
||||
toByteOffset() const;
|
||||
|
||||
/// @deprecated use toByteOffset
|
||||
uint64_t
|
||||
toSegmentOffset() const
|
||||
{
|
||||
return toByteOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interpret as timestamp component using NDN naming conventions
|
||||
*
|
||||
@@ -465,13 +460,6 @@ public: // naming conventions
|
||||
static Component
|
||||
fromByteOffset(uint64_t offset);
|
||||
|
||||
/// @deprecated use fromByteOffset
|
||||
static Component
|
||||
fromSegmentOffset(uint64_t offset)
|
||||
{
|
||||
return fromByteOffset(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create sequence number component using NDN naming conventions
|
||||
*
|
||||
|
||||
+19
-26
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -23,8 +23,8 @@
|
||||
* @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
|
||||
*/
|
||||
|
||||
#ifndef NDN_NAME_HPP
|
||||
#define NDN_NAME_HPP
|
||||
#ifndef NDN_CXX_NAME_HPP
|
||||
#define NDN_CXX_NAME_HPP
|
||||
|
||||
#include "ndn-cxx/name-component.hpp"
|
||||
|
||||
@@ -39,6 +39,7 @@ class Name;
|
||||
using PartialName = Name;
|
||||
|
||||
/** @brief Represents an absolute name
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html
|
||||
*/
|
||||
class Name
|
||||
{
|
||||
@@ -82,34 +83,34 @@ public: // constructors, encoding, decoding
|
||||
|
||||
/** @brief Parse name from NDN URI
|
||||
* @param uri a null-terminated URI string
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
|
||||
*/
|
||||
Name(const char* uri);
|
||||
|
||||
/** @brief Create name from NDN URI
|
||||
* @param uri a URI string
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
|
||||
*/
|
||||
Name(std::string uri);
|
||||
|
||||
/** @brief Write URI representation of the name to the output stream
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
|
||||
*/
|
||||
void
|
||||
toUri(std::ostream& os, name::UriFormat format = name::UriFormat::DEFAULT) const;
|
||||
|
||||
/** @brief Get URI representation of the name
|
||||
* @return URI representation; "ndn:" scheme identifier is not included
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
|
||||
* @note To print URI representation into a stream, it is more efficient to use ``os << name``.
|
||||
* @return URI representation; the "ndn:" scheme identifier is not included
|
||||
* @note To print URI representation into a stream, it is more efficient to use `os << name`.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
|
||||
*/
|
||||
std::string
|
||||
toUri(name::UriFormat format = name::UriFormat::DEFAULT) const;
|
||||
|
||||
/** @brief Check if this Name instance already has wire encoding
|
||||
/** @brief Check if this instance already has wire encoding
|
||||
*/
|
||||
bool
|
||||
hasWire() const
|
||||
hasWire() const noexcept
|
||||
{
|
||||
return m_wire.hasWire();
|
||||
}
|
||||
@@ -374,9 +375,8 @@ public: // modifiers
|
||||
append(const PartialName& name);
|
||||
|
||||
/** @brief Append a component with a nonNegativeInteger
|
||||
* @sa number the number
|
||||
* @return a reference to this name, to allow chaining
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/tlv.html#non-negative-integer-encoding
|
||||
*/
|
||||
Name&
|
||||
appendNumber(uint64_t number)
|
||||
@@ -428,13 +428,6 @@ public: // modifiers
|
||||
return append(Component::fromByteOffset(offset));
|
||||
}
|
||||
|
||||
/// @deprecated use appendByteOffset
|
||||
Name&
|
||||
appendSegmentOffset(uint64_t offset)
|
||||
{
|
||||
return appendByteOffset(offset);
|
||||
}
|
||||
|
||||
/** @brief Append a timestamp component
|
||||
* @param timestamp the timestamp to append; if nullopt, the current system time is used
|
||||
* @return a reference to this name, to allow chaining
|
||||
@@ -585,7 +578,7 @@ public: // algorithms
|
||||
* @retval zero this equals other
|
||||
* @retval positive this comes after other in canonical ordering
|
||||
*
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html#canonical-order
|
||||
*/
|
||||
int
|
||||
compare(const Name& other) const
|
||||
@@ -642,8 +635,8 @@ private: // non-member operators
|
||||
return lhs.compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
/** @brief Print URI representation of a name
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
|
||||
/** @brief Print the URI representation of a name.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
|
||||
*/
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Name& name)
|
||||
@@ -663,8 +656,8 @@ private:
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Name);
|
||||
|
||||
/** @brief Parse URI from stream as Name
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
|
||||
/** @brief Parse URI from stream as Name.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
|
||||
*/
|
||||
std::istream&
|
||||
operator>>(std::istream& is, Name& name);
|
||||
@@ -682,4 +675,4 @@ struct hash<ndn::Name>
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // NDN_NAME_HPP
|
||||
#endif // NDN_CXX_NAME_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California,
|
||||
* Copyright (c) 2013-2020 Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -29,10 +29,11 @@
|
||||
#include "ndn-cxx/net/dns.hpp"
|
||||
#include "ndn-cxx/util/string-helper.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
#include <regex>
|
||||
#include <set>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -24,18 +24,13 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
static const name::Component KEYWORD_PA_COMP = "20025041"_block;
|
||||
const name::Component KEYWORD_PA_COMP = "20 02 5041"_block; // 32=PA
|
||||
|
||||
PrefixAnnouncement::PrefixAnnouncement() = default;
|
||||
|
||||
PrefixAnnouncement::PrefixAnnouncement(Data data)
|
||||
: m_data(std::move(data))
|
||||
{
|
||||
if (m_data->getContentType() != tlv::ContentType_PrefixAnn) {
|
||||
NDN_THROW(Error("Data is not a prefix announcement: ContentType is " +
|
||||
to_string(m_data->getContentType())));
|
||||
}
|
||||
|
||||
const Name& dataName = m_data->getName();
|
||||
if (dataName.size() < 3 || dataName[-3] != KEYWORD_PA_COMP ||
|
||||
!dataName[-2].isVersion() || !dataName[-1].isSegment()) {
|
||||
@@ -43,6 +38,15 @@ PrefixAnnouncement::PrefixAnnouncement(Data data)
|
||||
}
|
||||
m_announcedName = dataName.getPrefix(-3);
|
||||
|
||||
if (m_data->getContentType() != tlv::ContentType_PrefixAnn) {
|
||||
NDN_THROW(Error("Data is not a prefix announcement: ContentType is " +
|
||||
to_string(m_data->getContentType())));
|
||||
}
|
||||
|
||||
if (m_data->getContent().value_size() == 0) {
|
||||
NDN_THROW(Error("Prefix announcement is empty"));
|
||||
}
|
||||
|
||||
const Block& payload = m_data->getContent();
|
||||
payload.parse();
|
||||
|
||||
@@ -56,7 +60,7 @@ PrefixAnnouncement::PrefixAnnouncement(Data data)
|
||||
for (const Block& element : payload.elements()) {
|
||||
if (element.type() != tlv::nfd::ExpirationPeriod && element.type() != tlv::ValidityPeriod &&
|
||||
tlv::isCriticalType(element.type())) {
|
||||
NDN_THROW(Error("unrecognized element of critical type " + to_string(element.type())));
|
||||
NDN_THROW(Error("Unrecognized element of critical type " + to_string(element.type())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loaded 100 of 329 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user