Compare commits

..
2 Commits
Author SHA1 Message Date
SunnyQjm 58b423fe00 feta(mgmt): Support set bandwith while create face by nfdc 2023-12-15 14:56:35 +00:00
SunnyQjm e72ce81d2b feat: Add qsccp tags 2023-12-03 19:02:32 +08:00
720 changed files with 28313 additions and 21484 deletions

No files matched your search

-17
View File
@@ -1,17 +0,0 @@
name: CI
on:
push:
paths-ignore:
- 'docs/**'
- '*.conf.sample*'
- '*.md'
- '.mailmap'
workflow_dispatch:
permissions: {}
jobs:
Ubuntu:
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
macOS:
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
-48
View File
@@ -1,48 +0,0 @@
name: Publish Docker image
on:
push:
branches:
- master
paths-ignore:
- '*.md'
- '.mailmap'
workflow_dispatch:
permissions:
contents: read
packages: write
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: latest=true
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
pull: true
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
-21
View File
@@ -1,21 +0,0 @@
name: Docs
on:
push:
workflow_dispatch:
inputs:
skip-deploy:
description: 'Skip deployment?'
required: true
type: boolean
permissions: {}
jobs:
html:
uses: named-data/actions/.github/workflows/docs-html.yml@v1
with:
# Deploy only the master branch and release tags
deploy: ${{ !inputs.skip-deploy && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/ndn-cxx-')) }}
secrets: inherit
man:
uses: named-data/actions/.github/workflows/docs-man.yml@v1
-1
View File
@@ -27,4 +27,3 @@ __pycache__/
# Other
/VERSION.info
/examples/example-trust-anchor.cert
+16 -36
View File
@@ -1,52 +1,32 @@
#!/usr/bin/env bash
set -eo pipefail
case $(uname) in
Linux)
if [[ -e /etc/os-release ]]; then
source /etc/os-release
else
source /usr/lib/os-release
fi
export ID VERSION_ID
export ID_LIKE="${ID} ${ID_LIKE} linux"
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
;;
Darwin)
# Emulate a subset of os-release(5)
export ID=macos
export VERSION_ID=$(sw_vers -productVersion)
export PATH="/usr/local/bin${PATH:+:}${PATH}"
if [[ -x /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -x /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
;;
esac
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
if [[ $JOB_NAME == *"code-coverage" ]]; then
export DISABLE_ASAN=yes
export DISABLE_HEADERS_CHECK=yes
fi
# https://reproducible-builds.org/docs/source-date-epoch/
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
nanos() {
# Cannot use date(1) because macOS does not support %N format specifier
python3 -c 'import time; print(int(time.time() * 1e9))'
}
for file in .jenkins.d/*; do
[[ -f $file && -x $file ]] || continue
if [[ -n $GITHUB_ACTIONS ]]; then
if [[ -n $TRAVIS ]]; then
label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
echo "::group::${label}"
echo -ne "travis_fold:start:${label}\r"
echo -ne "travis_time:start:${label}\r"
start=$(nanos)
fi
echo "\$ $file"
"$file"
if [[ -n $GITHUB_ACTIONS ]]; then
echo "::endgroup::"
if [[ -n $TRAVIS ]]; then
finish=$(nanos)
echo -ne "travis_time:end:${label}:start=${start},finish=${finish},duration=$((finish-start)),event=${label}\r"
echo -ne "travis_fold:end:${label}\r"
fi
done
+32 -32
View File
@@ -1,38 +1,38 @@
#!/usr/bin/env bash
set -eo pipefail
set -ex
APT_PKGS=(build-essential pkg-config python3-minimal
libboost-all-dev libssl-dev libsqlite3-dev)
FORMULAE=(boost openssl pkg-config)
PIP_PKGS=()
case $JOB_NAME in
*code-coverage)
APT_PKGS+=(lcov python3-pip)
PIP_PKGS+=('gcovr~=5.2')
;;
*Docs)
APT_PKGS+=(doxygen graphviz python3-pip)
FORMULAE+=(doxygen graphviz)
PIP_PKGS+=(sphinx sphinxcontrib-doxylink)
;;
esac
set -x
if [[ $ID == macos ]]; then
if [[ -n $GITHUB_ACTIONS ]]; then
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
if has OSX $NODE_LABELS; then
FORMULAE=(boost openssl pkg-config)
if has OSX-10.13 $NODE_LABELS || has OSX-10.14 $NODE_LABELS; then
FORMULAE+=(python)
fi
brew update
brew install --formula "${FORMULAE[@]}"
elif [[ $ID_LIKE == *debian* ]]; then
if [[ -n $TRAVIS ]]; then
# 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 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
elif has Ubuntu $NODE_LABELS; then
sudo apt-get -qq update
sudo apt-get -qy install "${APT_PKGS[@]}"
elif [[ $ID_LIKE == *fedora* ]]; then
sudo dnf -y install gcc-c++ libasan lld pkgconf-pkg-config python3 \
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
fi
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
if (( ${#PIP_PKGS[@]} )); then
pip3 install --user --upgrade --upgrade-strategy=eager "${PIP_PKGS[@]}"
fi
+7
View File
@@ -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
-9
View File
@@ -1,9 +0,0 @@
#!/usr/bin/env bash
set -exo pipefail
PROJ=ndn-cxx
sudo rm -f /usr/local/bin/ndnsec*
sudo rm -fr /usr/local/include/"$PROJ"
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
sudo rm -f /usr/local/lib{,64}/pkgconfig/{,lib}"$PROJ".pc
+13 -14
View File
@@ -1,5 +1,8 @@
#!/usr/bin/env bash
set -eo pipefail
set -ex
git submodule sync
git submodule update --init
if [[ -z $DISABLE_ASAN ]]; then
ASAN="--with-sanitizer=address"
@@ -7,43 +10,39 @@ fi
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
fi
if [[ $ID == macos && ${VERSION_ID%%.*} -ge 12 ]]; then
KEYCHAIN="--without-osx-keychain"
fi
if [[ -n $DISABLE_PCH ]]; then
if has CentOS-8 $NODE_LABELS; then
# https://bugzilla.redhat.com/show_bug.cgi?id=1721553
PCH="--without-pch"
fi
set -x
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
# 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
./waf --color=yes build -j$WAF_JOBS
# Cleanup
./waf --color=yes distclean
# Build static and shared library in release mode without tests
./waf --color=yes configure --enable-static --enable-shared $PCH
./waf --color=yes build
./waf --color=yes build -j$WAF_JOBS
# Cleanup
./waf --color=yes distclean
fi
# 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 $KEYCHAIN $PCH
./waf --color=yes build
./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 the debug version)
# Install
sudo ./waf --color=yes install
sudo_preserve_env PATH -- ./waf --color=yes install
if [[ $ID_LIKE == *fedora* ]]; then
if has CentOS-8 $NODE_LABELS; then
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
fi
if [[ $ID_LIKE == *linux* ]]; then
if has Linux $NODE_LABELS; then
sudo ldconfig
fi
+10 -7
View File
@@ -1,5 +1,14 @@
#!/usr/bin/env bash
set -eo pipefail
set -ex
# Prepare environment
rm -rf ~/.ndn
if has OSX $NODE_LABELS; then
security unlock-keychain -p named-data
fi
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
ASAN_OPTIONS="color=always"
@@ -11,16 +20,10 @@ ASAN_OPTIONS+=":detect_invalid_pointer_pairs=2"
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
export ASAN_OPTIONS
# https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/runtime_config/summary.html
export BOOST_TEST_BUILD_INFO=1
export BOOST_TEST_COLOR_OUTPUT=1
export BOOST_TEST_DETECT_MEMORY_LEAK=0
export BOOST_TEST_LOGGER=HRF,test_suite,stdout:XML,all,build/xunit-log.xml
set -x
# Prepare environment
rm -rf ~/.ndn
# Run unit tests
./build/unit-tests
+13 -15
View File
@@ -1,32 +1,30 @@
#!/usr/bin/env bash
set -exo pipefail
set -ex
if [[ $JOB_NAME == *"code-coverage" ]]; then
# Generate an XML report (Cobertura format) and a detailed HTML report using gcovr
# Note: trailing slashes are important in the paths below. Do not remove them!
gcovr --object-directory build \
--filter ndn-cxx/ \
--exclude ndn-cxx/detail/nonstd/ \
--exclude-throw-branches \
--exclude-unreachable-branches \
--cobertura build/coverage.xml \
--html-details build/gcovr/ \
--print-summary
gcovr --object-directory=build \
--output=build/coverage.xml \
--exclude="$PWD/(examples|tests)" \
--root=. \
--xml
# Generate a detailed HTML report using lcov
# Generate also a detailed HTML output, but using lcov (better results)
lcov --quiet \
--capture \
--directory . \
--exclude "$PWD/ndn-cxx/detail/nonstd/*" \
--exclude "$PWD/tests/*" \
--no-external \
--rc lcov_branch_coverage=1 \
--output-file build/coverage-with-tests.info
lcov --quiet \
--remove build/coverage-with-tests.info "$PWD/tests/*" \
--rc lcov_branch_coverage=1 \
--output-file build/coverage.info
genhtml --branch-coverage \
--demangle-cpp \
--legend \
--output-directory build/lcov \
--output-directory build/coverage \
--title "ndn-cxx unit tests" \
build/coverage.info
fi
+11 -11
View File
@@ -1,24 +1,23 @@
#!/usr/bin/env bash
set -eo pipefail
# It's intentional not to use `set -x`, because this script explicitly prints useful information
# and should not run in trace mode.
PROJ=ndn-cxx
PCFILE=libndn-cxx
# 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 [[ $ID_LIKE == *fedora* ]]; then
if has CentOS-8 $NODE_LABELS; then
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
fi
CXX=${CXX:-g++}
STD=-std=c++17
CXXFLAGS="-O2 -Wall -Wno-unneeded-internal-declaration -Wno-unused-const-variable $(pkg-config --cflags libndn-cxx $PCFILE)"
INCLUDEDIR="$(pkg-config --variable=includedir $PCFILE)"/$PROJ
STD=-std=c++14
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"
@@ -26,12 +25,13 @@ NCHECKED=0
NERRORS=0
while IFS= read -r -d '' H; do
echo "Checking header ${H#${INCLUDEDIR}/}"
"$CXX" -xc++ $STD $CXXFLAGS -c -o /dev/null "$H" || : $((NERRORS++))
: $((NCHECKED++))
"$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 headers found. Is $PROJ installed?"
echo 'No headers found. Is ndn-cxx installed?'
exit 1
else
echo "$NCHECKED headers checked."
+16 -24
View File
@@ -1,36 +1,28 @@
# Continuous Integration Scripts
# CONTINUOUS INTEGRATION SCRIPTS
## Environment Variables
## Environment Variables Used in Build Scripts
- `ID`: lower-case string that identifies the operating system, for example: `ID=ubuntu`,
`ID=centos`. See [os-release(5)] for more information. On macOS, where `os-release` is
not available, we emulate it by setting `ID=macos`.
- `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.
- `ID_LIKE`: space-separated list of operating system identifiers that are closely related
to the running OS. See [os-release(5)] for more information. The listed values are used
by the CI scripts to select the proper behavior for different platforms and OS flavors.
The list should normally contain `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
Examples:
Example values:
- On CentOS, `ID_LIKE="centos rhel fedora linux"`
- On Ubuntu, `ID_LIKE="ubuntu debian linux"`
- `[OS_TYPE]`: `Linux`, `OSX`
- `[DISTRO_TYPE]`: `Ubuntu`, `CentOS`
- `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`, `CentOS-8`, `OSX-10.14`, `OSX-10.15`
- `VERSION_ID`: identifies the operating system version, excluding any release code names.
See [os-release(5)] for more information. Examples: `VERSION_ID=42`, `VERSION_ID=22.04`.
- `JOB_NAME`: optional variable that defines the type of build job. Depending on the job type,
the build scripts can perform different tasks.
- `JOB_NAME`: defines the type of the current CI job. Depending on the job type, the CI
scripts can perform different tasks.
Supported values:
Possible values:
- empty: default build task
- `code-coverage`: debug build with tests and code coverage analysis
- `code-coverage`: debug build with tests and code coverage analysis (Ubuntu Linux is assumed)
- `limited-build`: only a single debug build with tests
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled
version of ndn-cxx. If not set, `/tmp` is used.
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled version
of ndn-cxx. If not set, `/tmp` is used.
- `DISABLE_ASAN`: disable building with AddressSanitizer. This is automatically set for
the `code-coverage` job type.
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
- `WAF_JOBS`: number of parallel build threads used by waf, defaults to 1.
+39
View File
@@ -0,0 +1,39 @@
has() {
local saved_xtrace
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
set +x
local p=$1
shift
local i ret=1
for i in "$@"; do
if [[ "${i}" == "${p}" ]]; then
ret=0
break
fi
done
set ${saved_xtrace}
return ${ret}
}
export -f has
sudo_preserve_env() {
local saved_xtrace
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
set +x
local vars=()
while [[ $# -gt 0 ]]; do
local arg=$1
shift
case ${arg} in
--) break ;;
*) vars+=("${arg}=${!arg}") ;;
esac
done
set ${saved_xtrace}
sudo env "${vars[@]}" "$@"
}
export -f sudo_preserve_env
+116
View File
@@ -0,0 +1,116 @@
version: ~> 1.0
language: cpp
os: linux
dist: bionic
arch:
- amd64
- arm64
- ppc64le
- s390x
env:
- COMPILER=g++-7
- COMPILER=g++-9
- COMPILER=clang++-6.0
- COMPILER=clang++-9
jobs:
include:
# 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
# macOS
- os: osx
osx_image: xcode9.4
env: # default compiler
- os: osx
osx_image: xcode10.1
env: # default compiler
- os: osx
osx_image: xcode10.3
env: # default compiler
- os: osx
osx_image: xcode11.3
env: # default compiler
- os: osx
osx_image: xcode11.6
env: # default compiler
- os: osx
osx_image: xcode12
env: # default compiler
allow_failures:
- env: COMPILER=g++-5
- env: COMPILER=g++-6
- env: COMPILER=clang++-4.0
- env: COMPILER=clang++-12
fast_finish: true
before_install:
- |
: Adding apt repositories
case ${COMPILER} in
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++-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%-12} main"
travis_retry sudo apt-get -qq update
;;
esac
install:
- |
: Installing C++ compiler
if [[ -n ${COMPILER} ]]; then
travis_retry sudo apt-get -qy install ${COMPILER/clang++/clang}
fi
before_script:
- |
: 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
script:
- ./.jenkins
+2 -2
View File
@@ -54,8 +54,8 @@ from waflib import Utils, Logs, Errors
from waflib.Configure import conf
from waflib.TaskGen import feature, after_method
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/homebrew/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/homebrew/include', '/opt/local/include', '/sw/include']
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
BOOST_VERSION_FILE = 'boost/version.hpp'
BOOST_VERSION_CODE = '''
+30
View File
@@ -0,0 +1,30 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
from waflib.Configure import conf
STD_TO_STRING = '''
#include <string>
int
main()
{
std::string s = std::to_string(0);
s = std::to_string(0l);
s = std::to_string(0ll);
s = std::to_string(0u);
s = std::to_string(0ul);
s = std::to_string(0ull);
s = std::to_string(0.0f);
s = std::to_string(0.0);
s = std::to_string(0.0l);
s.clear();
}
'''
@conf
def check_std_to_string(self):
if self.check_cxx(msg='Checking for std::to_string',
fragment=STD_TO_STRING, mandatory=False):
self.define('HAVE_STD_TO_STRING', 1)
def configure(conf):
conf.check_std_to_string()
-25
View File
@@ -1,25 +0,0 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
from waflib import Utils
def options(opt):
opt.add_option('--build', default=Utils.unversioned_sys_platform(),
help='Build platform that is doing the actual compilation (e.g., darwin)')
opt.add_option('--host', default=Utils.unversioned_sys_platform(),
help='Host platform on which the compiled binary will run (e.g., android)')
# opt.add_option('--target', default=Utils.unversioned_sys_platform(),
# help='Target platform on which the compiled binary's output will run')
def configure(conf):
conf.env.BUILD = conf.options.build
conf.env.HOST = conf.options.host
# conf.env.TARGET = conf.options.target
conf.start_msg('Build platform')
conf.end_msg(conf.env.BUILD)
conf.start_msg('Host platform')
conf.end_msg(conf.env.HOST)
# conf.start_msg('Target platform')
# conf.end_msg(conf.env.TARGET)
+78 -92
View File
@@ -3,12 +3,10 @@
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 (-Og)')
def configure(conf):
conf.start_msg('Checking C++ compiler version')
@@ -18,27 +16,23 @@ def configure(conf):
errmsg = ''
warnmsg = ''
if cxx == 'gcc':
if ccver < (7, 4, 0):
if ccver < (5, 3, 0):
errmsg = ('The version of gcc you are using is too old.\n'
'The minimum supported gcc version is 9.3.')
elif ccver < (9, 3, 0):
warnmsg = ('Using a version of gcc older than 9.3 is not '
'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 Utils.unversioned_sys_platform() == 'darwin':
if ccver < (10, 0, 0):
errmsg = ('The version of Xcode you are using is too old.\n'
'The minimum supported Xcode version is 12.4.')
elif ccver < (12, 0, 0):
warnmsg = ('Using a version of Xcode older than 12.4 is not '
'officially supported and may result in build failures.')
elif ccver < (7, 0, 0):
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 7.0.')
'The minimum supported clang version is 4.0.')
conf.flags = ClangFlags()
else:
warnmsg = f'{cxx} compiler is unsupported'
warnmsg = '%s compiler is unsupported' % cxx
conf.flags = CompilerFlags()
if errmsg:
@@ -50,7 +44,7 @@ def configure(conf):
else:
conf.end_msg(ccverstr)
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
# General flags are always applied (e.g., selecting C++ language standard)
generalFlags = conf.flags.getGeneralFlags(conf)
@@ -58,7 +52,6 @@ def configure(conf):
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
conf.env.DEFINES += generalFlags['DEFINES']
@Configure.conf
def check_compiler_flags(conf):
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
@@ -81,11 +74,10 @@ def check_compiler_flags(conf):
conf.env.DEFINES += extraFlags['DEFINES']
@Configure.conf
def add_supported_cxxflags(self, cxxflags):
"""
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
"""
if len(cxxflags) == 0:
return
@@ -101,11 +93,10 @@ def add_supported_cxxflags(self, cxxflags):
self.end_msg(' '.join(supportedFlags))
self.env.prepend_value('CXXFLAGS', supportedFlags)
@Configure.conf
def add_supported_linkflags(self, linkflags):
"""
Check which linkflags are supported by the active compiler and add them to env.LINKFLAGS variable.
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
"""
if len(linkflags) == 0:
return
@@ -122,17 +113,13 @@ def add_supported_linkflags(self, linkflags):
self.env.prepend_value('LINKFLAGS', supportedFlags)
class CompilerFlags:
class CompilerFlags(object):
def getCompilerVersion(self, conf):
return tuple(int(i) for i in conf.env.CC_VERSION)
def getGeneralFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
return {
'CXXFLAGS': [],
'LINKFLAGS': [],
'DEFINES': ['BOOST_ASIO_NO_DEPRECATED', 'BOOST_FILESYSTEM_NO_DEPRECATED'],
}
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
def getDebugFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
@@ -142,100 +129,99 @@ class CompilerFlags:
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
class GccClangCommonFlags(CompilerFlags):
class GccBasicFlags(CompilerFlags):
"""
This class defines common flags that work for both gcc and clang compilers.
This class defines basic flags that work for both gcc and clang compilers
"""
def getGeneralFlags(self, conf):
flags = super().getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++17']
if Utils.unversioned_sys_platform() != 'darwin':
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++14']
if Utils.unversioned_sys_platform() == 'linux':
flags['LINKFLAGS'] += ['-fuse-ld=gold']
elif Utils.unversioned_sys_platform() == 'freebsd':
flags['LINKFLAGS'] += ['-fuse-ld=lld']
return flags
__cxxFlags = [
'-fdiagnostics-color',
'-Wall',
'-Wextra',
'-Wpedantic',
'-Wenum-conversion',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-unused-parameter',
]
__linkFlags = ['-Wl,-O1']
def getDebugFlags(self, conf):
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += ['-Og', '-g'] + self.__cxxFlags + [
'-Werror',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
]
flags['LINKFLAGS'] += self.__linkFlags
flags = super(GccBasicFlags, self).getDebugFlags(conf)
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
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-Wl,-O1']
return flags
def getOptimizedFlags(self, conf):
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2', '-g1'] + self.__cxxFlags
flags['LINKFLAGS'] += self.__linkFlags
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2',
'-g',
'-pedantic',
'-Wall',
'-Wextra',
'-Wcatch-value=2',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-Wl,-O1']
return flags
class GccFlags(GccClangCommonFlags):
__cxxFlags = [
'-Wcatch-value=2',
'-Wcomma-subscript', # enabled by default in C++20
'-Wduplicated-branches',
'-Wduplicated-cond',
'-Wlogical-op',
'-Wredundant-tags',
'-Wvolatile', # enabled by default in C++20
]
class GccFlags(GccBasicFlags):
def getDebugFlags(self, conf):
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags = super(GccFlags, self).getDebugFlags(conf)
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().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags = super(GccFlags, self).getOptimizedFlags(conf)
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(GccClangCommonFlags):
class ClangFlags(GccBasicFlags):
def getGeneralFlags(self, conf):
flags = super().getGeneralFlags(conf)
flags = super(ClangFlags, self).getGeneralFlags(conf)
if Utils.unversioned_sys_platform() == 'darwin':
# Bug #4296
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
flags['CXXFLAGS'] += [
['-isystem', f'{brewdir}/include'], # for Homebrew
['-isystem', '/opt/local/include'], # for MacPorts
]
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
['-isystem', '/opt/local/include']] # for MacPorts
elif Utils.unversioned_sys_platform() == 'freebsd':
# Bug #4790
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
return flags
__cxxFlags = [
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
def getDebugFlags(self, conf):
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
if self.getCompilerVersion(conf) < (6, 0, 0):
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
return flags
def getOptimizedFlags(self, conf):
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
if self.getCompilerVersion(conf) < (6, 0, 0):
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
return flags
+49 -55
View File
@@ -1,8 +1,10 @@
#! /usr/bin/env python
# encoding: utf-8
# Yingdi Yu (UCLA) 2016
"""
When using this tool, the wscript should look like:
'''
When using this tool, the wscript will look like:
def options(opt):
opt.load('openssl')
@@ -13,17 +15,15 @@ When using this tool, the wscript should look like:
def build(bld):
bld(source='main.cpp', target='app', use='OPENSSL')
"""
'''
import re
from waflib import Utils
from waflib.Configure import conf
OPENSSL_DIR_OSX = ['/usr/local', '/opt/local', '/usr/local/opt/openssl']
OPENSSL_DIR = ['/usr', '/usr/local', '/opt/local', '/sw']
OPENSSL_DIR_MACOS = ['/usr/local',
'/opt/homebrew/opt/openssl', # Homebrew on arm64
'/usr/local/opt/openssl', # Homebrew on x86_64
'/opt/local'] # MacPorts
def options(opt):
opt.add_option('--with-openssl', type='string', default=None, dest='openssl_dir',
@@ -37,62 +37,55 @@ def __openssl_get_version_file(self, dir):
return None
@conf
def __openssl_find_root_and_version_file(self, root):
if root:
file = self.__openssl_get_version_file(root)
if not file:
self.fatal(f'OpenSSL not found in {root}')
def __openssl_find_root_and_version_file(self, *k, **kw):
root = k and k[0] or kw.get('path', self.options.openssl_dir)
file = self.__openssl_get_version_file(root)
if root and file:
return (root, file)
openssl_dirs = OPENSSL_DIR
openssl_dir = []
if Utils.unversioned_sys_platform() == 'darwin':
openssl_dirs = OPENSSL_DIR_MACOS
openssl_dir = OPENSSL_DIR_OSX
else:
openssl_dir = OPENSSL_DIR
for dir in openssl_dirs:
file = self.__openssl_get_version_file(dir)
if file:
return (dir, file)
if not root:
for dir in openssl_dir:
file = self.__openssl_get_version_file(dir)
if file:
return (dir, file)
self.fatal('OpenSSL not found, please provide a --with-openssl=PATH argument (see --help)')
@conf
def __openssl_check_version(self, version_file, atleast_version):
min_version = tuple(int(i) for i in atleast_version.split('.'))
txt = version_file.read()
# OpenSSL 3.0.0 and later
ver_tuple = (re.search(r'^#\s*define\s+OPENSSL_VERSION_MAJOR\s+(\d+)', txt, re.MULTILINE),
re.search(r'^#\s*define\s+OPENSSL_VERSION_MINOR\s+(\d+)', txt, re.MULTILINE),
re.search(r'^#\s*define\s+OPENSSL_VERSION_PATCH\s+(\d+)', txt, re.MULTILINE))
ver_string = re.search(r'^#\s*define\s+OPENSSL_FULL_VERSION_STR\s+"(.+)"', txt, re.MULTILINE)
if all(ver_tuple):
version = tuple(int(i[1]) for i in ver_tuple)
ver_string = ver_string[1] if ver_string else '.'.join(version)
return (version >= min_version, ver_string)
# OpenSSL 1.1.1 and earlier
ver_number = re.search(r'^#\s*define\s+OPENSSL_VERSION_NUMBER\s+(.+)L', txt, re.MULTILINE)
ver_string = re.search(r'^#\s*define\s+OPENSSL_VERSION_TEXT\s+"(.+)"', txt, re.MULTILINE)
if ver_number and ver_string:
version = int(ver_number[1], 16)
min_version = (min_version[0] << 28) | (min_version[1] << 20) | (min_version[2] << 12) | 0xf
return (version >= min_version, ver_string[1])
self.fatal(f'Cannot extract version information from {version_file}')
if root:
self.fatal('OpenSSL not found in %s' % root)
else:
self.fatal('OpenSSL not found, please provide a --with-openssl=PATH argument (see help)')
@conf
def check_openssl(self, *k, **kw):
self.start_msg('Checking for OpenSSL version')
(root, file) = self.__openssl_find_root_and_version_file(*k, **kw)
try:
txt = file.read()
re_version = re.compile('^#\\s*define\\s+OPENSSL_VERSION_NUMBER\\s+(.*)L', re.M)
version_number = re_version.search(txt)
re_version_text = re.compile('^#\\s*define\\s+OPENSSL_VERSION_TEXT\\s+(.*)', re.M)
version_text = re_version_text.search(txt)
if version_number and version_text:
version = version_number.group(1)
self.end_msg(version_text.group(1))
else:
self.fatal('OpenSSL version file is present, but is not recognizable')
except:
self.fatal('OpenSSL version file is not found or is not usable')
path = k and k[0] or kw.get('path', self.options.openssl_dir)
root, version_file = self.__openssl_find_root_and_version_file(path)
atleast_version = kw.get('atleast_version', 0)
ok, version_str = self.__openssl_check_version(version_file, atleast_version)
self.end_msg(version_str)
if not ok:
self.fatal(f'The version of OpenSSL is too old; {atleast_version} or later is required.\n'
'Please upgrade your distribution or manually install a newer version of OpenSSL.')
if int(version, 16) < atleast_version:
self.fatal('The version of OpenSSL is too old\n'
'Please upgrade your distribution or manually install a newer version of OpenSSL')
if 'msg' not in kw:
kw['msg'] = 'Checking if OpenSSL library works'
@@ -101,8 +94,9 @@ def check_openssl(self, *k, **kw):
if 'uselib_store' not in kw:
kw['uselib_store'] = 'OPENSSL'
if 'define_name' not in kw:
kw['define_name'] = f"HAVE_{kw['uselib_store']}"
kw['includes'] = f'{root}/include'
kw['libpath'] = f'{root}/lib'
kw['define_name'] = 'HAVE_%s' % kw['uselib_store']
if root:
kw['includes'] = '%s/include' % root
kw['libpath'] = '%s/lib' % root
self.check_cxx(**kw)
+4 -4
View File
@@ -1,8 +1,8 @@
# ndn-cxx Authors
The following lists maintainers, primary developers, and all much-appreciated contributors to ndn-cxx in alphabetical order.
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/main/CONTRIBUTING.md>.
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.
* Sepehr Abdous <https://sepehrabdous.github.io>
* ***(Maintainer)*** Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
@@ -23,7 +23,7 @@ If you would like to become a contributor to the official repository, please fol
* Xiaoke Jiang <http://netarchlab.tsinghua.edu.cn/~shock>
* Marcin Juszkiewicz <https://marcin.juszkiewicz.com.pl>
* Luca Keidel <https://lucakeidel.de>
* Spencer Lee <https://www.linkedin.com/in/spenlee>
* 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>
@@ -39,7 +39,7 @@ If you would like to become a contributor to the official repository, please fol
* Arthi Padmanabhan <https://github.com/arthipadmanabhan>
* Ju Pan <https://cs-jupan.com>
* João Pereira <http://website.jpereira.co.uk>
* ***(Maintainer)*** Davide Pesavento <https://github.com/Pesa>
* 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>
+19 -11
View File
@@ -6,30 +6,38 @@ ndn-cxx relies on third-party software, licensed under the following licenses:
- The Boost libraries are licensed under the
[Boost Software License 1.0](https://www.boost.org/users/license.html)
- OpenSSL is licensed under the
[Apache License 2.0](https://www.openssl.org/source/license.html)
- any-lite by Martin Moene is licensed under the
[Boost Software License 1.0](https://github.com/martinmoene/any-lite/blob/master/LICENSE.txt)
- 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)
- span-lite by Martin Moene is licensed under the
[Boost Software License 1.0](https://github.com/martinmoene/span-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)
- SQLite is in the [public domain](https://www.sqlite.org/copyright.html)
- The waf build system is licensed under the terms of the
[BSD license](https://github.com/named-data/ndn-cxx/blob/master/waf)
The ndn-cxx library also relies on other third-party software with a GPL-incompatible
free software license. The following libraries fall into the category of "System
Libraries" under the GPL license definitions and are used in accordance with the GPL
license exception for "System Libraries":
- *(macOS platform only)* The macOS Security Framework is licensed under the
[Apple Public Source License 2.0](https://opensource.apple.com/apsl)
The ndn-cxx library also relies on several other third-party libraries with non-GPL
compatible license. These library fall into category of "System Libraries" under GPL
license definitions and are used in accordance with GPL license exception for "System
Libraries":
- OpenSSL is licensed under an
[Apache-style license](https://www.openssl.org/source/license.html)
- (macOS platform only) The macOS Security Framework is licensed under the
[Apple Public Source License](https://opensource.apple.com/apsl)
The LGPL and GPL licenses are provided below in this file. For more information
about these licenses, see <https://www.gnu.org/licenses/>
about these licenses, see https://www.gnu.org/licenses/
--------------------------------------------------------------------------------
-26
View File
@@ -1,26 +0,0 @@
FROM gcc:12-bookworm
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
dpkg-dev \
libboost-atomic-dev \
libboost-chrono-dev \
libboost-date-time-dev \
libboost-filesystem-dev \
libboost-iostreams-dev \
libboost-log-dev \
libboost-program-options-dev \
libboost-regex-dev \
libboost-stacktrace-dev \
libboost-system-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
COPY . /ndn-cxx
RUN cd /ndn-cxx \
&& ./waf configure --without-pch --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-static --enable-shared \
&& ./waf \
&& ./waf install \
&& cd \
&& rm -rf /ndn-cxx
+13 -8
View File
@@ -1,20 +1,20 @@
Notes for ndn-cxx developers
============================
If you are new to the NDN software community, please read our
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md).
If you are new to the NDN community of software generally, read the
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md).
Code style
----------
ndn-cxx code is subject to [ndn-cxx code style](https://docs.named-data.net/ndn-cxx/current/code-style.html).
ndn-cxx code is subject to [ndn-cxx code style](https://named-data.net/doc/ndn-cxx/current/code-style.html).
Licensing
---------
Contributions to ndn-cxx must be licensed under the LGPL v3 or a compatible license.
If you choose the LGPL v3, please use the following license boilerplate in all `.hpp`
and `.cpp` files:
Contributions to the library must be licensed under the LGPL v3 or compatible license. If
you are choosing LGPL v3, please use the following license boilerplate in all `.hpp` and
`.cpp` files:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
@@ -35,6 +35,11 @@ and `.cpp` files:
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
////// [optional part] //////
*
* @author Author's Name <email@domain-or-homepage://url>
* @author Other Author's Name <another.email@domain-or-homepage://url>
////// [end of optional part] //////
*/
If you are affiliated to an NSF-supported NDN project institution, please use the [NDN Team License
@@ -57,7 +62,7 @@ The simplest way to run the tests is to launch the compiled binary without any p
./build/unit-tests
The [Boost.Test framework](https://www.boost.org/doc/libs/1_71_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:
@@ -90,7 +95,7 @@ or `-p` to show a progress bar:
There are many more command line options available, information about which can be obtained
either from the command line using the `--help` switch, or online on the
[Boost.Test website](https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/runtime_config.html).
[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
+21 -30
View File
@@ -1,51 +1,42 @@
<div align="center">
[<img alt height="65" src="docs/named_data_theme/static/ndn-logo.svg"/>](https://named-data.net/)
# ndn-cxx: NDN C++ library with eXperimental eXtensions
</div>
![Language](https://img.shields.io/badge/C%2B%2B-14-blue.svg)
[![Build Status](https://travis-ci.org/named-data/ndn-cxx.svg?branch=master)](https://travis-ci.org/named-data/ndn-cxx)
![Latest Version](https://img.shields.io/github/tag/named-data/ndn-cxx.svg?color=darkkhaki&label=latest%20version)
[![CI](https://github.com/named-data/ndn-cxx/actions/workflows/ci.yml/badge.svg)](https://github.com/named-data/ndn-cxx/actions/workflows/ci.yml)
[![Docs](https://github.com/named-data/ndn-cxx/actions/workflows/docs.yml/badge.svg)](https://github.com/named-data/ndn-cxx/actions/workflows/docs.yml)
![Language](https://img.shields.io/badge/C%2B%2B-17-blue)
![Latest version](https://img.shields.io/github/v/tag/named-data/ndn-cxx?label=Latest%20version)
**ndn-cxx** is a C++17 library implementing Named Data Networking (NDN) primitives
**ndn-cxx** is a C++14 library implementing Named Data Networking (NDN) primitives
that can be used to write various NDN applications. The library is currently being
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)
* [**ndn-svs** - State Vector Sync library](https://github.com/named-data/ndn-svs)
* [**PSync** - Partial and full Sync library](https://github.com/named-data/PSync)
* [**ChronoSync** - Sync library for distributed real-time applications *(deprecated)*](https://github.com/named-data/ChronoSync)
* [**NAC** - Name-based Access Control library](https://github.com/named-data/name-based-access-control)
* [**NDNCERT** - NDN certificate management protocol](https://github.com/named-data/ndncert)
* [**repo-ng** - NDN repository implementation in C++ *(deprecated)*](https://github.com/named-data/repo-ng)
* [**ndn-traffic-generator** - Simple NDN traffic generator](https://github.com/named-data/ndn-traffic-generator)
* [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 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)
* [NDNS - Domain Name Service for NDN](https://github.com/named-data/ndns)
## Documentation
See [`docs/INSTALL.rst`](docs/INSTALL.rst) for compilation and installation instructions.
Extensive documentation is available on the library's [homepage](https://docs.named-data.net/ndn-cxx/).
Extensive documentation is available on the library's [homepage](https://named-data.net/doc/ndn-cxx/).
## Reporting bugs
Please submit any bug reports or feature requests to the
Please submit any bugs or feature requests to the
[ndn-cxx issue tracker](https://redmine.named-data.net/projects/ndn-cxx/issues).
## Contributing
Contributions to ndn-cxx are greatly appreciated and can be made through our
[Gerrit code review site](https://gerrit.named-data.net/).
If you are new to the NDN software community, please read our
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md)
and [`README-dev.md`](README-dev.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
ndn-cxx is free software distributed under the GNU Lesser General Public License version 3.
See [`COPYING.md`](COPYING.md) for details.
ndn-cxx is an open source project licensed under the LGPL version 3.
See [`COPYING.md`](COPYING.md) for more information.
+1
View File
@@ -0,0 +1 @@
docs/release-notes-latest.rst
+45 -55
View File
@@ -7,22 +7,21 @@ Supported platforms
ndn-cxx is built against a continuous integration system and has been tested on the
following platforms:
- Ubuntu 20.04 (focal)
- Ubuntu 22.04 (jammy)
- Debian 11 (bullseye)
- Debian 12 (bookworm)
- CentOS Stream 9
- macOS 11 / 12 / 13 / 14
- Ubuntu 18.04 (amd64, armhf, i386)
- Ubuntu 20.04 (amd64)
- macOS 10.13
- macOS 10.14
- macOS 10.15
- CentOS 8
ndn-cxx should also work on the following platforms, although they are not officially
ndn-cxx is known to work on the following platforms, although they are not officially
supported:
- Any other recent version of Ubuntu not listed above
- Fedora >= 33
- Alpine >= 3.12
- Any version of Raspberry Pi OS based on Debian 11 (bullseye) or later
- macOS 10.15
- FreeBSD >= 12.2
- Debian 10 (Buster)
- Fedora >= 29
- Gentoo Linux
- Raspbian >= 2019-06-20 (Buster)
- FreeBSD >= 11.3
Prerequisites
-------------
@@ -30,22 +29,22 @@ Prerequisites
Required
~~~~~~~~
- GCC >= 9.3 or clang >= 7.0 (if you are on Linux or FreeBSD)
- Xcode >= 12.4 or corresponding version of Command Line Tools (if you are on macOS)
- Python >= 3.8
- pkg-config
- Boost >= 1.71.0
- OpenSSL >= 1.1.1
- 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
- SQLite 3.x
To build ndn-cxx from source, one must first install a C++ compiler and all necessary
development tools and libraries:
- On **Debian** and **Ubuntu**
- On **Ubuntu**
In a terminal, enter::
sudo apt install build-essential pkg-config python3-minimal libboost-all-dev libssl-dev libsqlite3-dev
sudo apt install g++ pkg-config python3-minimal libboost-all-dev libssl-dev libsqlite3-dev
- On **CentOS** and **Fedora**
@@ -58,9 +57,7 @@ development tools and libraries:
* 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:
.. code-block:: sh
* If using Homebrew (recommended), enter the following in a terminal::
brew install boost openssl pkg-config
@@ -78,35 +75,28 @@ development tools and libraries:
Optional
~~~~~~~~
To build tutorials, man pages, and API documentation the following additional dependencies
To build tutorials, manpages, and API documentation the following additional dependencies
need to be installed:
- doxygen
- graphviz
- sphinx >= 4.0
- sphinxcontrib-doxylink
- doxygen
- graphviz
- sphinx >= 1.3
- sphinxcontrib-doxylink
The following lists the steps to install these prerequisites on various common platforms.
.. note::
On Linux, you may need to add ``$HOME/.local/bin`` to the ``PATH`` environment variable
for your user, for example:
.. code-block:: sh
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
- On **Debian** and **Ubuntu**:
- On **Ubuntu**:
.. code-block:: sh
sudo apt install doxygen graphviz python3-pip
pip3 install --user sphinx sphinxcontrib-doxylink
sudo pip3 install sphinx sphinxcontrib-doxylink
- On **CentOS** and **Fedora**:
.. code-block:: sh
sudo dnf config-manager --enable PowerTools # on CentOS only
sudo dnf install doxygen graphviz python3-pip
pip3 install --user sphinx sphinxcontrib-doxylink
@@ -115,13 +105,13 @@ The following lists the steps to install these prerequisites on various common p
.. code-block:: sh
brew install doxygen graphviz
sudo pip3 install sphinx sphinxcontrib-doxylink
sudo pip install sphinx sphinxcontrib-doxylink
- On **FreeBSD**:
.. code-block:: sh
sudo pkg install doxygen graphviz py39-sphinx
sudo pkg install doxygen graphviz py37-sphinx
Build
-----
@@ -134,7 +124,7 @@ To build in a terminal, change directory to the ndn-cxx root, then enter:
.. code-block:: sh
./waf configure
./waf configure # on CentOS, add --without-pch
./waf
sudo ./waf install
@@ -161,12 +151,12 @@ been installed:
sudo ldconfig
.. note::
When the library is installed in a non-default location (in general: not in ``/usr/lib``
or ``/usr/local/lib``; on some Linux distros like Fedora and its derivatives, including
CentOS: not in ``/usr/lib``), the following additional actions may be necessary.
When the library is installed in a non-standard path (in general: not in ``/usr/lib``
or ``/usr/local/lib``; on some Linux distros including Fedora: not in ``/usr/lib``),
additional actions may be necessary.
The library installation path should be added to ``/etc/ld.so.conf`` or in
``/etc/ld.so.conf.d/*.conf`` **before** running ``ldconfig``. For example:
The installation path should be added to ``/etc/ld.so.conf`` (or in
``/etc/ld.so.conf.d``) **before** running ``sudo ldconfig``. For example:
.. code-block:: sh
@@ -190,7 +180,7 @@ The ``./waf install`` command installs the following files:
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``: command-line tool to manage NDN keys and certificates.
- ``<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
@@ -212,7 +202,7 @@ them, pass ``--with-examples`` during the configuration step:
.. code-block:: sh
./waf configure --with-examples
./waf configure --with-examples # on CentOS, add --without-pch
./waf
sudo ./waf install
sudo ldconfig # on Linux only
@@ -285,9 +275,9 @@ Tutorials and API documentation can be built using the following commands:
# Only API docs in build/docs/doxygen
./waf doxygen
If ``sphinx-build`` is detected during ``./waf configure``, man pages will automatically
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, man pages will be installed into ``${PREFIX}/share/man``
``./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.
@@ -303,7 +293,7 @@ The following is the suggested build procedure for development builds:
.. code-block:: sh
./waf configure --debug --with-tests
./waf configure --debug --with-tests # on CentOS, add --without-pch
./waf
sudo ./waf install
sudo ldconfig # on Linux only
@@ -314,5 +304,5 @@ will be treated as errors. This default behavior can be overridden by setting th
.. code-block:: sh
CXXFLAGS="-O1 -g3 -Wall" ./waf configure --debug --with-tests
./waf
CXXFLAGS="-O1 -g3" ./waf configure --debug --with-tests
...
+4
View File
@@ -0,0 +1,4 @@
Release Notes
+++++++++++++
.. include:: release-notes-latest.rst
+95 -100
View File
@@ -3,11 +3,11 @@ ndn-cxx Code Style and Coding Guidelines
Based on
* "C++ Programming Style Guidelines" by Geotechnical Software Services, Copyright © 1996-2011.
The original document is available at `<http://geosoft.no/development/cppstyle.html>`__
* "C++ Programming Style Guidelines" by Geotechnical Software Services, Copyright © 1996 – 2011.
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 is available at `<https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`__
* NDN Platform "C++, C, C#, Java and JavaScript Code Guidelines".
The original document available at `<https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`_
1. Code layout
--------------
@@ -31,14 +31,14 @@ extended it to C++.
.. code-block:: c++
a = (b + c) * d; // NOT: a=(b+c)*d
a = (b + c) * d; // NOT: a=(b+c)*d
while (true) { // NOT: while(true)
while (true) { // NOT: while(true)
...
doSomething(a, b, c, d); // NOT: doSomething(a,b,c,d);
doSomething(a, b, c, d); // NOT: doSomething(a,b,c,d);
for (i = 0; i < 10; i++) { // NOT: for(i=0;i<10;i++){
for (i = 0; i < 10; i++) { // NOT: for(i=0;i<10;i++){
...
1.3. Namespaces should have the following form:
@@ -52,11 +52,11 @@ extended it to C++.
} // namespace example
Note that code inside the namespace is **not** indented. Avoid the following:
Note that code inside namespace is **not** indented. Avoid the following:
.. code-block:: c++
// WRONG
// NOT
//
// namespace example {
//
@@ -180,7 +180,7 @@ extended it to C++.
switch (condition) {
case ABC: // 2 space indent
statements; // 4 space indent
[[fallthrough]];
NDN_CXX_FALLTHROUGH;
case DEF:
statements;
@@ -211,7 +211,7 @@ extended it to C++.
// Correct style
case A1: {
statements;
[[fallthrough]];
NDN_CXX_FALLTHROUGH;
}
// Incorrect style: braces should cover the entire case block
@@ -232,7 +232,7 @@ extended it to C++.
switch (condition) {
case ABC: // no indent
statements; // 2 space indent
[[fallthrough]];
NDN_CXX_FALLTHROUGH;
case DEF:
statements;
@@ -243,11 +243,11 @@ extended it to C++.
break;
}
The ``[[fallthrough]]`` annotation must be included whenever there is a
case without a break statement. Leaving the break out is a common error,
The ``NDN_CXX_FALLTHROUGH;`` annotation must be included whenever there is
a case without a break statement. Leaving the break out is a common error,
and it must be made clear that it is intentional when it is not there.
Moreover, modern compilers will warn when a case that falls through is
not explicitly annotated.
Moreover, modern compilers will warn when a case that falls through is not
explicitly annotated.
1.11. A ``try-catch`` statement should have the following form:
@@ -329,14 +329,6 @@ should take the following form:
statements;
}
[&] (T arg) {
statements;
}
[=] (T arg) {
statements;
}
If the lambda has no parameters, ``()`` should be omitted.
.. code-block:: c++
@@ -345,8 +337,21 @@ should take the following form:
statements;
}
Trailing return types should be omitted whenever possible. Add it only when the compiler
cannot deduce the return type automatically, or when it improves readability. Note that
Either capture-default (``[&]`` or ``[=]``) is permitted, but its usage should be minimized.
Only use a capture-default when it significantly simplifies code and improves readability.
.. code-block:: c++
[&] (T arg) {
statements;
}
[=] (T arg) {
statements;
}
Trailing return type should be omitted whenever possible. Add it only when the compiler
cannot deduce the return type automatically, or when it improves readability.
``()`` is required by the C++ standard when ``mutable`` or a trailing return type is used.
.. code-block:: c++
@@ -366,7 +371,7 @@ should take the following form:
[&capture1, capture2] (T1 arg1, T2 arg2) { statement; }
A no-op lambda can be written in a more compact form:
No-op can be written in a more compact form:
.. code-block:: c++
@@ -390,20 +395,26 @@ should take the following form:
T({arg1, arg2})
T object = {arg1, arg2};
class Class
{
private:
T m_member{arg1, arg2};
T m_member = {arg1, arg2};
static T s_member = {arg1, arg2};
};
Class::Class()
: m_member{arg1, arg2}
{
}
T object = {arg1, arg2};
An empty braced-init-list is written as ``{}``. For example:
.. code-block:: c++
T object{};
T object = {};
2. Naming Conventions
@@ -479,11 +490,13 @@ written in mixed case starting with lower case.
.. code-block:: c++
namespace model::analyzer {
namespace model {
namespace analyzer {
...
} // namespace model::analyzer
} // namespace analyzer
} // namespace model
2.7. Names representing generic template types should be a single uppercase letter.
@@ -517,8 +530,8 @@ written in mixed case starting with lower case.
In general, the use of global variables should be avoided. Consider using singleton
objects instead.
2.10. All non-static data members of a class should be prefixed with ``m_`` unless they
are public. Similarly, non-public static data members should be prefixed with ``s_``.
2.10. Private class variables should have ``m_`` prefix. Static class variables should have
``s_`` prefix.
.. code-block:: c++
@@ -616,13 +629,13 @@ symmetry.
::
get/set, add/remove, create/destroy, start/stop, insert/erase,
get/set, add/remove, create/destroy, start/stop, insert/delete,
increment/decrement, old/new, begin/end, first/last, up/down, min/max,
next/previous (and commonly used next/prev), open/close, show/hide,
suspend/resume, etc.
The pair ``insert/erase`` is preferred. ``insert/delete`` can also be used if it
does not conflict with the ``delete`` keyword of C++.
Pair ``insert/erase`` should be preferred. ``insert/delete`` can also be used if it
does not conflict with C++ delete keyword.
2.21. Variable names should not include reference to variable type (do not use Hungarian
notation).
@@ -745,29 +758,20 @@ For example, the include section of ``ndn-cxx/foo/bar.cpp`` may look like this:
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
3.5. Definitions that are local to only one ``.cpp`` file should be declared inside that
file and be placed in an unnamed namespace or declared ``static``.
3.5. Types that are local to one file only can be declared inside that file.
3.6. Implicit conversion is generally allowed.
Implicit conversion between integer and floating point numbers can cause problems and
should be avoided.
Implicit conversion in constructors that can be called with a single argument is usually
undesirable. Therefore, all single-argument constructors should be marked ``explicit``,
unless implicit conversion is desirable. In that case, a comment should document the
reason for this.
As an exception, copy and move constructors should not be explicit, since they do not
perform type conversion.
Constructors that cannot be called with a single argument may omit ``explicit``.
Constructors that take a single ``std::initializer_list`` parameter should also omit
``explicit``, in order to support copy-initialization.
Implicit conversion in single-argument constructor is usually undesirable. Therefore, all
single-argument constructors should be marked 'explicit', unless implicit conversion is
desirable. In that case, a comment should document the reason.
Avoid C-style casts.
Use ``static_cast``, ``dynamic_cast``, ``const_cast``, ``reinterpret_cast``, or
``bit_cast`` instead where appropriate.
Use ``static_pointer_cast``, ``dynamic_pointer_cast``, or ``const_pointer_cast``
when dealing with ``shared_ptr``.
Avoid C-style casts. Use ``static_cast``, ``dynamic_cast``, ``reinterpret_cast``,
``const_cast`` instead where appropriate. Use ``static_pointer_cast``,
``dynamic_pointer_cast``, ``const_pointer_cast`` when dealing with ``shared_ptr``.
3.7. Variables should be initialized where they are declared.
@@ -789,9 +793,9 @@ file and be placed in an unnamed namespace or declared ``static``.
Exceptions to this rule:
* When the class is essentially a passive data structure with no or minimal behavior
(equivalent to a C struct, also known as POD type). In this case, all fields should
be public and the keyword ``struct`` should be used instead of ``class``.
* When the class is essentially a dumb data structure with no or minimal behavior
(equivalent to a C struct, also known as POD type). In this case it is appropriate
to make the instance variables public by using ``struct``.
* When the class is used only inside the compilation unit, e.g., when implementing pImpl
idiom (aka Bridge pattern) or similar cases.
@@ -808,11 +812,8 @@ than to the name.
.. code-block:: c++
if (nLines != 0) // NOT: if (nLines)
int* ptr = ...
if (ptr) // OK
if (ptr != nullptr) // also OK
if (nLines != 0) // NOT: if (nLines)
if (value != 0.0) // NOT: if (value)
3.11. *(removed)*
@@ -836,10 +837,10 @@ than to the name.
// NOT:
for (;;) { // NO!
...
:
}
while (1) { // NO!
...
:
}
3.14. Complex conditional expressions must be avoided. Introduce temporary boolean variables
@@ -1003,10 +1004,10 @@ decimal, and without omitting 0 before the decimal point.
int z = x + y;
BOOST_ASSERT(z - y == x);
The expression passed to ``BOOST_ASSERT`` must not have side effects,
because it may not be evaluated in release builds.
The expression passed to ``BOOST_ASSERT`` MUST NOT have side effects,
because it MAY NOT be evaluated in release builds.
3.28. Use ``static_assert`` for compile-time assertions.
3.28. Use ``static_assert`` for static assertions.
.. code-block:: c++
@@ -1021,32 +1022,43 @@ decimal, and without omitting 0 before the decimal point.
static_assert(std::is_base_of<BaseClass, DerivedClass>::value,
"DerivedClass must inherit from BaseClass");
3.29. The ``auto`` type specifier may be used for local variables if a human reader can
easily deduce the actual type, or if it makes the code safer.
3.29. ``auto`` type specifier MAY be used for local variables, if a human reader
can easily deduce the actual type.
.. code-block:: c++
std::vector<int> intVector;
auto i = intVector.find(4); // OK
auto i = intVector.find(4);
auto stringSet = std::make_shared<std::set<std::string>>(); // OK
auto stringSet = std::make_shared<std::set<std::string>>();
std::vector<std::string> strings;
for (const auto& str : strings) { // OK, iterating over the elements of a container
std::cout << str;
``auto`` SHOULD NOT be used if a human reader cannot easily deduce the actual type.
.. code-block:: c++
auto x = foo(); // BAD if the declaration of foo() isn't nearby
``const auto&`` SHOULD be used to represent constant reference types.
``auto&&`` SHOULD be used to represent mutable reference types.
.. code-block:: c++
std::list<std::string> strings;
for (const auto& str : strings) {
statements; // cannot modify `str`
}
for (auto&& str : strings) {
statements; // can modify `str`
}
obj.onEvent([] (auto&&...) { std::cout << "hi!"; }); // OK, unused lambda parameters
auto x = foo(); // BAD unless foo() is declared nearby or has a well-known prototype
3.30. Use the ``override`` or ``final`` specifier when overriding a virtual
member function or a virtual destructor.
``virtual`` must not be used along with ``final`` so that the compiler can generate
an error when a final function does not override.
``virtual`` MUST NOT be used along with ``final``, so that the compiler
can generate an error when a final function does not override.
``virtual`` should not be used along with ``override`` for consistency with ``final``.
``virtual`` SHOULD NOT be used along with ``override``, for consistency
with ``final``.
.. code-block:: c++
@@ -1073,22 +1085,5 @@ member function or a virtual destructor.
3.31. The recommended way to throw an exception derived from ``std::exception`` is to use
``NDN_THROW`` or one of the other ``NDN_THROW_*`` macros.
Exceptions thrown using these macros will be augmented with additional diagnostic
information, including the file name, line number, and function name from which
the exception was thrown.
The extended diagnostic information contained in the exception can be printed with
``boost::diagnostic_information()``.
.. code-block:: c++
#include <boost/exception/diagnostic_information.hpp>
#include <iostream>
try {
operationThatMayThrow();
}
catch (const std::exception& e) {
std::cerr << boost::diagnostic_information(e);
}
Exceptions thrown using these macros will be augmented with additional diagnostic information,
including the file name, line number, and function name from which the exception was thrown.
+89 -35
View File
@@ -1,17 +1,25 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import importlib.util
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'ndn-cxx: NDN C++ library with eXperimental eXtensions'
copyright = 'Copyright © 2013-2023 Regents of the University of California.'
author = 'Named Data Networking Project'
project = u'ndn-cxx: NDN C++ library with eXperimental eXtensions'
copyright = u'Copyright © 2013-2020 Regents of the University of California.'
author = u'Named Data Networking Project'
# The short X.Y version.
#version = ''
@@ -27,34 +35,49 @@ today_fmt = '%Y-%m-%d'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
needs_sphinx = '4.0'
# If your documentation needs a minimal Sphinx version, state it here.
#
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
# ones.
extensions = [
'sphinx.ext.extlinks',
'sphinx.ext.todo',
]
def addExtensionIfExists(extension: str):
def addExtensionIfExists(extension):
try:
if importlib.util.find_spec(extension) is None:
raise ModuleNotFoundError(extension)
except (ImportError, ValueError):
sys.stderr.write(f'WARNING: Extension {extension!r} not found. '
'Some documentation may not build correctly.\n')
else:
__import__(extension)
extensions.append(extension)
except ImportError:
sys.stderr.write("Extension '%s' not found. "
"Some documentation may not build correctly.\n" % extension)
addExtensionIfExists('sphinxcontrib.doxylink')
# The master toctree document.
master_doc = 'index'
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
exclude_patterns = ['Thumbs.db', '.DS_Store']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'named_data_theme'
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ['.']
# Add any paths that contain custom static files (such as style sheets) here,
@@ -69,36 +92,67 @@ html_show_sourcelink = False
highlight_language = 'none'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'ndn-cxx-docs.tex', u'NDN C++ library with eXperimental eXtensions',
author, 'manual'),
]
# -- Options for manual page output ------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-manual-page-output
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('manpages/ndnsec', 'ndnsec', 'NDN security toolkit', [], 1),
('manpages/ndnsec-cert-dump', 'ndnsec-cert-dump', 'export an NDN certificate', [], 1),
('manpages/ndnsec-cert-gen', 'ndnsec-cert-gen', 'create an NDN certificate for an identity', [], 1),
('manpages/ndnsec-cert-install', 'ndnsec-cert-install', 'import an NDN certificate from a file', [], 1),
('manpages/ndnsec-delete', 'ndnsec-delete', 'delete an NDN identity, key, or certificate', [], 1),
('manpages/ndnsec-export', 'ndnsec-export', 'export an NDN certificate and its private key to a file', [], 1),
('manpages/ndnsec-get-default', 'ndnsec-get-default', 'show the default NDN identity, key, and certificate for the current user', [], 1),
('manpages/ndnsec-import', 'ndnsec-import', 'import an NDN certificate and its private key from a file', [], 1),
('manpages/ndnsec-key-gen', 'ndnsec-key-gen', 'generate an NDN key for an identity', [], 1),
('manpages/ndnsec-list', 'ndnsec-list', 'list all known NDN identities, keys, and certificates', [], 1),
('manpages/ndnsec-set-default', 'ndnsec-set-default', 'change the default NDN identity, key, or certificate for the current user', [], 1),
('manpages/ndnsec-sign-req', 'ndnsec-sign-req', 'generate an NDN certificate signing request', [], 1),
('manpages/ndnsec-unlock-tpm', 'ndnsec-unlock-tpm', 'unlock the TPM', [], 1),
('manpages/ndn-client.conf', 'ndn-client.conf', 'configuration file for NDN applications', [], 5),
('manpages/ndn-log', 'ndn-log', 'ndn-cxx logging', [], 7),
('manpages/ndnsec', 'ndnsec', 'NDN security toolkit', None, 1),
('manpages/ndnsec-cert-dump', 'ndnsec-cert-dump', 'export an NDN certificate', None, 1),
('manpages/ndnsec-cert-gen', 'ndnsec-cert-gen', 'create an NDN certificate for an identity', None, 1),
('manpages/ndnsec-cert-install', 'ndnsec-cert-install', 'import an NDN certificate from a file', None, 1),
('manpages/ndnsec-delete', 'ndnsec-delete', 'delete an NDN identity, key, or certificate', None, 1),
('manpages/ndnsec-export', 'ndnsec-export', 'export an NDN certificate and its private key to a file', None, 1),
('manpages/ndnsec-get-default', 'ndnsec-get-default', 'show the default NDN identity, key, and certificate for the current user', None, 1),
('manpages/ndnsec-import', 'ndnsec-import', 'import an NDN certificate and its private key from a file', None, 1),
('manpages/ndnsec-key-gen', 'ndnsec-key-gen', 'generate an NDN key for an identity', None, 1),
('manpages/ndnsec-list', 'ndnsec-list', 'list all known NDN identities, keys, and certificates', None, 1),
('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 applications', None, 5),
('manpages/ndn-log', 'ndn-log', 'ndn-cxx logging', None, 7),
]
# If true, show URL addresses after external links.
#man_show_urls = True
# -- Misc options ------------------------------------------------------------
# -- Custom options ----------------------------------------------------------
doxylink = {
'ndn-cxx': ('ndn-cxx.tag', 'doxygen/'),
}
extlinks = {
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #%s'),
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #'),
}
+57 -6
View File
@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = docs/doxygen
# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = NO
CREATE_SUBDIRS = YES
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
@@ -230,6 +230,12 @@ TAB_SIZE = 4
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
@@ -437,7 +443,7 @@ EXTRACT_PACKAGE = NO
# included in the documentation.
# The default value is: NO.
EXTRACT_STATIC = NO
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO,
@@ -774,7 +780,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = ndn-cxx build/ndn-cxx/version.hpp
INPUT = ndn-cxx
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -830,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/* */ndn-cxx/detail/nonstd/*
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
@@ -1041,6 +1047,13 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
@@ -1178,7 +1191,7 @@ HTML_COLORSTYLE_GAMMA = 91
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = NO
HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
@@ -1739,6 +1752,16 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
@@ -1811,6 +1834,16 @@ RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@@ -1900,6 +1933,15 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
# program listings (including syntax highlighting and cross-referencing
# information) to the DOCBOOK output. Note that enabling this will significantly
# increase the size of the DOCBOOK output.
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@@ -2090,6 +2132,15 @@ EXTERNAL_PAGES = YES
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can 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.
@@ -2110,7 +2161,7 @@ HIDE_UNDOC_RELATIONS = YES
# set to NO
# The default value is: YES.
HAVE_DOT = @HAVE_DOT@
HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
+10 -10
View File
@@ -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 <https://docs.named-data.net/NFD/>`__.
homepage <https://named-data.net/doc/NFD/>`_.
Trivial consumer
----------------
@@ -18,7 +18,7 @@ callbacks to be called when Data/Nack is retrieved or Interest times out.
.. literalinclude:: ../examples/consumer.cpp
:language: c++
:linenos:
:emphasize-lines: 43-48,51-54,62,76,82
:emphasize-lines: 39-45,48,59,65,71
Trivial producer
----------------
@@ -41,7 +41,7 @@ using :ndn-cxx:`Face::put` method.
.. literalinclude:: ../examples/producer.cpp
:language: c++
:linenos:
:emphasize-lines: 39-42,55,60-63,78,86,90
:emphasize-lines: 41,50,57-59,62,70,74
Consumer that uses Scheduler
----------------------------
@@ -49,13 +49,13 @@ Consumer that uses Scheduler
The following example demonstrates how to use :ndn-cxx:`Scheduler` to schedule arbitrary
events for execution at specific points of time.
The library internally uses `boost::asio::io_context
<https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/reference/io_context.html>`__
to implement fully asynchronous NDN operations (i.e., sending and receiving Interests and
Data). In addition to network-related operations, ``boost::asio::io_context`` can be used
The library internally uses `boost::asio::io_service
<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_context::run()`` or implicitly via :ndn-cxx:`Face::processEvents` as in previous
examples). :ndn-cxx:`Scheduler` is just a wrapper on top of ``io_context``, providing a
``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
@@ -64,4 +64,4 @@ Interest approximately 3 seconds after the first one.
.. literalinclude:: ../examples/consumer-with-timer.cpp
:language: c++
:linenos:
:emphasize-lines: 47-50,53,84,96-99,104-106
:emphasize-lines: 39-40,56,62,93,106,114-116
+34 -38
View File
@@ -1,6 +1,26 @@
ndn-cxx: NDN C++ library with eXperimental eXtensions
=====================================================
**ndn-cxx** is a C++14 library implementing Named Data Networking (NDN) primitives
that can be used to write various NDN applications. The library is currently being
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>`_
* `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>`_
* `NDNS - Domain Name Service for NDN <https://github.com/named-data/ndns>`_
Please submit any bugs or feature requests to the `ndn-cxx issue tracker
<https://redmine.named-data.net/projects/ndn-cxx/issues>`_.
ndn-cxx Documentation
---------------------
.. toctree::
:hidden:
:maxdepth: 3
@@ -16,60 +36,36 @@ ndn-cxx: NDN C++ library with eXperimental eXtensions
:maxdepth: 1
code-style
release-notes
RELEASE_NOTES
releases
**ndn-cxx** is a C++17 library implementing Named Data Networking (NDN) primitives
that can be used to write various NDN applications. The library is currently being
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>`_
* `ndn-svs - State Vector Sync library <https://github.com/named-data/ndn-svs>`_
* `PSync - Partial and full Sync library <https://github.com/named-data/PSync>`_
* `ChronoSync - Sync library for distributed real-time applications (deprecated) <https://github.com/named-data/ChronoSync>`_
* `NAC - Name-based Access Control library <https://github.com/named-data/name-based-access-control>`_
* `NDNCERT - NDN certificate management protocol <https://github.com/named-data/ndncert>`_
* `repo-ng - NDN repository implementation in C++ (deprecated) <https://github.com/named-data/repo-ng>`_
* `ndn-traffic-generator - Simple NDN traffic generator <https://github.com/named-data/ndn-traffic-generator>`_
Documentation
-------------
- :doc:`INSTALL`
- :doc:`examples`
- :doc:`tutorials`
+ `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`
- :doc:`manpages`
- :doc:`release-notes`
- :doc:`releases`
For developers
^^^^^^^^^^^^^^
- `NDN Software Contributor's Guide <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>`__
(guide for newcomers to the NDN community of software)
- :doc:`specs`
+ :doc:`specs/safe-bag`
+ :doc:`specs/signed-interest`
+ :doc:`specs/certificate-format`
+ :doc:`specs/safe-bag`
+ :doc:`specs/validation-error-code`
- `API documentation (doxygen) <doxygen/annotated.html>`__
- :doc:`manpages`
Additional Documentation
^^^^^^^^^^^^^^^^^^^^^^^^
- `API documentation (doxygen) <doxygen/annotated.html>`_
- :doc:`code-style`
Issues
------
Please submit any bug reports or feature requests to the
`ndn-cxx issue tracker <https://redmine.named-data.net/projects/ndn-cxx/issues>`__.
- :doc:`RELEASE_NOTES`
- :doc:`releases`
License
-------
ndn-cxx is an open source project licensed under the LGPL version 3. For more information about
the license, refer to `COPYING.md <https://github.com/named-data/ndn-cxx/blob/master/COPYING.md>`__.
the license, refer to `COPYING.md <https://github.com/named-data/ndn-cxx/blob/master/COPYING.md>`_.
+18 -8
View File
@@ -1,10 +1,20 @@
Man pages
=========
Manpages
========
.. toctree::
:glob:
:maxdepth: 1
ndn-client.conf <manpages/ndn-client.conf>
ndn-log: ndn-cxx logging <manpages/ndn-log>
manpages/ndnsec*
ndn-client.conf <manpages/ndn-client.conf>
ndn-cxx logging <manpages/ndn-log>
manpages/ndnsec
ndnsec-list <manpages/ndnsec-list>
ndnsec-get-default <manpages/ndnsec-get-default>
ndnsec-set-default <manpages/ndnsec-set-default>
ndnsec-key-gen <manpages/ndnsec-key-gen>
ndnsec-sign-req <manpages/ndnsec-sign-req>
ndnsec-cert-gen <manpages/ndnsec-cert-gen>
ndnsec-cert-install <manpages/ndnsec-cert-install>
ndnsec-cert-dump <manpages/ndnsec-cert-dump>
ndnsec-delete <manpages/ndnsec-delete>
ndnsec-export <manpages/ndnsec-export>
ndnsec-import <manpages/ndnsec-import>
ndnsec-unlock-tpm <manpages/ndnsec-unlock-tpm>
:maxdepth: 1
+15 -18
View File
@@ -1,9 +1,6 @@
client.conf
===========
Description
-----------
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:
@@ -16,11 +13,11 @@ The configuration file ``client.conf`` is looked up in several directories in th
Here is an example of ``client.conf`` for the current ndn-cxx package:
.. literalinclude:: ../../client.conf.sample
:language: ini
:language: ini
Forwarder
---------
NFD
---
transport
FaceUri for default connection toward local NDN forwarder. Only ``unix``, ``tcp``, ``tcp4``, and
@@ -41,17 +38,17 @@ pib
pib=[scheme]:[location]
Possible values for ``[scheme]`` are:
Possible values for ``[scheme]``:
* ``pib-sqlite3``: local PIB implementation using the SQLite3 storage engine.
* ``pib-sqlite3``: local PIB implementation with SQLite3 storage engine
Possible values for ``[location]``:
* absolute path where the SQLite3 database will be stored
* relative path (relative to ``client.conf``)
* empty: the default path ``$HOME/.ndn`` will be used
* absolute path where SQLite3 database will be stored
* relative path (relative to ``config.conf``)
* empty: default path ``$HOME/.ndn`` will be used
When ``[location]`` is empty, the trailing ``:`` can be omitted. For example::
When ``[location]`` is empty, trailing ``:`` can be omitted. For example::
pib=pib-sqlite3
@@ -73,12 +70,12 @@ tpm
tpm=[scheme]:[location]
Possible values for ``[scheme]`` are:
Possible values for ``[scheme]``:
* ``tpm-osxkeychain`` (default on macOS): secure storage of private keys in the macOS
* ``tpm-osx-keychain`` (default on macOS): secure storage of private keys in the macOS
Keychain with OS-provided access restrictions.
The ``[location]`` parameter is ignored.
``[location]`` parameter is ignored.
May not work for daemon applications, as user interaction may be required to access the
macOS Keychain.
@@ -89,10 +86,10 @@ tpm
* absolute path to directory that will store private/public key files (unencrypted with
``0700`` permission)
* relative path (relative to ``client.conf``)
* empty: the default path ``$HOME/.ndn/ndnsec-tpm-file`` will be used
* relative path (relative to ``config.conf``)
* empty: default path ``$HOME/.ndn/ndnsec-tpm-file`` will be used
When ``[location]`` is empty, the trailing ``:`` can be omitted. For example::
When ``[location]`` is empty, trailing ``:`` can be omitted. For example::
tpm=tpm-file
+4 -7
View File
@@ -1,8 +1,5 @@
ndn-cxx logging
===============
Description
-----------
ndn-log
=======
The ndn-cxx logging facility exposes the internal state of NDN libraries and
applications so the user can investigate internal interactions, such as interest
@@ -11,8 +8,8 @@ sync and recovery Interest processing inside ChronoSync, etc. During runtime, th
user is able to specify the types of messages he or she would like to receive from
a set of logging modules pre-configured by library and application developers.
Environment
-----------
Environment Variable
--------------------
One way to control ndn-cxx logging facility is through the environment variable
``NDN_LOG``. Using this variable, one can set the log levels for the available logging
+18 -17
View File
@@ -11,7 +11,7 @@ Description
-----------
:program:`ndnsec-cert-dump` reads a certificate from the **Public Info Base (PIB)**
or from a file, and prints it on the standard output in Base64 encoding.
or from a file, and prints it on the standard output.
By default, *name* is interpreted as a certificate name.
@@ -44,21 +44,22 @@ Dump a certificate from PIB to standard output::
$ ndnsec-cert-dump /ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
Print the NDN testbed root certificate in human-readable format::
Dump a certificate in human-readable format::
$ curl -A ndnsec -fsLS https://named-data.net/ndnsec/ndn-testbed-root.ndncert.x3.base64 | ndnsec-cert-dump -fp -
Certificate Name:
/ndn/KEY/%EC%F1L%8EQ%23%15%E0/ndn/%FD%00%00%01u%E6%7F2%10
Additional Description:
fullname: NDN Testbed Root X3
Public Key:
Key Type: 256-bit EC
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGx+3Y4FvYo1eScIvgD74lQhQdzN4
zq021dop8t7kGfEpfGdKf2HGpnn4/qoF9iJ1yUZE/7Na8zzO4xT6RpIM0Q==
$ ndnsec-cert-dump -p /ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
Certificate name:
/ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
Validity:
Not Before: 2020-11-20T16:31:37
Not After: 2024-12-31T23:59:59
Signature Information:
Signature Type: SignatureSha256WithEcdsa
Key Locator: Name=/ndn/KEY/%EC%F1L%8EQ%23%15%E0
Self-Signed: yes
NotBefore: 20140401T000000
NotAfter: 20150331T235959
Subject Description:
2.5.4.41: David
2.5.4.10: Some Organization
Public key bits:
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAtLq50tpynJ15zExEh9l6
jvh/HOmwhOppr/hTEPYUn2VTh21+JJIg5pHAAH/DQr8Bq5BGrdDUCIShxSxbaHwu
a1y4XgKP1MYBQP/WzcIhIzB/3PBDdmE0jM3Qg6yuk8BOwett3C07GtwW9dfgacwt
aC29xIHnYKfryH/gBSIDUIb38M7ILIDgQeIiQcHGHoFO8CbDtKY2OvVkFNgxowAR
Xn+gtkIfMdE77Z8p0S21pYfdvPuIpVVLy7lnFdwGzyCi3nmbtd/r9NSTepBczWQz
zBbThT7yfeNyHWLu0PZPdz84UpNPsBad3Bx9tT31noIVnt8yyBEfEU1jyEIVkm8U
VQIB
+6 -7
View File
@@ -74,19 +74,18 @@ Example
YXL9AgIHRm9vIEJhchdHMEUCIQDPT9Hq1kvkE0r9W1aYSBVTnHlTEzgtz+v1DwkC
ug/vLAIgY3xJITCwf55sqey33q5GIQSk1TRCkNNl58ojvPs5sNU=
$ ndnsec-cert-dump -p -f signed.cert
Certificate Name:
$ 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:
Key Type: 256-bit EC
Public key bits:
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOkmwKS8TlEyPFFV3IrpbrP4WgKr6
pEQSf+zF/6faCeyXbmqbU1qsJ9IZ/3rMgnL0FED1u24wx65aUA3/Ka8wXA==
Validity:
Not Before: 2020-05-01T00:00:00
Not After: 2021-01-01T00:00:00
Signature Information:
Signature Type: SignatureSha256WithEcdsa
Key Locator: Name=/ndn/test/KEY/I%3FS%9A%28%BB%9A%95
+6 -3
View File
@@ -14,9 +14,8 @@ Description
will be set as the default certificate for the corresponding identity and
the identity will be set as the user's default identity.
*file* is a path to a file that contains the certificate to install.
If *file* is "-", the certificate will be read from the standard input.
The certificate should be in Base64 encoding.
*file* can be a filesystem path or an HTTP URL of a file containing the certificate
to install. If *file* is "-", the certificate will be read from the standard input.
Options
-------
@@ -42,6 +41,10 @@ Install a certificate and set it as the default certificate::
$ ndnsec-cert-install cert_file.cert
Install a certificate via HTTP and set it as the default certificate::
$ ndnsec-install-cert "http://ndncert.domain.com/cert/get/my-certificate.ndncert"
Install a certificate but do not change any default settings::
$ ndnsec-cert-install -N cert_file.cert
+25 -14
View File
@@ -21,40 +21,51 @@ provides a command-line interface for managing and using the NDN security data.
Commands
--------
The following commands are understood:
:doc:`list <ndnsec-list>`
list_
List all known identities/keys/certificates.
:doc:`get-default <ndnsec-get-default>`
get-default_
Show the default identity/key/certificate.
:doc:`set-default <ndnsec-set-default>`
set-default_
Change the default identity/key/certificate.
:doc:`delete <ndnsec-delete>`
delete_
Delete an identity/key/certificate.
:doc:`key-gen <ndnsec-key-gen>`
key-gen_
Generate a key for an identity.
:doc:`sign-req <ndnsec-sign-req>`
sign-req_
Generate a certificate signing request.
:doc:`cert-gen <ndnsec-cert-gen>`
cert-gen_
Create a certificate for an identity.
:doc:`cert-dump <ndnsec-cert-dump>`
cert-dump_
Export a certificate.
:doc:`cert-install <ndnsec-cert-install>`
cert-install_
Import a certificate from a file.
:doc:`export <ndnsec-export>`
export_
Export an identity as a SafeBag.
:doc:`import <ndnsec-import>`
import_
Import an identity from a SafeBag.
:doc:`unlock-tpm <ndnsec-unlock-tpm>`
unlock-tpm_
Unlock the TPM.
.. _list: ndnsec-list.html
.. _get-default: ndnsec-get-default.html
.. _set-default: ndnsec-set-default.html
.. _delete: ndnsec-delete.html
.. _key-gen: ndnsec-key-gen.html
.. _sign-req: ndnsec-sign-req.html
.. _cert-gen: ndnsec-cert-gen.html
.. _cert-dump: ndnsec-cert-dump.html
.. _cert-install: ndnsec-cert-install.html
.. _export: ndnsec-export.html
.. _import: ndnsec-import.html
.. _unlock-tpm: ndnsec-unlock-tpm.html
+2 -2
View File
@@ -26,13 +26,13 @@ $mathjax
<div class="row">
<div class="three columns">
<div id="logo">
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
<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="https://docs.named-data.net/ndn-cxx/$projectnumber/">$projectname $projectnumber documentation</a></h1>
<h1><a href="http://named-data.net/doc/ndn-cxx/$projectnumber/">$projectname $projectnumber documentation</a></h1>
</div>
</div>
</div><!--header container end-->
+1
View File
@@ -0,0 +1 @@
release-notes/release-notes-0.7.1.rst
-4
View File
@@ -1,4 +0,0 @@
Release Notes
=============
.. include:: release-notes/release-notes-0.8.1.rst
+1 -1
View File
@@ -35,7 +35,7 @@ The current features include:
- **Wire format**
+ Full support of `NDN-TLV packet format v0.1 <https://docs.named-data.net/NDN-packet-spec/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
+10 -10
View File
@@ -37,14 +37,14 @@ New features
+ New :ndn-cxx:`SignatureSha256WithEcdsa` signature type
+ Updates in ``Signature`` data structure to reflect changes in the `NDN-TLV spec v0.1.1
<https://docs.named-data.net/NDN-packet-spec/0.1.1/>`__
+ Updates in :ndn-cxx:`Signature` data structure to reflect changes in `NDN-TLV spec
0.1.1 <https://named-data.net/doc/NDN-packet-spec/0.1.1/>`_
- **Wire encoding**
+ :ndn-cxx:`Data::getFullName` method to get the Data packet name including the implicit digest
+ ``Data::getFullName()`` method to get the Data packet name including the implicit digest
+ :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`)
@@ -66,7 +66,7 @@ New features
+ Introduce ``util::EventEmitter``, :ndn-cxx:`util::NotificationSubscriber`,
:ndn-cxx:`util::NotificationStream`, and :ndn-cxx:`nfd::FaceMonitor` utility classes
+ Introduce :ndn-cxx:`SegmentFetcher` helper class to fetch multi-segmented data
+ Introduce :ndn-cxx:`util::SegmentFetcher` helper class to fetch multi-segmented data
(:issue:`1879`)
- **Build**
@@ -78,7 +78,7 @@ Updates and bug fixes
- **Base**
+ Serialization of socket write operations (:issue:`1769`)
+ Serialization of socket write operations (:issue:`1707`)
+ Enforcing limit on Interest and Data packet size in :ndn-cxx:`Face::expressInterest` and
:ndn-cxx:`Face::put` methods (:issue:`1774`)
@@ -86,7 +86,7 @@ Updates and bug fixes
+ Cleaning up transport state on communication failure, so Face can try to reconnect
in the future
+ Fix bug in ``Face::removePendingInterest()`` (:issue:`1917`)
+ Fix bug in ``Face::removePendingInterest`` (:issue:`1917`)
- **Wire encoding**
@@ -111,8 +111,8 @@ Updates and bug fixes
+ 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 to the
`NDN-TLV specification <https://docs.named-data.net/NDN-packet-spec/0.1.1/>`__
+ ``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
:ndn-cxx:`ValidatorConfig`
@@ -145,7 +145,7 @@ Deprecated
Use versions that accept reference to ``io_service`` object.
- ``Face::ioService`` method, use ``Face::getIoService`` instead.
- ``Face::ioService`` method, use :ndn-cxx:`Face::getIoService` instead.
- :ndn-cxx:`Interest` constructor that accepts name, individual selectors, and individual
guiders as constructor parameters.
+2 -2
View File
@@ -112,8 +112,8 @@ Deprecated
``ndn::CertificateExtension``, ``ndn::CertificateSubjectDescription``. When necessary, use
``security::v1::PublicKey``, ``security::v1::Certificate``, ``security::v1::IdentityCertificate``,
``security::v1::CertificateExtension``, ``security::v1::CertificateSubjectDescription`` instead.
The next release will feature `a new version of the NDN Certificate format
<https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__.
The next release will feature :doc:`a new version of NDN Certificate format
<../specs/certificate-format>`.
Removed
^^^^^^^
+19 -17
View File
@@ -13,19 +13,19 @@ Changes since version 0.5.0:
New features
^^^^^^^^^^^^
- Add version 2 of the security framework in ``security::v2`` namespace
- Add version 2 of the security framework (introduced in ``security::v2`` namespace)
* `NDN Certificate Format version 2.0
<https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__ (:issue:`3103`)
* New Public Information Base (PIB) and Trusted Platform Module (TPM) framework to manage
* :ref:`NDN Certificate Format Version 2.0 <NDN Certificate Format Version 2.0>`
(:issue:`3103`)
* New Public Information Base (PIB) and Trusted Program Module (TPM) framework to manage
public/private keys and NDN Certificate version 2.0 (:issue:`2948`, :issue:`3202`)
* New KeyChain implementation (:issue:`2926`)
* New Validator implementation (:issue:`3289`, :issue:`1872`)
* New security-supporting utilities: trust anchor container and certificate cache
* Creation of `Command Interests
<https://redmine.named-data.net/projects/ndn-cxx/wiki/CommandInterest>`__ delegated to
``CommandInterestSigner`` class, while the new KeyChain only :doc:`signs Interests
</specs/signed-interest>` (:issue:`3912`)
:ndn-cxx:`CommandInterestSigner` class, while the new KeyChain only :ref:`signs Interests
<Signed Interest>` (:issue:`3912`)
- Enable validator to fetch certificates directly from the signed/command interest sender
(:issue:`3921`)
@@ -63,27 +63,27 @@ Improvements and bug fixes
Deprecated
^^^^^^^^^^
- Old security framework. All old security framework classes are moved to the
- Old security framework. All old security framework classes are moved to
``ndn::security::v1`` namespace in this release and will be removed in the next release.
* ``v1::KeyChain``; use ``v2::KeyChain`` instead.
* ``v1::KeyChain``, use :ndn-cxx:`v2::KeyChain` instead
* ``v1::Validator`` interface and all implementations of this interface (``ValidatorRegex``,
``ValidatorConfig``, ``ValidatorNull``). Use ``v2::Validator`` and the corresponding
implementations of :ndn-cxx:`ValidationPolicy` interfaces (will be introduced before
the 0.6.0 release).
``ValidatorConfig``, ``ValidatorNull``). Use :ndn-cxx:`v2::Validator` and the
corresponding implementations of :ndn-cxx:`ValidationPolicy` interfaces (will be introduced
before 0.6.0 release).
* ``v1::SecPublicInfo`` and its implementation (``SecPublicInfoSqlite``), ``SecTpm`` and its
implementations (``SecTpmFile``, ``SecTpmOsx``). These classes are internal implementation
and not intended to be used without ``v1::KeyChain``. ``v2::KeyChain`` internally uses
the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their corresponding
implementations.
and not intended to be used without ``v1::KeyChain``. :ndn-cxx:`v2::KeyChain` internally
uses the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their
corresponding implementations.
* ``v1::Certificate``, ``v1::IdentityCertificate``, ``v1::CertificateExtension``,
``v1::CertificateSubjectDescription``; use ``v2::Certificate`` and ``AdditionalDescription``
instead.
``v1::CertificateSubjectDescription``, use :ndn-cxx:`v2::Certificate` and
:ndn-cxx:`AdditionalDescription`
* ``v1::SecuredBag``; use :ndn-cxx:`SafeBag` instead.
* ``v1::SecuredBag``, use ``v2::SafeBag`` instead
- Constant ``io::BASE_64``, use ``io::BASE64`` instead (:issue:`3741`)
@@ -100,3 +100,5 @@ Deprecated
``ndn::CertificateExtension``, ``ndn::CertificateSubjectDescription``. When necessary, use
``security::v1::PublicKey``, ``security::v1::Certificate``, ``security::v1::IdentityCertificate``,
``security::v1::CertificateExtension``, ``security::v1::CertificateSubjectDescription`` instead.
The next release will feature :ref:`a new version of NDN Certificate format
<NDN Certificate Format Version 2.0>`.
+34 -29
View File
@@ -11,12 +11,12 @@ New features
- **(breaking change)** Security framework version 2 (:issue:`3098`, :issue:`3920`,
:issue:`3644`, :issue:`4085`, :issue:`4323`, :issue:`4339`).
This release of the library supports only the new version of the security framework
and features a number of updates to the KeyChain and Validator interfaces.
At the same time, management APIs for :ndn-cxx:`ValidatorConfig` remained intact;
transition to the new framework only requires adjusting :ndn-cxx:`Validator::validate`
calls and updating configuration files to follow the naming conventions of the new
`Certificate format <https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__.
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`)
@@ -25,7 +25,7 @@ New features
to include ``ForwardingHint`` instead of ``LinkObject``, following the latest NDN
specification updates (:issue:`4054`, :issue:`4055`)
- Fine-grained signals on interface/address changes in :ndn-cxx:`NetworkMonitor`
- Fine-grained signals on interface/address changes in NetworkMonitor
for all supported platforms (:issue:`3353`, :issue:`4025`, :issue:`3817`, :issue:`4024`)
- Addition of ``TxSequence`` field and ``Ack``, the first repeatable field in
@@ -51,7 +51,7 @@ Improvements and bug fixes
- FaceUri now accepts link-local IPv6 addresses (:issue:`1428`)
- Rename fields in :ndn-cxx:`FaceStatus` and :ndn-cxx:`ForwarderStatus` ('datas' => 'data')
- Rename variables in ``FaceStatus`` and ``ForwarderStatus`` ('datas' => 'data')
(:issue:`3955`)
- Improve logging framework and its uses
@@ -63,19 +63,19 @@ Improvements and bug fixes
* Add logging capabilities to ``Face``, ``UnixTransport``, ``TcpTransport``, and the new
security framework (:issue:`3563`)
To configure logging, set the environment variable :doc:`NDN_LOG </manpages/ndn-log>`.
Examples:
To enable logging, set environment variable ``NDN_LOG`` to enable specific, subset, or all
logging module at appropriate levels. Examples:
.. code-block:: sh
::
export NDN_LOG="*=ALL"
export NDN_LOG="ndn.*=ALL"
export NDN_LOG="ndn.security=DEBUG:ndn.TcpTransport=ALL"
export NDN_LOG=*=ALL
export NDN_LOG=ndn.*=ALL
export NDN_LOG=ndn.security=DEBUG:ndn.TcpTransport=ALL
- Ensure that :ndn-cxx:`Face` sends a ``Nack`` only after every ``InterestCallback`` has
responded (:issue:`4228`)
- Ensure that ``Face`` sends ``Nack`` only after every ``InterestCallback`` has responded
(:issue:`4228`)
- Fix potential overflow in :ndn-cxx:`time::toIsoString` (:issue:`3915`)
- Fix potential overflow in ``time::toIsoString`` (:issue:`3915`)
- Fix potentially misaligned memory accesses (:issue:`4172`, :issue:`4097`, :issue:`4175`,
:issue:`4190`, :issue:`4191`)
@@ -86,15 +86,20 @@ Improvements and bug fixes
- Source/header reorganization (:issue:`3940`)
* Move network-related files to ``src/net``. Note the following namespace changes:
* Move network-related files to ``src/net``
+ ``ndn::util::FaceUri`` is now ``ndn::FaceUri``
+ ``ndn::util::ethernet`` is now ``ndn::ethernet``
+ ``ndn::util::NetworkMonitor`` and related classes are now in ``ndn::net``
.. note::
Namespace changes
* Move signal-related files into ``src/util/signal`` directory, except for
* ndn::util::FaceUri is now ndn::FaceUri
* ndn::util::ethernet is now ndn::ethernet
* ndn::util::NetworkMonitor and related classes are now in ndn::net
* Move signal-related files into ``src/util/signal/`` directory, except for
the main include ``signal.hpp``
* Move :ndn-cxx:`InMemoryStorage` and related classes to ``src/ims``
* Move InMemoryStorage to ``src/ims``
* Rename ``digest.hpp`` to ``sha256.hpp`` to match the ``Sha256`` class declared within
Removed
@@ -102,23 +107,23 @@ Removed
- Old security framework.
* ``v1::KeyChain``; use :ndn-cxx:`KeyChain` instead.
* ``v1::KeyChain``, use :ndn-cxx:`v2::KeyChain` instead
* ``v1::Validator`` interface and ``ValidatorRegex`` implementation of this
interface. ``ValidatorConfig``, ``ValidatorNull`` implementation refactored to be based on
the new validation framework.
* ``v1::SecPublicInfo`` and its implementation (``SecPublicInfoSqlite``), ``SecTpm`` and its
implementations (``SecTpmFile``, ``SecTpmOsx``). These classes are internal implementation
and not intended to be used without ``v1::KeyChain``. The new :ndn-cxx:`KeyChain` internally
implementations (``SecTpmFile``, ``SecTpmOsx``). These classes are internal implementation
and not intended to be used without ``v1::KeyChain``. :ndn-cxx:`v2::KeyChain` internally
uses the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their
corresponding implementations.
* ``v1::Certificate``, ``v1::IdentityCertificate``, ``v1::CertificateExtension``,
``v1::CertificateSubjectDescription``; use the new :ndn-cxx:`Certificate` and
:ndn-cxx:`AdditionalDescription` instead.
``v1::CertificateSubjectDescription``, use :ndn-cxx:`v2::Certificate` and
:ndn-cxx:`AdditionalDescription`
* ``v1::SecuredBag``; use :ndn-cxx:`SafeBag` instead.
* ``v1::SecuredBag``, use ``v2::SafeBag`` instead
- Constant ``io::BASE_64``, use ``io::BASE64`` instead (:issue:`3741`)
+1 -1
View File
@@ -7,7 +7,7 @@ New features
^^^^^^^^^^^^
- Initial support for `NDN packet format version 0.3
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
* Recognize typed name components, allow typed name component in ``FinalBlockId``
(:issue:`4526`)
+1 -1
View File
@@ -13,7 +13,7 @@ New features
^^^^^^^^^^^^
- More support for `NDN packet format version 0.3
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
- Allow applications to declare a default ``CanBePrefix`` setting (:issue:`4581`)
+17 -18
View File
@@ -6,8 +6,8 @@ Release date: February 4, 2019
New features
^^^^^^^^^^^^
- More support for `NDN packet format version 0.3
<https://docs.named-data.net/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`)
* Stop using ``ChildSelector`` in ``NotificationSubscriber`` (:issue:`4664`)
@@ -18,42 +18,41 @@ New features
- Scoped prefix registration, scoped Interest filter, and scoped pending Interest
(:issue:`3919`, :issue:`4316`)
- Counters for satisfied and unsatisfied Interests in :ndn-cxx:`ForwarderStatus`
- Counters for satisfied and unsatisfied Interests in ``ForwarderStatus``
(:issue:`4720`)
- :ndn-cxx:`random::getRandomNumberEngine` in the public API
- ``random::getRandomNumberEngine()`` in the public API
- :ndn-cxx:`MetadataObject` class to encode/decode RDR-style metadata (:issue:`4707`)
- ``MetadataObject`` class to encode/decode RDR-style metadata (:issue:`4707`)
- :ndn-cxx:`SegmentFetcher::stop` (:issue:`4692`)
- ``SegmentFetcher::stop()`` (:issue:`4692`)
Improvements and bug fixes
^^^^^^^^^^^^^^^^^^^^^^^^^^
- Use openssl-based routines for the PKCS#8 decoding/decryption when exporting key from macOS
Keychain (:issue:`4450`)
- Switch to AES-256 for private key encryption in PKCS #8 export
- Use OpenSSL-based routines for PKCS #8 decoding/decryption when exporting keys from the
macOS Keychain (:issue:`4450`)
- Forbid unrecognized TLVs before ``Name`` (:issue:`4667`)
- Stop accepting NonNegativeInteger as sequence number in NDNLP (:issue:`4598`)
- Add exponential backoff in :ndn-cxx:`CertificateFetcherFromNetwork` (:issue:`4718`,
:issue:`4712`)
- Add exponential backoff in ``CertificateFetcherFromNetwork`` (:issue:`4718`, :issue:`4712`)
- Throw exception when loading an orphaned ``ValidationPolicyConfig`` (API violation)
(:issue:`4758`)
- Prevent memory pool size from becoming zero in :ndn-cxx:`InMemoryStorage` (:issue:`4769`)
- Forbid unrecognized TLVs before ``Name`` (:issue:`4667`)
- Clean up fetchers when destructing :ndn-cxx:`nfd::Controller` (:issue:`4775`)
- Prevent memory pool size from becoming zero in ``InMemoryStorage`` (:issue:`4769`)
- Clean up fetchers when destructing ``nfd::Controller`` (:issue:`4775`)
- Fix ``SegmentFetcher`` undefined behavior caused by uncanceled pending interest
(:issue:`4770`)
- Seed the PRNG with more entropy (:issue:`4808`)
- Stop accepting NonNegativeInteger as sequence number in NDNLP (:issue:`4598`)
- Backport C++17 ``std::any`` and ``std::variant`` as ``ndn::any`` and ``ndn::variant``
- Reimplement ``scheduler::EventId`` with ``CancelHandle`` (:issue:`4698`)
@@ -61,7 +60,7 @@ Improvements and bug fixes
Deprecated
^^^^^^^^^^
- ``ndn-cxx/util/scheduler-scoped-event-id.hpp`` header, as it is now sufficient to use
- ``ndn-cxx/util/scheduler-scoped-event-id.hpp`` header as it is now sufficient to use
``ndn-cxx/util/scheduler.hpp`` header (:issue:`4698`)
- Implicit conversion from nullptr to ``scheduler::EventId`` (:issue:`4698`)
+4 -5
View File
@@ -5,15 +5,15 @@ Release date: April 27, 2019
.. note::
This is the last release to support the `NDN packet format version 0.2.1
<https://docs.named-data.net/NDN-packet-spec/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://docs.named-data.net/NDN-packet-spec/0.3/>`__.
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__.
New features
^^^^^^^^^^^^
- More support for `NDN packet format version 0.3
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
<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`)
@@ -23,8 +23,7 @@ New features
- ``NDN_THROW`` macro to throw exceptions including file position and runtime context of the
throw statement (:issue:`4834`)
- Ensure that a :ndn-cxx:`Block` with TLV-TYPE zero is treated as invalid (:issue:`4726`,
:issue:`4895`)
- Ensure that a ``Block`` with TLV-TYPE zero is treated as invalid (:issue:`4726`, :issue:`4895`)
Improvements and bug fixes
^^^^^^^^^^^^^^^^^^^^^^^^^^
+8 -9
View File
@@ -6,7 +6,7 @@ Release date: January 13, 2020
**Breaking Change**
This release features support of only `NDN packet format version 0.3
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`, :issue:`4567`,
<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 been updated to follow the
@@ -17,29 +17,28 @@ New features
- HMAC signing support (:issue:`3075`)
- Support for ``ParametersSha256DigestComponent`` in :ndn-cxx:`Name` and :ndn-cxx:`Interest`
- Support for ``ParametersSha256DigestComponent`` in ``Name`` and ``Interest`` classes
(:issue:`4658`)
- Encoding and decoding of ``HopLimit`` field in Interest (:issue:`4806`)
- Encoding/decoding of ``HopLimit`` field in Interest (:issue:`4806`)
- Support for encoding and decoding PIT token as NDNLPv2 field (:issue:`4532`).
- PIT token (:issue:`4532`).
PIT token is a hop-by-hop header field that identifies an Interest-Data exchange. The
downstream node can assign an opaque token to an outgoing Interest, and the upstream node
is expected to return the same token on the Data or Nack in reply to that Interest. This
would allow the downstream node to accelerate its processing, especially in PIT lookup.
- :ndn-cxx:`io::loadBuffer` and :ndn-cxx:`io::saveBuffer` helper functions
- ``io::loadBuffer`` and ``io::saveBuffer`` helper functions
Improvements and bug fixes
^^^^^^^^^^^^^^^^^^^^^^^^^^
- Various improvements in the Linux implementation of :ndn-cxx:`NetworkMonitor`
- Various improvements in the Linux implementation of ``NetworkMonitor`` class
- Rework of ``RttEstimator`` class:
* split into two classes: :ndn-cxx:`RttEstimator` and :ndn-cxx:`RttEstimatorWithStats`
(:issue:`4887`)
* split into two classes: ``RttEstimator`` and ``RttEstimatorWithStats`` (:issue:`4887`)
* add a getter for the smoothed RTT value (:issue:`4892`)
* switch to use ``time::nanoseconds`` (:issue:`4887`)
@@ -65,7 +64,7 @@ Removals
- Unused ``v2::PublicKey`` alias of ``transform::PublicKey``
- ``HmacFilter`` class, use :ndn-cxx:`SignerFilter` and :ndn-cxx:`VerifierFilter` instead
- ``HmacFilter`` class, use SignerFilter and VerifierFilter instead
- Ill-defined equality operators for ``Interest``, ``MetaInfo``, ``Signature`` (:issue:`4569`)
+5 -6
View File
@@ -12,11 +12,10 @@ Additionally, this release drops support for CentOS 7 and adds support for CentO
New features
^^^^^^^^^^^^
- `Signed Interests <https://docs.named-data.net/NDN-packet-spec/0.3/signed-interest.html>`__
according to Packet Specification v0.3 (:issue:`4804`)
- Signed Interests according to Packet Specification v0.3 (:issue:`4804`)
- Add "in-order" mode to :ndn-cxx:`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
- 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
@@ -35,7 +34,7 @@ Improvements and bug fixes
- Fix spurious error message from ``ndnsec-key-gen`` when ``key-id`` is specified (:issue:`5057`)
- Provide more fine-grained choices for :ndn-cxx:`name::UriFormat` (:issue:`4777`)
- Provide more fine-grained choices for ``name::UriFormat`` (:issue:`4777`)
- Allow automatic log flushing to be disabled (:issue:`3668`)
@@ -50,7 +49,7 @@ Improvements and bug fixes
- Correctly handle non-existent identity in ``PibImpl::setDefaultIdentity``
- Fix incompatibility with Boost 1.73.0+ in :ndn-cxx:`time::toIsoString`
- Fix incompatibility with ``time::toIsoString`` in Boost 1.73.0+
- Fix incompatibility with ``<version>`` header in C++20
@@ -1,84 +0,0 @@
ndn-cxx version 0.8.0
---------------------
Release date: February 15, 2022
Important changes
^^^^^^^^^^^^^^^^^
- Flip default value of ``CanBePrefix`` to **false** (:issue:`4582`). This means that
Interests created without explicitly specifying ``CanBePrefix`` option will be treated
as Interests for exact Data name.
- Change default name component encoding convention to ``TYPED`` (:issue:`5044`)
- Update TLV-TYPE numbers to revision 3 of the `naming conventions`_
.. _naming conventions:
https://named-data.net/publications/techreports/ndn-tr-22-3-ndn-memo-naming-conventions/
- Change TLV-TYPE number of ``IncomingFaceId`` field in NDNLP (:issue:`5185`)
- Update Interest ``ForwardingHint`` format (:issue:`5187`)
Improvements and bug fixes
^^^^^^^^^^^^^^^^^^^^^^^^^^
- Support certificate name, versionless certificate name, and key name options for
KeyLocator name in ``ValidatorConfig`` (:issue:`5142`)
- Generalize signature verification to allow ``digest-sha256``, effectively adding
support of digest integrity verification in ``ValidatorConfig``
- Enforce ``sig-type`` check in ``ValidatorConfig`` (:issue:`4524`)
- Fix ``ValidatorConfig`` rule processing bug (:issue:`5145`)
- Prevent potential dereferencing of past-the-end iterator in ``Block::value()``
- Fail early in :ndn-cxx:`Block::blockFromValue` if TLV length is zero
- Refactor and cleanup of :ndn-cxx:`StatusDatasetContext`, including increase of maximum
payload size of each produced segment to 8000 bytes
- Improve error reporting when loading a ``Certificate`` or ``SafeBag`` fails
- Add API to get the keyword name component for Metadata and Prefix Announcements
- Backport C++20 ``std::span`` and convert most APIs to use it
- Introduce ``time::{to,from}IsoExtendedString()`` utility functions
- Add support for OpenSSL 3.0. Note that because of the API changes, HMAC implementation
does not currently work when compiled with OpenSSL 3.0+, use older version of OpenSSL
when needed.
- Various build system and documentation extension and fixes
Deprecations
^^^^^^^^^^^^
- ``Interest::setDefaultCanBePrefix()``
- ``Name::append(Block)`` overload, as it has confusing semantics (:issue:`5186`)
- ``ndnsec`` tool aliases: ``ndnsec-certgen``, ``ndnsec-dump-certificate``,
``ndnsec-install-cert``, ``ndnsec-keygen``, ``ndnsec-ls-identity``
Removals
^^^^^^^^
- Previously deprecated ``Signature`` class, its subclasses, and deprecated methods from
``Data``, ``KeyChain``, ``SignatureInfo``, and ``SigningInfo``
- Redundant overloads of ``verifySignature()`` and ``verifyDigest()``
- Previously deprecated ``security/v2`` headers
- Previously deprecated ``CommandInterestSigner``
- Unused ``Transport::send()`` overload
- Remove HTTP download feature in ``ndnsec cert-install``, as it does not support HTTPS
retrieval. The recommended way of installing certificates published over HTTP/HTTPS has
been changed to use ``curl`` or ``wget`` (:issue:`4506`)
-102
View File
@@ -1,102 +0,0 @@
ndn-cxx version 0.8.1
---------------------
Release date: December 31, 2022
.. note::
This is the last release of ndn-cxx to support the C++14 standard.
Future versions will require C++17 to build.
Important changes and new features
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The minimum build requirements have been increased as follows:
- Either GCC >= 7.4.0 or Clang >= 6.0 is required on Linux
- On macOS, Xcode 11.3 or later is recommended; older versions may still work but are not
officially supported
- Boost >= 1.65.1 and OpenSSL >= 1.1.1 are required on all platforms
- Sphinx 4.0 or later is required to build the documentation
- CentOS Stream 9 is now officially supported; CentOS 8 has been dropped (:issue:`5181`)
- macOS 12 (Monterey) and 13 (Ventura) running on arm64 are now officially supported
(:issue:`5135`)
- Add the initial version of a :ndn-cxx:`Segmenter` API that applications can use to simplify
the process of chunking a large object into multiple signed Data packets (:issue:`5247`)
- Add ``KeyChain::makeCertificate()`` to simplify the creation of certificates
- Put the full certificate name in the ``KeyLocator`` field, instead of just the key name
(:issue:`5112`)
- NFD management commands sent by :ndn-cxx:`nfd::Controller` now use the `new signed Interest
format <https://docs.named-data.net/NDN-packet-spec/0.3/signed-interest.html>`__ (:issue:`4804`)
Improvements and bug fixes
^^^^^^^^^^^^^^^^^^^^^^^^^^
- Several enhancements and cleanups in :ndn-cxx:`Name` and :ndn-cxx:`Component` to make
the API more consistent and simpler to use (:issue:`5186`)
- Various improvements in the validation framework and policies
- Avoid redundant TLV decoding during Interest validation
- Fix validation of signed Interests with malformed ``InterestSignatureInfo``
- More accurate validation error codes are returned in several cases
- Rename ``ValidationError::NO_SIGNATURE`` to ``MALFORMED_SIGNATURE``
- Optimize parsing of PIB and TPM locators in :ndn-cxx:`KeyChain`
- Major cleanup and modernization of PIB implementation
- Gracefully handle invalid or unsupported public keys stored in the PIB
- Fix OpenSSL 3.0 deprecation warnings in private key generation routines (:issue:`5154`)
- Change ``Certificate::getPublicKey()`` to return a ``span``
- Make :ndn-cxx:`Block` convertible to ``span<const uint8_t>``
- Avoid assertion failure in :ndn-cxx:`OBufferStream` under certain conditions (:issue:`5240`)
- Allow customizing the FaceId in :ndn-cxx:`DummyClientFace` (:issue:`5011`)
- Improve pretty-printing of certificates, e.g., in ``ndnsec list`` and ``ndnsec cert-dump``
- Relax restrictions on KeyId component type in ``ndnsec key-gen``
- Fix handling of ``--without-osx-keychain`` configure option (:issue:`3338`)
- Stop using the ``gold`` linker on Linux; prefer instead linking with ``lld`` if installed
- Update waf build system to version 2.0.24
- Various documentation improvements
Deprecations
^^^^^^^^^^^^
- ``Name::append()`` overloads and :ndn-cxx:`Component` constructors that take a
``const uint8_t*``. Use the ``span``-based overloads instead.
- ``Component::fromImplicitSha256Digest()`` and ``Component::fromParametersSha256Digest()``.
Use one of the constructors directly instead.
Removals
^^^^^^^^
- Obsolete TLV-TYPE definitions
- Many previously deprecated functions that take raw byte buffers as ``uint8_t*`` + ``size_t``,
replaced by equivalent functions that take a ``span``. These include ``Data::setContent()``,
``Interest::setApplicationParameters()``, ``Block::fromBuffer()``, ``verifySignature()``,
``PublicKey::loadPkcs8()``, ``transform::bufferSource()``, ``random::generateSecureBytes()``,
``printHex()``, ``toHex()``, and so on.
- Previously deprecated ``Name::append(Block)`` overload
- Previously deprecated ``Interest::setDefaultCanBePrefix()``
- ``ndn::any`` and related functionality
+59 -55
View File
@@ -1,135 +1,139 @@
All ndn-cxx Releases
====================
++++++++++++++++++++
.. toctree::
:glob:
:hidden:
:maxdepth: 1
:reversed:
release-notes/*
* **ndn-cxx version 0.8.1**
(:doc:`Release Notes <release-notes/release-notes-0.8.1>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.8.1/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.8.1>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.8.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.8.1.tar.bz2.sha256>`__)
* **ndn-cxx version 0.8.0**
(:doc:`Release Notes <release-notes/release-notes-0.8.0>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.8.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.8.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.8.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.8.0.tar.bz2.sha256>`__)
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
release-notes/release-notes-0.6.3
release-notes/release-notes-0.6.2
release-notes/release-notes-0.6.1
release-notes/release-notes-0.6.0
release-notes/release-notes-0.5.1
release-notes/release-notes-0.5.0
release-notes/release-notes-0.4.1
release-notes/release-notes-0.4.0
release-notes/release-notes-0.3.4
release-notes/release-notes-0.3.3
release-notes/release-notes-0.3.2
release-notes/release-notes-0.3.1
release-notes/release-notes-0.3.0
release-notes/release-notes-0.2.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://docs.named-data.net/ndn-cxx/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/ndn-cxx-0.7.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.7.1.tar.bz2.sha256>`__)
`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://docs.named-data.net/ndn-cxx/0.7.0/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.7.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.7.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.7.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.7.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.7.0.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.7.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.7.0.tar.bz2.sha256>`__)
* **ndn-cxx version 0.6.6**
(:doc:`Release Notes <release-notes/release-notes-0.6.6>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.6/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.6.6>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.6/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.6>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.6.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.6.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.6.6.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.6.tar.bz2.sha256>`__)
* **ndn-cxx version 0.6.5**
(:doc:`Release Notes <release-notes/release-notes-0.6.5>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.5/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.6.5>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.5/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.5>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.5.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.5.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.6.5.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.5.tar.bz2.sha256>`__)
* **ndn-cxx version 0.6.4** was skipped
* **ndn-cxx version 0.6.4 was skipped**
* **ndn-cxx version 0.6.3**
(:doc:`Release Notes <release-notes/release-notes-0.6.3>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.3/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.6.3>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.3/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.3>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.3.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.6.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.3.tar.bz2.sha256>`__)
* **ndn-cxx version 0.6.2**
(:doc:`Release Notes <release-notes/release-notes-0.6.2>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.2/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.6.2>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.2/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.2>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.2.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.6.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.2.tar.bz2.sha256>`__)
* **ndn-cxx version 0.6.1**
(:doc:`Release Notes <release-notes/release-notes-0.6.1>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.1/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.6.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.1/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.1>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.1.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.6.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.1.tar.bz2.sha256>`__)
* **ndn-cxx version 0.6.0**
(:doc:`Release Notes <release-notes/release-notes-0.6.0>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.0/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.6.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.0.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.6.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.0.tar.bz2.sha256>`__)
* **ndn-cxx version 0.5.1**
(:doc:`Release Notes <release-notes/release-notes-0.5.1>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.5.1/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.5.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.5.1/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.5.1>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.5.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.5.1.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.5.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.5.1.tar.bz2.sha256>`__)
* **ndn-cxx version 0.5.0**
(:doc:`Release Notes <release-notes/release-notes-0.5.0>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.5.0/>`__)
(:doc:`Release Notes <release-notes/release-notes-0.5.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.5.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.5.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.5.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.5.0.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.5.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.5.0.tar.bz2.sha256>`__)
* **ndn-cxx version 0.4.1**
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`)
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.4.1/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.4.1>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.4.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.4.1.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.4.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.4.1.tar.bz2.sha256>`__)
* **ndn-cxx version 0.4.0**
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`)
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.4.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.4.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.4.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.4.0.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.4.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.4.0.tar.bz2.sha256>`__)
* **ndn-cxx version 0.3.4**
(:doc:`Release Notes <release-notes/release-notes-0.3.4>`)
(:doc:`Release Notes <release-notes/release-notes-0.3.4>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.4/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.4>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.4.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.4.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.3.4.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.4.tar.bz2.sha256>`__)
* **ndn-cxx version 0.3.3**
(:doc:`Release Notes <release-notes/release-notes-0.3.3>`)
(:doc:`Release Notes <release-notes/release-notes-0.3.3>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.3/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.3>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.3.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.3.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.3.tar.bz2.sha256>`__)
* **ndn-cxx version 0.3.2**
(:doc:`Release Notes <release-notes/release-notes-0.3.2>`)
(:doc:`Release Notes <release-notes/release-notes-0.3.2>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.2/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.2>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.2.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.3.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.2.tar.bz2.sha256>`__)
* **ndn-cxx version 0.3.1**
(:doc:`Release Notes <release-notes/release-notes-0.3.1>`)
(:doc:`Release Notes <release-notes/release-notes-0.3.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.1/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.1>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.1.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.3.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.1.tar.bz2.sha256>`__)
* **ndn-cxx version 0.3.0**
(:doc:`Release Notes <release-notes/release-notes-0.3.0>`)
(:doc:`Release Notes <release-notes/release-notes-0.3.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.0.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.3.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.0.tar.bz2.sha256>`__)
* **ndn-cxx version 0.2.0**
(:doc:`Release Notes <release-notes/release-notes-0.2.0>`)
(:doc:`Release Notes <release-notes/release-notes-0.2.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.2.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.2.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.2.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.2.0.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.2.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.2.0.tar.bz2.sha256>`__)
- ndn-cxx version 0.2.0-rc1
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.2.0-rc1>`__
@@ -138,10 +142,10 @@ All ndn-cxx Releases
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.2.0-rc2>`__
* **ndn-cxx version 0.1.0**
(:doc:`Release Notes <release-notes/release-notes-0.1.0>`)
(:doc:`Release Notes <release-notes/release-notes-0.1.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.1.0/>`__)
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.1.0>`__,
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.1.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.1.0.tar.bz2.sha256>`__)
`src (tarball) <https://named-data.net/downloads/nfd-0.1.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.1.0.tar.bz2.sha256>`__)
- ndn-cxx version 0.1.0-rc1
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.1.0-rc1>`__
+3 -1
View File
@@ -4,5 +4,7 @@ Specifications
.. toctree::
:maxdepth: 2
specs/safe-bag
specs/signed-interest
specs/certificate-format
specs/safe-bag
specs/validation-error-code
+200
View File
@@ -0,0 +1,200 @@
.. _NDN Certificate Format Version 2.0:
NDN Certificate Format Version 2.0
==================================
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
that carries a public key as content is conceptually a certificate. However,
the specification of a data packet is not sufficient to be the specification of
a common certificate format, as it requires additional components. For example,
a certificate may follow a specific naming convention and may need to include
validity period, revocation information, etc. This specification defines
naming and structure of the NDN certificates and is complementary to NDN packet
specification.
::
Overview of NDN certificate format
+--------------------------+
| Name |
+--------------------------+
| MetaInfo |
|+------------------------+|
|| ContentType: KEY(2) ||
|+------------------------+|
|+------------------------+|
|| FreshnessPeriod: >~ 1h ||
|+------------------------+|
+--------------------------+
| Content |
|+------------------------+|
|| Public Key ||
|+------------------------+|
+--------------------------+
| SignatureInfo |
|+------------------------+|
|| SignatureType: ... ||
|| KeyLocator: ... ||
|| ValidityPeriod: ... ||
|| ... ||
|+------------------------+|
+--------------------------+
| SignatureValue |
+--------------------------+
.. code-block:: abnf
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
Name
----
The name of a certificate consists of five parts as shown below::
/<SubjectName>/KEY/[KeyId]/[IssuerId]/[Version]
A certificate name starts with the subject to which a public key is bound. The following parts
include the keyword ``KEY`` component, KeyId, IssuerId, and version components.
``KeyId`` is an opaque name component to identify an instance of the public key for the
certificate namespace. The value of `Key ID` is controlled by the namespace owner and can be
an 8-byte random number, SHA-256 digest of the public key, timestamp, or a simple numerical
identifier.
``Issuer Id`` is an opaque name component to identify issuer of the certificate. The value is
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::
/edu/ucla/cs/yingdi/KEY/%03%CD...%F1/%9F%D3...%B7/%FD%d2...%8E
\_________________/ \___________/ \___________/\___________/
Certificate Namespace Key Id Issuer Id Version
(Identity)
MetaInfo
--------
The ``ContentType`` of certificate is set to ``KEY`` (2).
The ``FreshnessPeriod`` of certificate must be explicitly specified. The
recommended value is 1 hour (3,600,000 milliseconds).
Content
-------
By default, the content of a certificate is the public key encoded in
`X509PublicKey <https://tools.ietf.org/html/rfc5280#section-4.1.2.7>`__ format.
SignatureInfo
-------------
The SignatureInfo block of a certificate is required to include the ``ValidityPeriod`` field.
``ValidityPeriod`` includes two sub TLV fields: ``NotBefore`` and ``NotAfter``, which carry two
UTC timestamps in ISO 8601 compact format (``yyyymmddTHHMMSS``, e.g., "20020131T235959").
``NotBefore`` indicates when the certificate takes effect while ``NotAfter`` indicates when the
certificate expires.
.. note::
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
NotAfter
NotBefore = NOT-BEFORE-TYPE TLV-LENGTH 8DIGIT "T" 6DIGIT
NotAfter = NOT-AFTER-TYPE TLV-LENGTH 8DIGIT "T" 6DIGIT
For each TLV, the TLV-TYPE codes are assigned as below:
+---------------------------------------------+-------------------+----------------+
| TLV-TYPE | Assigned code | Assigned code |
| | (decimal) | (hexadecimal) |
+=============================================+===================+================+
| ValidityPeriod | 253 | 0xFD |
+---------------------------------------------+-------------------+----------------+
| NotBefore | 254 | 0xFE |
+---------------------------------------------+-------------------+----------------+
| NotAfter | 255 | 0xFF |
+---------------------------------------------+-------------------+----------------+
Extensions
~~~~~~~~~~
A certificate may optionally carry some extensions in SignatureInfo. An extension
could be either critical or non-critical depends on the TLV-TYPE code convention. A
critical extension implies that if a validator cannot recognize or parse the
extension, the validator must reject the certificate. A non-critical extension
implies that if a validator cannot recognize or cannot parse the extension, the
validator may ignore the extension.
The TLV-TYPE code range [256, 512) is reserved for extensions. The last bit of a
TLV-TYPE code indicates whether the extension is critical or not: ``1`` for critical
while ``0`` for non-critical. If an extension could be either critical or
non-critical, the extension should be allocated with two TLV-TYPE codes which only
differ at the last bit.
Extensions
----------
We list currently defined extensions:
+---------------------------------------------+-------------------+----------------+
| TLV-TYPE | Assigned number | Assigned number|
| | (decimal) | (hexadecimal) |
+=============================================+===================+================+
| AdditionalDescription (non-critical) | 258 | 0x0102 |
+---------------------------------------------+-------------------+----------------+
AdditionalDescription
~~~~~~~~~~~~~~~~~~~~~
``AdditionalDescription`` is a non-critical extension that provides additional
information about the certificate. The information is expressed as a set of
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
AdditionalDescription = ADDITIONAL-DESCRIPTION-TYPE TLV-LENGTH
1*DescriptionEntry
DescriptionEntry = DESCRIPTION-ENTRY-TYPE TLV-LENGTH
DescriptionKey
DescriptionValue
DescriptionKey = DESCRIPTION-KEY-TYPE TLV-LENGTH 1*OCTET
DescriptionValue = DESCRIPTION-VALUE-TYPE TLV-LENGTH 1*OCTET
+---------------------------------------------+-------------------+----------------+
| TLV-TYPE | Assigned number | Assigned number|
| | (decimal) | (hexadecimal) |
+=============================================+===================+================+
| DescriptionEntry | 512 | 0x0200 |
+---------------------------------------------+-------------------+----------------+
| DescriptionKey | 513 | 0x0201 |
+---------------------------------------------+-------------------+----------------+
| DescriptionValue | 514 | 0x0202 |
+---------------------------------------------+-------------------+----------------+
+20 -19
View File
@@ -1,29 +1,30 @@
SafeBag Format for Exported Credentials
=======================================
Sometimes it may be necessary to export an identity's credentials (i.e., private key and associated
certificate) from one machine and import them into another. This requires a secure container to
carry the sensitive information. For this purpose, we define the **SafeBag** format, which contains
an `NDN certificate <https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__ and the
corresponding private key in encrypted form. The private key is formatted as a DER-encoded
:rfc:`EncryptedPrivateKeyInfo <5208#section-6>` structure as described in PKCS #8.
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>`_.
The TLV encoding of ``SafeBag`` is defined as follows:
The format of **SafeBag** is defined as:
.. code-block:: abnf
SafeBag = SAFE-BAG-TYPE TLV-LENGTH
Certificate
EncryptedKey
CertificateV2
EncryptedKeyBag
EncryptedKey = ENCRYPTED-KEY-TYPE TLV-LENGTH
*OCTET ; PKCS #8 EncryptedPrivateKeyInfo
EncryptedKeyBag = ENCRYPTED-KEY-BAG-TYPE TLV-LENGTH
*OCTET ; private key encrypted in PKCS #8 format
+---------------------------------------------+------------------+-----------------+
| Type | Assigned number | Assigned number |
| | (decimal) | (hexadecimal) |
+=============================================+==================+=================+
| SafeBag | 128 | 0x80 |
+---------------------------------------------+------------------+-----------------+
| EncryptedKey | 129 | 0x81 |
+---------------------------------------------+------------------+-----------------+
All TLV-TYPE numbers are application specific:
+---------------------------------------------+-------------------+----------------+
| TLV-TYPE | Assigned number | Assigned number|
| | (decimal) | (hexadecimal) |
+=============================================+===================+================+
| SafeBag | 128 | 0x80 |
+---------------------------------------------+-------------------+----------------+
| EncryptedKeyBag | 129 | 0x81 |
+---------------------------------------------+-------------------+----------------+
+8 -6
View File
@@ -1,10 +1,12 @@
.. _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://docs.named-data.net/NDN-packet-spec/current/signed-interest.html>`__.
`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.
@@ -52,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 <https://docs.named-data.net/NDN-packet-spec/0.2.1/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 <https://docs.named-data.net/NDN-packet-spec/0.2.1/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 <https://docs.named-data.net/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
`SignatureInfo <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
::
@@ -84,7 +86,7 @@ SignatureValue component (n *th*)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The value of the n *th* component is actually a
`SignatureValue <https://docs.named-data.net/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
`SignatureValue <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
::
@@ -109,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 <https://docs.named-data.net/NDN-packet-spec/0.2.1/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
+33
View File
@@ -0,0 +1,33 @@
Validation Error Code
=====================
The following table defines a list of known codes and their description, which can be returned from the :ndn-cxx:`v2::Validator` interface.
Other error codes can be returned by validator implementations outside ndn-cxx codebase.
+------------+--------------------------+-----------------------------------------------------+
| Error code | Short ID | Description |
+============+==========================+=====================================================+
| 0 | NO_ERROR | No error |
+------------+--------------------------+-----------------------------------------------------+
| 1 | INVALID_SIGNATURE | Invalid signature |
+------------+--------------------------+-----------------------------------------------------+
| 2 | NO_SIGNATURE | Missing signature |
+------------+--------------------------+-----------------------------------------------------+
| 3 | CANNOT_RETRIEVE_CERT | Cannot retrieve certificate |
+------------+--------------------------+-----------------------------------------------------+
| 4 | EXPIRED_CERT | Certificate expired |
+------------+--------------------------+-----------------------------------------------------+
| 5 | LOOP_DETECTED | Loop detected in certification chain |
+------------+--------------------------+-----------------------------------------------------+
| 6 | MALFORMED_CERT | Malformed certificate |
+------------+--------------------------+-----------------------------------------------------+
| 7 | EXCEEDED_DEPTH_LIMIT | Exceeded validation depth limit |
+------------+--------------------------+-----------------------------------------------------+
| 8 | INVALID_KEY_LOCATOR | Key locator violates validation policy |
+------------+--------------------------+-----------------------------------------------------+
| .. | ... | ... |
+------------+--------------------------+-----------------------------------------------------+
| 255 | IMPLEMENTATION_ERROR | Internal implementation error |
+------------+--------------------------+-----------------------------------------------------+
Specialized validator implementations can use error codes >= 256 to indicate a specialized error.
+23 -44
View File
@@ -199,38 +199,31 @@ checkers:
Customized Checker
~~~~~~~~~~~~~~~~~~
The customized checker can include optional **sig-type** property, which specifies the acceptable signature
type. If not specified, the checker will only accept ECDSA signature. Possible values for **sig-type** are:
- **ecdsa-sha256**: ECDSA signature required (default if **sig-type** not specified)
- **rsa-sha256**: RSA signature required
- **sha256** (not recommended, as it is not a real signature): SHA256 digest is required
If sig-type is **rsa-sha256** or **ecdsa-sha256**, the customized checker requires
**key-locator** property. If sig-type is **sha256**, **key-locator** property can be
specified, but is optional.
The customized checker requires two properties: **sig-type**, **key-locator**. Both must
appear exactly once and are related to the ``SignatureInfo`` of a packet.
::
checker
{
type customized
sig-type rsa-sha256
sig-type ...
key-locator
{
...
}
}
checker
{
type customized
sig-type sha256
}
The property **sig-type** specifies the acceptable signature type and can be
**rsa-sha256**, **ecdsa-sha256** (strong signature types), or **sha256** (weak signature
type). If sig-type is sha256, **key-locator** is ignored, and the validator will simply
calculate the digest of a packet and compare it with the one in ``SignatureValue``. If
sig-type is rsa-sha256 or ecdsa-sha256, you have to further customize the checker with
**key-locator**.
The **key-locator** property is a nested configuration property that can appear exactly once
and specifies conditions on ``KeyLocator``. It requires **type** property that currently
supports only one value: **name**.
The property **key-locator** specifies the conditions on ``KeyLocator``. If the
**key-locator** property is specified, it requires the existence of the ``KeyLocator``
field in ``SignatureInfo``. **key-locator** property only supports one type: **name**:
::
@@ -240,9 +233,9 @@ supports only one value: **name**.
...
}
``KeyLocator`` conditions can be specified in the same way as the name filter. For example, a
checker that requires ``SignatureSha256WithRsa`` signature type with ``KeyLocator`` to be exactly
``/ndn/edu/ucla/yingdi/KEY/1234`` can be written as follows:
This key-locator property specifies the conditions on the certificate name of the signing
key. Since the conditions are about name, they can be specified in the same way as the
name filter. For example, a checker can be:
::
@@ -258,27 +251,13 @@ checker that requires ``SignatureSha256WithRsa`` signature type with ``KeyLocato
}
}
Similarly, a checker that requires ``SignatureSha256WithEcdsa`` signature with ``KeyLocator``
that follows a regular expression pattern ``<ndn><>*<KEY><>{1,3}`` can be written as follows:
This checker property requires that the packet must have a ``rsa-sha256`` signature that
can be verified with ``/ndn/edu/ucla/yingdi/KEY/1234`` key.
::
checker
{
type customized
sig-type ecdsa-sha256
key-locator
{
type name
regex <ndn><>*<KEY><>{1,3}
relation equal
}
}
In addition, ``KeyLocator`` can be further constrained using information extracted from the
packet name using the **hyper-relation** property.
The **hyper-relation** property consists of three parts:
Besides the two ways to express conditions on the ``KeyLocator`` name (name and regex),
you can further constrain the ``KeyLocator`` name using the information extracted from the
packet name. This third type of condition is expressed via a property
**hyper-relation**. The **hyper-relation** property consists of three parts:
- an NDN regular expression that extracts information from the packet name
- an NDN regular expression that extracts information from the ``KeyLocator`` name
@@ -298,7 +277,7 @@ For example, a checker:
type name
hyper-relation
{
k-regex ^(<>*)<KEY><>{1,3}$
k-regex ^(<>*)<KEY><>$
k-expand \\1
h-relation is-prefix-of
p-regex ^(<>*)$
@@ -338,7 +317,7 @@ is equivalent to a customized checker:
type name
hyper-relation
{
k-regex ^(<>*)<KEY><>{1,3}$
k-regex ^(<>*)<KEY><>$
k-expand \\1
h-relation is-prefix-of
p-regex ^(<>*)$
+24 -24
View File
@@ -4,12 +4,12 @@ NDN Regular Expression
NDN regular expression is a kind of regular expression that can match NDN names. Matching is
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 using the `Modified ECMAScript Regular Expression Syntax
A name component matcher, enclosed in ``<`` and ``>``, specifies the pattern of a name component. The
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.
not match the 2nd component. A special case is that ``<>`` denotes a wildcard matcher that can match
**ANY** name component.
A component matcher can match only one name component. To match a name, you need to compose an NDN
regular expression with zero or more name component matchers. For example, ``<ndn><edu><ucla>``
@@ -31,8 +31,8 @@ name: ``/ndn/edu``.
Repetition
~~~~~~~~~~
A component matcher can be followed by a **repeat quantifier** to indicate how many times the
preceding component may appear.
A component matcher can be followed by a repeat quantifier to indicate how many times the preceding
component may appear.
The ``*`` quantifier denotes "zero or more times". For example, ``^<A><B>*<C>$`` matches ``/A/C``,
``/A/B/C``, ``/A/B/B/C``, and so on.
@@ -43,44 +43,44 @@ The ``+`` quantifier denotes "one or more times". For example, ``^<A><B>+<C>$``
The ``?`` quantifier denotes "zero or one time". For example, ``^<A><B>?<C>`` matches ``/A/C`` and
``/A/B/C``, but does not match ``/A/B/B/C``.
A **bounded quantifier** specifies either a minimum or a maximum number of permitted matches, or
both. ``{n}`` means "exactly ``n`` times"; ``{n,}`` means "at least ``n`` times"; ``{,n}`` means
"at most ``n`` times"; ``{m,n}`` (with ``m ≤ n``) means "between ``m`` and ``n`` times (inclusive)".
For example, ``^<A><B>{2,4}<C>$`` matches ``/A/B/B/C`` and ``/A/B/B/B/B/C``.
A bounded quantifier specifies a minimum and maximum number of permitted matches: ``{n}`` denotes
"exactly ``n`` times"; ``{n,}`` denotes "at least ``n`` times"; ``{,n}`` denotes "at most ``n``
times"; ``{n, m}`` denotes "between ``n`` and ``m`` times (inclusive)". For example,
``^<A><B>{2, 4}<C>$`` matches ``/A/B/B/C`` and ``/A/B/B/B/B/C``.
Note that the quantifiers are *greedy*, meaning that they will consume as many matching components
as possible. For example, for the name ``/A/B/C/C/C``, ``^<A><B><C>+`` will match the entire name
instead of only ``/A/B/C``. NDN regular expressions do not currently support non-greedy quantifiers
and possessive quantifiers.
Note that the quantifiers are **greedy**, which means it will consume as many matched components as
possible. NDN regular expressions currently do not support non-greedy repeat matching and possessive
repeat matching. For example, for the name ``/A/B/C/C/C``, ``^<A><B><C>+$`` will match the entire
name instead of only ``/A/B/C``.
Sets
~~~~
A **name component set**, denoted by a bracket expression starting with ``[`` and ending with ``]``,
A name component set, denoted by a bracket expression starting with ``[`` and ending with ``]``,
defines a set of name components. It matches any single name component that is a member of that set.
Unlike standard regular expressions, NDN regular expressions support only single components sets,
Unlike standard regular expressions, NDN regular expression only supports **Single Components Set**,
that is, you have to list all the set members one by one between the brackets. For example,
``^[<ndn><localhost>]`` matches any names starting with either ``ndn`` or ``localhost`` component.
``^[<ndn><localhost>]`` matches any names starting with either ``ndn"`` or ``localhost`` component.
When a name component set starts with a ``'^'``, the set becomes a **negation set**. It matches the
When a name component set starts with a ``'^'``, the set becomes a **Negation Set**. It matches the
complement of the contained name components. For example, ``^[^<ndn>]`` matches any non-empty name
that does *not* start with ``/ndn``.
that does not start with ``ndn`` component.
Some other types of sets, such as range sets, will be supported later.
Some other types of sets, such as Range Set, will be supported later.
Note that component sets may be repeated in the same way as component matchers.
Sub-pattern and Back Reference
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A section beginning ``(`` and ending ``)`` acts as a **marked sub-pattern**. Whatever matched the
A section beginning ``(`` and ending ``)`` acts as a marked sub-pattern. Whatever matched the
sub-pattern is split out in a separate field by the matching algorithm. For example
``^<A>(<>{2})<B>(<>)`` matches the name ``/A/C/D/B/E``, and the first sub-pattern captures ``C/D``.
Marked sub-patterns can be referred to by a **back-reference** of the form ``\N``, which references
one or more capturing groups. In the example above, a back reference ``\1\2`` extracts ``/C/D/E``
out of the name.
Marked sub-patterns can be referred to by a back-reference ``\N``, which references one or more
capturing groups. In the example above, a back reference ``\1\2`` extracts ``/C/D/E`` out of the
name.
Marked sub-patterns can also be repeated. The regex engine does not permanently substitute
back-references in a regular expression, but will use the last match saved into the back-reference.
+24 -37
View File
@@ -1,22 +1,22 @@
# ndn-cxx examples
ndn-cxx examples
================
By default, the examples in `examples/` folder are not built. To enable them, use
By default, examples in `examples/` folder are not built. To enable them, use
`--with-examples` configure option. For example:
./waf configure --with-examples
./waf
There are two ways to add new examples, depending on their complexity.
There are two ways to add new examples, depending on their complexity:
1. **Examples with a single translation unit**
1. Examples with a single translation unit
For simple examples that have a single translation unit, the `.cpp` file can be directly put
in the `examples/` folder and it will be automatically compiled on the next run of `./waf`.
The name of the compiled executable will be determined by the base name of the `.cpp` file.
For instance, `examples/foo.cpp` will be compiled into an executable named `foo` inside the
`build/examples` folder:
For simple examples that have a single translation unit, the `.cpp` file can be directly put
in `examples/` folder and it will be automatically compiled on the next run of `./waf`. Name
of the compiled binary will be determined by the base name of the `.cpp` file. For example,
`examples/foo.cpp` will be compiled into binary `foo` in `<build>/examples` folder:
echo 'int main() { return 0; }' > examples/foo.cpp
echo "int main() { return 0; }" > examples/foo.cpp
./waf
# ... Compiling examples/foo.cpp
# ... Linking build/examples/foo
@@ -24,23 +24,25 @@ There are two ways to add new examples, depending on their complexity.
# To run the example
./build/examples/foo
2. **Examples with multiple translation units**
2. Examples with multiple translation units
For more complex examples that contain multiple translation units, one can use
the following directory structure:
For more complex examples that contain multiple translation units, one can use
the following directory structure:
- Create a directory under the `examples/` folder (e.g., `examples/bar`). The name of this
directory will determine the name of the compiled executable (`build/examples/bar/bar`).
- Place any number of translation units (e.g., `examples/bar/a.cpp`, `examples/bar/b.cpp`,
...) in this directory. All `.cpp` files in this directory will be compiled and linked
together to produce the binary executable of the example. One of the .cpp files must
contain the `main()` function.
- Create a directory under `examples/` folder (e.g., `examples/bar`).
The name of this directory will determine the name of the compiled binary
(`<build>/examples/bar/bar`)
For example:
- Place any number of translation units (e.g., `examples/bar/a.cpp`, `examples/bar/b.cpp`,
...) in this directory. All `.cpp` files in this directory will be compiled and linked
together to produce the binary of the example. One of the .cpp files should contain
the `main()` function.
For example:
mkdir examples/bar
echo 'int bar(); int main() { return bar(); }' > examples/bar/a.cpp
echo 'int bar() { return 10; }' > examples/bar/b.cpp
echo "int bar(); int main() { return bar(); }" > examples/bar/a.cpp
echo "int bar() { return 10; } " > examples/bar/b.cpp
./waf
# ... Compiling examples/bar/a.cpp
# ... Compiling examples/bar/b.cpp
@@ -48,18 +50,3 @@ There are two ways to add new examples, depending on their complexity.
# To run the example
./build/examples/bar/bar
## Security configuration for example apps
In order for the ``consumer`` example app to be able to properly authenticate data packets
created by the ``producer`` app, you must configure the following parameters.
1. Generate example trust anchor:
ndnsec key-gen /example
ndnsec cert-dump -i /example > example-trust-anchor.cert
2. Create a key for the producer and sign it with the example trust anchor:
ndnsec key-gen /example/testApp
ndnsec sign-req /example/testApp | ndnsec cert-gen -s /example -i example | ndnsec cert-install -
+24 -14
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,12 +17,14 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/io_service.hpp>
#include <iostream>
// Enclosing code in ndn simplifies coding (can also use `using namespace ndn`)
@@ -33,6 +35,12 @@ namespace examples {
class ConsumerWithTimer
{
public:
ConsumerWithTimer()
: m_face(m_ioService) // Create face with io_service object
, m_scheduler(m_ioService)
{
}
void
run()
{
@@ -40,20 +48,21 @@ public:
interestName.appendVersion();
Interest interest(interestName);
interest.setCanBePrefix(false);
interest.setMustBeFresh(true);
interest.setInterestLifetime(2_s);
std::cout << "Sending Interest " << interest << std::endl;
m_face.expressInterest(interest,
std::bind(&ConsumerWithTimer::onData, this, _1, _2),
std::bind(&ConsumerWithTimer::onNack, this, _1, _2),
std::bind(&ConsumerWithTimer::onTimeout, this, _1));
bind(&ConsumerWithTimer::onData, this, _1, _2),
bind(&ConsumerWithTimer::onNack, this, _1, _2),
bind(&ConsumerWithTimer::onTimeout, this, _1));
// Schedule a new event
m_scheduler.schedule(3_s, [this] { delayedInterest(); });
// m_ioCtx.run() will block until all events finished or m_ioCtx.stop() is called
m_ioCtx.run();
// m_ioService.run() will block until all events finished or m_ioService.stop() is called
m_ioService.run();
// Alternatively, m_face.processEvents() can also be called.
// processEvents will block until the requested data received or timeout occurs.
@@ -89,21 +98,22 @@ private:
interestName.appendVersion();
Interest interest(interestName);
interest.setCanBePrefix(false);
interest.setMustBeFresh(true);
interest.setInterestLifetime(2_s);
std::cout << "Sending Interest " << interest << std::endl;
m_face.expressInterest(interest,
std::bind(&ConsumerWithTimer::onData, this, _1, _2),
std::bind(&ConsumerWithTimer::onNack, this, _1, _2),
std::bind(&ConsumerWithTimer::onTimeout, this, _1));
bind(&ConsumerWithTimer::onData, this, _1, _2),
bind(&ConsumerWithTimer::onNack, this, _1, _2),
bind(&ConsumerWithTimer::onTimeout, this, _1));
}
private:
// Explicitly create io_context object, which will be shared between Face and Scheduler
boost::asio::io_context m_ioCtx;
Face m_face{m_ioCtx};
Scheduler m_scheduler{m_ioCtx};
// Explicitly create io_service object, which will be shared between Face and Scheduler
boost::asio::io_service m_ioService;
Face m_face;
Scheduler m_scheduler;
};
} // namespace examples
+8 -20
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,10 +17,11 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/validator-config.hpp>
#include <iostream>
@@ -32,11 +33,6 @@ namespace examples {
class Consumer
{
public:
Consumer()
{
m_validator.load("trust-schema.conf");
}
void
run()
{
@@ -44,14 +40,15 @@ public:
interestName.appendVersion();
Interest interest(interestName);
interest.setCanBePrefix(false);
interest.setMustBeFresh(true);
interest.setInterestLifetime(6_s); // The default is 4 seconds
std::cout << "Sending Interest " << interest << std::endl;
m_face.expressInterest(interest,
std::bind(&Consumer::onData, this, _1, _2),
std::bind(&Consumer::onNack, this, _1, _2),
std::bind(&Consumer::onTimeout, this, _1));
bind(&Consumer::onData, this, _1, _2),
bind(&Consumer::onNack, this, _1, _2),
bind(&Consumer::onTimeout, this, _1));
// processEvents will block until the requested data is received or a timeout occurs
m_face.processEvents();
@@ -59,17 +56,9 @@ public:
private:
void
onData(const Interest&, const Data& data)
onData(const Interest&, const Data& data) const
{
std::cout << "Received Data " << data << std::endl;
m_validator.validate(data,
[] (const Data&) {
std::cout << "Data conforms to trust schema" << std::endl;
},
[] (const Data&, const security::ValidationError& error) {
std::cout << "Error authenticating data: " << error << std::endl;
});
}
void
@@ -86,7 +75,6 @@ private:
private:
Face m_face;
ValidatorConfig m_validator{m_face};
};
} // namespace examples
+13 -30
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,6 +17,8 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#include <ndn-cxx/face.hpp>
@@ -36,43 +38,25 @@ public:
void
run()
{
m_face.setInterestFilter("/example/testApp/randomData",
std::bind(&Producer::onInterest, this, _2),
m_face.setInterestFilter("/example/testApp",
bind(&Producer::onInterest, this, _1, _2),
nullptr, // RegisterPrefixSuccessCallback is optional
std::bind(&Producer::onRegisterFailed, this, _1, _2));
auto cert = m_keyChain.getPib().getDefaultIdentity().getDefaultKey().getDefaultCertificate();
m_certServeHandle = m_face.setInterestFilter(security::extractIdentityFromCertName(cert.getName()),
[this, cert] (auto&&...) {
m_face.put(cert);
},
std::bind(&Producer::onRegisterFailed, this, _1, _2));
bind(&Producer::onRegisterFailed, this, _1, _2));
m_face.processEvents();
}
private:
void
onInterest(const Interest& interest)
onInterest(const InterestFilter&, const Interest& interest)
{
std::cout << ">> I: " << interest << std::endl;
// Create Data packet
auto data = std::make_shared<Data>();
data->setName(interest.getName());
data->setFreshnessPeriod(10_s);
data->setContent("Hello, world!");
static const std::string content("Hello, world!");
// In order for the consumer application to be able to validate the packet, you need to setup
// the following keys:
// 1. Generate example trust anchor
//
// ndnsec key-gen /example
// ndnsec cert-dump -i /example > example-trust-anchor.cert
//
// 2. Create a key for the producer and sign it with the example trust anchor
//
// ndnsec key-gen /example/testApp
// ndnsec sign-req /example/testApp | ndnsec cert-gen -s /example -i example | ndnsec cert-install -
// Create Data packet
auto data = make_shared<Data>(interest.getName());
data->setFreshnessPeriod(10_s);
data->setContent(reinterpret_cast<const uint8_t*>(content.data()), content.size());
// Sign Data packet with default identity
m_keyChain.sign(*data);
@@ -90,14 +74,13 @@ private:
onRegisterFailed(const Name& prefix, const std::string& reason)
{
std::cerr << "ERROR: Failed to register prefix '" << prefix
<< "' with the local forwarder (" << reason << ")\n";
<< "' with the local forwarder (" << reason << ")" << std::endl;
m_face.shutdown();
}
private:
Face m_face;
KeyChain m_keyChain;
ScopedRegisteredPrefixHandle m_certServeHandle;
};
} // namespace examples
-34
View File
@@ -1,34 +0,0 @@
rule
{
id "Example rule"
for data
filter
{
type name
name /example/testApp
relation is-prefix-of
}
checker
{
type customized
sig-type ecdsa-sha256
key-locator
{
type name
hyper-relation
{
k-regex ^(<>*)<KEY><><>?<>?$
k-expand \\1
h-relation is-prefix-of
p-regex ^(<>*)<>*$
p-expand \\1
}
}
}
}
trust-anchor
{
type file
file-name "example-trust-anchor.cert"
}
+2 -2
View File
@@ -6,7 +6,7 @@ def build(bld):
# List all .cpp files (whole example in one .cpp)
for ex in bld.path.ant_glob('*.cpp'):
name = ex.change_ext('').path_from(bld.path.get_bld())
bld.program(name=f'example-{name}',
bld.program(name='example-%s' % name,
target=name,
source=[ex],
use='ndn-cxx',
@@ -15,7 +15,7 @@ def build(bld):
# List all directories (example can have multiple .cpp in the directory)
for subdir in bld.path.ant_glob('*', dir=True, src=False):
name = subdir.path_from(bld.path)
bld.program(name=f'example-{name}',
bld.program(name='example-%s' % name,
target=name,
source=subdir.ant_glob('**/*.cpp'),
use='ndn-cxx',
+84 -76
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 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,10 +20,19 @@
*/
#include "ndn-cxx/data.hpp"
#include "ndn-cxx/signature.hpp"
#include "ndn-cxx/util/sha256.hpp"
#include <iostream>
namespace ndn {
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Data>));
BOOST_CONCEPT_ASSERT((WireEncodable<Data>));
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Data>));
BOOST_CONCEPT_ASSERT((WireDecodable<Data>));
static_assert(std::is_base_of<tlv::Error, Data::Error>::value,
"Data::Error must inherit from tlv::Error");
Data::Data(const Name& name)
: m_name(name)
{
@@ -42,41 +51,40 @@ Data::wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly) const
// Name
// [MetaInfo]
// [Content]
// [ServiceClass]
// [TargetRate]
// SignatureInfo
// SignatureValue
// [ServiceClass]
// [TargetRate]
// (elements are encoded in reverse order)
size_t totalLength = 0;
// TargetRate
if (getTargetRate()) {
uint64_t targetRate = *getTargetRate();
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::TargetRate, targetRate);
// totalLength += encoder.prependByteArrayBlock(tlv::TargetRate, reinterpret_cast<uint8_t*>(&targetRate), sizeof(targetRate));
}
// ServiceClass
if (getServiceClass()) {
uint8_t serviceClass = *getServiceClass();
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::ServiceClass, serviceClass);
// totalLength += encoder.prependByteArrayBlock(tlv::ServiceClass, reinterpret_cast<uint8_t*>(&serviceClass), sizeof(serviceClass));
}
// SignatureValue
if (!wantUnsignedPortionOnly) {
if (!m_signatureInfo) {
NDN_THROW(Error("Requested wire format, but Data has not been signed"));
}
totalLength += prependBlock(encoder, m_signatureValue);
totalLength += encoder.prependBlock(m_signatureValue);
}
// SignatureInfo
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
if (hasContent()) {
totalLength += prependBlock(encoder, m_content);
totalLength += encoder.prependBlock(m_content);
}
// MetaInfo
@@ -99,12 +107,10 @@ template size_t
Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
const Block&
Data::wireEncode(EncodingBuffer& encoder, span<const uint8_t> signature) const
Data::wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const
{
size_t totalLength = encoder.size();
totalLength += encoder.appendVarNumber(tlv::SignatureValue);
totalLength += encoder.appendVarNumber(signature.size());
totalLength += encoder.appendBytes(signature);
totalLength += encoder.appendBlock(signatureValue);
encoder.prependVarNumber(totalLength);
encoder.prependVarNumber(tlv::Data);
@@ -142,10 +148,10 @@ Data::wireDecode(const Block& wire)
// Name
// [MetaInfo]
// [Content]
// SignatureInfo
// SignatureValue
// [ServiceClass]
// [TargetRate]
// SignatureInfo
// SignatureValue
auto element = m_wire.elements_begin();
if (element == m_wire.elements_end() || element->type() != tlv::Name) {
@@ -161,6 +167,7 @@ Data::wireDecode(const Block& wire)
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) {
@@ -178,35 +185,19 @@ Data::wireDecode(const Block& wire)
lastElement = 3;
break;
}
case tlv::SignatureInfo: {
if (lastElement >= 4) {
NDN_THROW(Error("SignatureInfo element is out of order"));
}
m_signatureInfo.wireDecode(*element);
lastElement = 4;
break;
}
case tlv::SignatureValue: {
if (lastElement >= 5) {
NDN_THROW(Error("SignatureValue element is out of order"));
}
m_signatureValue = *element;
lastElement = 5;
break;
}
case tlv::ServiceClass: {
if (lastElement >= 6) {
if (lastElement >= 4) {
break; // ServiceClass is non-critical, ignore out-of-order appearance
}
if (element->value_size() != 1) {
NDN_THROW(Error("ServiceClass element is malformed"));
}
m_serviceClass = *element->value();
lastElement = 6;
lastElement = 4;
break;
}
case tlv::TargetRate: {
if (lastElement >= 7) {
if (lastElement >= 5) {
break; // TargetRate is non-critical, ignore out-of-order appearance
}
uint64_t targetRate = 0;
@@ -215,9 +206,26 @@ Data::wireDecode(const Block& wire)
}
std::memcpy(&targetRate, element->value(), sizeof(targetRate));
m_targetRate = targetRate;
lastElement = 5;
break;
}
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())) {
@@ -245,7 +253,7 @@ Data::getFullName() const
NDN_THROW(Error("Cannot compute full name because Data has no wire encoding (not signed)"));
}
m_fullName = m_name;
m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire));
m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire.wire(), m_wire.size()));
}
return m_fullName;
@@ -295,17 +303,13 @@ Data::setContent(const Block& block)
}
Data&
Data::setContent(span<const uint8_t> value)
Data::setContent(const uint8_t* value, size_t length)
{
m_content = makeBinaryBlock(tlv::Content, value);
resetWire();
return *this;
}
if (value == nullptr && length != 0) {
NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
}
Data&
Data::setContent(std::string_view value)
{
m_content = makeStringBlock(tlv::Content, value);
m_content = makeBinaryBlock(tlv::Content, value, length);
resetWire();
return *this;
}
@@ -313,8 +317,8 @@ Data::setContent(std::string_view value)
Data&
Data::setContent(ConstBufferPtr value)
{
if (!value) {
NDN_THROW(std::invalid_argument("Content buffer cannot be null"));
if (value == nullptr) {
NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
}
m_content = Block(tlv::Content, std::move(value));
@@ -325,10 +329,23 @@ Data::setContent(ConstBufferPtr value)
Data&
Data::unsetContent()
{
if (m_content.isValid()) {
m_content = {};
resetWire();
}
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();
return *this;
}
@@ -340,19 +357,11 @@ Data::setSignatureInfo(const SignatureInfo& info)
return *this;
}
Data&
Data::setSignatureValue(span<const uint8_t> value)
{
m_signatureValue = makeBinaryBlock(tlv::SignatureValue, value);
resetWire();
return *this;
}
Data&
Data::setSignatureValue(ConstBufferPtr value)
{
if (!value) {
NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be null"));
if (value == nullptr) {
NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be nullptr"));
}
m_signatureValue = Block(tlv::SignatureValue, std::move(value));
@@ -368,14 +377,13 @@ Data::extractSignedRanges() const
wireEncode();
auto lastSignedIt = std::prev(m_wire.find(tlv::SignatureValue));
// Note: we assume that both iterators point to the same underlying buffer
bufs.emplace_back(m_wire.value_begin(), lastSignedIt->end());
bufs.emplace_back(m_wire.value(),
std::distance(m_wire.value_begin(), lastSignedIt->end()));
return bufs;
}
const Data&
Data::setServiceClass(std::optional<uint8_t> serviceClass) const
Data::setServiceClass(optional<uint8_t> serviceClass) const
{
if (m_serviceClass != serviceClass) {
m_serviceClass = serviceClass;
@@ -383,8 +391,9 @@ Data::setServiceClass(std::optional<uint8_t> serviceClass) const
}
return *this;
}
const Data&
Data::setTargetRate(std::optional<uint64_t> targetRate) const
Data::setTargetRate(optional<uint64_t> targetRate) const
{
if (m_targetRate != targetRate) {
m_targetRate = targetRate;
@@ -414,7 +423,7 @@ Data::setFreshnessPeriod(time::milliseconds freshnessPeriod)
}
Data&
Data::setFinalBlock(std::optional<name::Component> finalBlockId)
Data::setFinalBlock(optional<name::Component> finalBlockId)
{
if (finalBlockId != m_metaInfo.getFinalBlock()) {
m_metaInfo.setFinalBlock(std::move(finalBlockId));
@@ -450,4 +459,3 @@ operator<<(std::ostream& os, const Data& data)
}
} // namespace ndn
+106 -141
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 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,9 +31,10 @@
namespace ndn {
/**
* @brief Represents a %Data packet.
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/data.html
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>
{
@@ -61,55 +62,49 @@ public:
explicit
Data(const Block& wire);
/**
* @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&, span<const uint8_t>) const.
* @throw Error Signature is not present and @p 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
wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
/**
* @brief Finalize Data packet encoding with the specified signature.
* @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
* without SignatureValue and the outermost Type-Length of the %Data element.
* @param signature Raw signature bytes, without TLV Type and Length; this will become the
* TLV-VALUE of the SignatureValue element added to the packet.
/** @brief Finalize Data packet encoding with the specified SignatureValue
* @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
* 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 `wireEncode(encoder, true)`, e.g.:
* @code
* Data data;
* ...
* EncodingBuffer encoder;
* data.wireEncode(encoder, true);
* ...
* auto signature = create_signature_over_signed_portion(encoder.data(), encoder.size());
* data.wireEncode(encoder, signature);
* @endcode
* This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
* @code
* Data data;
* ...
* EncodingBuffer encoder;
* data.wireEncode(encoder, true);
* ...
* Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
* data.wireEncode(encoder, signatureValue)
* @endcode
*/
const Block&
wireEncode(EncodingBuffer& encoder, span<const uint8_t> signature) const;
wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
/**
* @brief Encode into a Block.
* @pre Data must be signed.
/** @brief Encode into a Block.
* @pre Data must be signed.
*/
const Block&
wireEncode() const;
/**
* @brief Decode from @p wire.
/** @brief Decode from @p wire.
*/
void
wireDecode(const Block& wire);
/**
* @brief Check if this instance has cached wire encoding.
/** @brief Check if this instance has cached wire encoding.
*/
bool
hasWire() const noexcept
@@ -117,17 +112,15 @@ public:
return m_wire.hasWire();
}
/**
* @brief Get the full name (including implicit digest).
* @pre hasWire() == true, i.e., wireEncode() must have been called.
* @throw Error Data has no wire encoding
/** @brief Get full name including implicit digest
* @pre hasWire() == true; i.e. wireEncode() must have been called
* @throw Error Data has no wire encoding
*/
const Name&
getFullName() const;
public: // Data fields
/**
* @brief Get the %Data name.
/** @brief Get name
*/
const Name&
getName() const noexcept
@@ -135,15 +128,13 @@ public: // Data fields
return m_name;
}
/**
* @brief Set the %Data name.
* @return A reference to this Data, to allow chaining.
/** @brief Set name
* @return a reference to this Data, to allow chaining
*/
Data&
setName(const Name& name);
/**
* @brief Get the `MetaInfo` element.
/** @brief Get MetaInfo
*/
const MetaInfo&
getMetaInfo() const noexcept
@@ -151,15 +142,14 @@ public: // Data fields
return m_metaInfo;
}
/**
* @brief Set the `MetaInfo` element.
* @return A reference to this Data, to allow chaining.
/** @brief Set MetaInfo
* @return a reference to this Data, to allow chaining
*/
Data&
setMetaInfo(const MetaInfo& metaInfo);
/**
* @brief Return whether this Data has a `Content` element.
* @brief Return whether this Data has a Content element
*/
bool
hasContent() const noexcept
@@ -168,17 +158,15 @@ public: // Data fields
}
/**
* @brief Get the `Content` element.
* @brief Get the Content element
*
* 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_bytes(), or
* - Block::value() and Block::value_size(), or
* - Block::value_begin() and Block::value_end().
* Block::value() / Block::value_size() or Block::value_begin() / Block::value_end().
*
* @sa hasContent()
* @sa Block::value_bytes(), Block::blockFromValue(), Block::parse()
* @sa Block::blockFromValue(), Block::parse()
*/
const Block&
getContent() const noexcept
@@ -187,9 +175,9 @@ public: // Data fields
}
/**
* @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.
* @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.
@@ -198,42 +186,46 @@ public: // Data fields
setContent(const Block& block);
/**
* @brief Set `Content` by copying from a contiguous sequence of bytes.
* @param value buffer with the TLV-VALUE of the content
* @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(span<const uint8_t> value);
setContent(const uint8_t* value, size_t length);
/**
* @brief Set `Content` by copying from a string.
* @param value string with the TLV-VALUE of the content
* @return A reference to this Data, to allow chaining.
*/
Data&
setContent(std::string_view value);
/**
* @brief Set `Content` from a shared buffer.
* @param value buffer with the TLV-VALUE of the content; must not be null
* @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);
Data&
setContent(std::nullptr_t) = delete;
/**
* @brief Remove the `Content` element.
* @return A reference to this Data, to allow chaining.
* @brief Remove the Content element
* @return a reference to this Data, to allow chaining
* @post hasContent() == false
*/
Data&
unsetContent();
/**
* @brief Get the `SignatureInfo` element.
/** @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 Get SignatureInfo
*/
const SignatureInfo&
getSignatureInfo() const noexcept
@@ -241,21 +233,19 @@ public: // Data fields
return m_signatureInfo;
}
/**
* @brief Set the `SignatureInfo` element.
/** @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().
* 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
* @return a reference to this Data, to allow chaining
* @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign().
* @sa SigningInfo
*/
Data&
setSignatureInfo(const SignatureInfo& info);
/**
* @brief Get the `SignatureValue` element.
/** @brief Get SignatureValue
*/
const Block&
getSignatureValue() const noexcept
@@ -263,58 +253,40 @@ public: // Data fields
return m_signatureValue;
}
/**
* @brief Set `SignatureValue` by copying from a contiguous sequence of bytes.
* @param value buffer from which the TLV-VALUE of the SignatureValue will be copied
* @return A reference to this Data, to allow chaining.
/** @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.
* This is a low-level function that should not normally be called directly by applications.
* Instead, use KeyChain::sign() to sign the packet.
*
* @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
*/
Data&
setSignatureValue(span<const uint8_t> value);
/**
* @brief Set `SignatureValue` from a shared buffer.
* @param value buffer containing the TLV-VALUE of the SignatureValue; must not be null
* @return A reference to this Data, to allow chaining.
*
* This is a low-level function that should not normally be called directly by applications.
* Instead, use KeyChain::sign() to sign the packet.
*
* @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
* @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);
Data&
setSignatureValue(std::nullptr_t) = delete;
/**
* @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.
/** @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.
*/
[[nodiscard]] InputBuffers
InputBuffers
extractSignedRanges() const;
std::optional<uint8_t>
optional<uint8_t>
getServiceClass() const noexcept
{
return m_serviceClass;
}
const Data&
setServiceClass(std::optional<uint8_t> serviceClass) const;
std::optional<uint64_t>
setServiceClass(optional<uint8_t> serviceClass) const;
optional<uint64_t>
getTargetRate() const noexcept
{
return m_targetRate;
}
const Data&
setTargetRate(std::optional<uint64_t> targetRate) const;
setTargetRate(optional<uint64_t> targetRate) const;
public: // MetaInfo fields
uint32_t
@@ -335,19 +307,18 @@ public: // MetaInfo fields
Data&
setFreshnessPeriod(time::milliseconds freshnessPeriod);
const std::optional<name::Component>&
const optional<name::Component>&
getFinalBlock() const
{
return m_metaInfo.getFinalBlock();
}
Data&
setFinalBlock(std::optional<name::Component> finalBlockId);
setFinalBlock(optional<name::Component> finalBlockId);
public: // SignatureInfo fields
/**
* @brief Get the `SignatureType`.
* @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid.
/** @brief Get SignatureType
* @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid
*/
int32_t
getSignatureType() const noexcept
@@ -355,22 +326,17 @@ public: // SignatureInfo fields
return m_signatureInfo.getSignatureType();
}
/**
* @brief Get the `KeyLocator` element.
/** @brief Get KeyLocator
*/
std::optional<KeyLocator>
optional<KeyLocator>
getKeyLocator() const noexcept
{
if (m_signatureInfo.hasKeyLocator()) {
return m_signatureInfo.getKeyLocator();
}
return std::nullopt;
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.
/** @brief Clear wire encoding and cached FullName
* @note This does not clear the SignatureValue.
*/
void
resetWire();
@@ -382,11 +348,11 @@ private:
SignatureInfo m_signatureInfo;
Block m_signatureValue;
// Add for QSCCP
mutable std::optional<uint8_t> m_serviceClass;
mutable std::optional<uint64_t> m_targetRate;
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
mutable Name m_fullName; ///< cached FullName computed from m_wire
};
#ifndef DOXYGEN
@@ -412,4 +378,3 @@ operator!=(const Data& lhs, const Data& rhs)
} // namespace ndn
#endif // NDN_CXX_DATA_HPP
+231
View File
@@ -0,0 +1,231 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* 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.
*/
#include "ndn-cxx/delegation-list.hpp"
#include "ndn-cxx/util/ostream-joiner.hpp"
namespace ndn {
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<DelegationList>));
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<DelegationList>));
BOOST_CONCEPT_ASSERT((WireDecodable<DelegationList>));
DelegationList::DelegationList()
: m_isSorted(true)
{
}
DelegationList::DelegationList(std::initializer_list<Delegation> dels)
: m_isSorted(true)
{
for (const Delegation& del : dels) {
this->insert(del, INS_REPLACE);
}
}
DelegationList::DelegationList(const Block& block, bool wantSort)
{
this->wireDecode(block, wantSort);
}
bool
DelegationList::isValidTlvType(uint32_t type)
{
switch (type) {
case tlv::Content:
case tlv::ForwardingHint:
return true;
default:
return false;
}
}
template<encoding::Tag TAG>
size_t
DelegationList::wireEncode(EncodingImpl<TAG>& encoder, uint32_t type) const
{
if (!isValidTlvType(type)) {
NDN_THROW(std::invalid_argument("Unexpected TLV-TYPE " + to_string(type) +
" while encoding DelegationList"));
}
if (this->size() == 0) {
NDN_THROW(Error("Empty DelegationList"));
}
// LinkContent ::= (type) TLV-LENGTH
// Delegation+
// Delegation ::= LINK-DELEGATION-TYPE TLV-LENGTH
// Preference
// Name
// Preference ::= LINK-PREFERENCE-TYPE TLV-LENGTH
// nonNegativeInteger
size_t totalLen = 0;
for (auto i = m_dels.rbegin(); i != m_dels.rend(); ++i) {
size_t delLen = 0;
delLen += i->name.wireEncode(encoder);
delLen += prependNonNegativeIntegerBlock(encoder, tlv::LinkPreference, i->preference);
delLen += encoder.prependVarNumber(delLen);
delLen += encoder.prependVarNumber(tlv::LinkDelegation);
totalLen += delLen;
}
totalLen += encoder.prependVarNumber(totalLen);
totalLen += encoder.prependVarNumber(type);
return totalLen;
}
template size_t
DelegationList::wireEncode<encoding::EncoderTag>(EncodingBuffer&, uint32_t) const;
template size_t
DelegationList::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, uint32_t) const;
void
DelegationList::wireDecode(const Block& block, bool wantSort)
{
if (!isValidTlvType(block.type())) {
NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(block.type()) + " while decoding DelegationList"));
}
m_isSorted = wantSort;
m_dels.clear();
block.parse();
for (const auto& del : block.elements()) {
if (del.type() != tlv::LinkDelegation) {
NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(del.type()) + " while decoding Delegation"));
}
del.parse();
auto val = del.elements_begin();
if (val == del.elements_end() || val->type() != tlv::LinkPreference) {
NDN_THROW(Error("Missing Preference field in Delegation"));
}
uint64_t preference = 0;
try {
preference = readNonNegativeInteger(*val);
}
catch (const tlv::Error&) {
NDN_THROW_NESTED(Error("Invalid Preference field in Delegation"));
}
++val;
if (val == del.elements_end() || val->type() != tlv::Name) {
NDN_THROW(Error("Missing Name field in Delegation"));
}
Name name;
try {
name.wireDecode(*val);
}
catch (const tlv::Error&) {
NDN_THROW_NESTED(Error("Invalid Name field in Delegation"));
}
this->insertImpl(preference, name);
}
if (this->size() == 0) {
NDN_THROW(Error("Empty DelegationList"));
}
}
void
DelegationList::sort()
{
if (m_isSorted) {
return;
}
std::vector<Delegation> dels;
dels.swap(m_dels);
m_isSorted = true;
for (const Delegation& del : dels) {
this->insertImpl(del.preference, del.name);
}
}
bool
DelegationList::insert(uint64_t preference, const Name& name,
InsertConflictResolution onConflict)
{
switch (onConflict) {
case INS_REPLACE:
this->eraseImpl(nullopt, name);
this->insertImpl(preference, name);
return true;
case INS_APPEND:
this->insertImpl(preference, name);
return true;
case INS_SKIP:
if (!std::any_of(m_dels.begin(), m_dels.end(),
[name] (const Delegation& del) { return del.name == name; })) {
this->insertImpl(preference, name);
return true;
}
return false;
}
NDN_THROW(std::invalid_argument("Unknown InsertConflictResolution"));
}
void
DelegationList::insertImpl(uint64_t preference, const Name& name)
{
if (!m_isSorted) {
m_dels.push_back({preference, name});
return;
}
Delegation del{preference, name};
auto pos = std::upper_bound(m_dels.begin(), m_dels.end(), del);
m_dels.insert(pos, del);
}
size_t
DelegationList::eraseImpl(optional<uint64_t> preference, const Name& name)
{
size_t nErased = 0;
for (auto i = m_dels.begin(); i != m_dels.end();) {
if ((!preference || i->preference == *preference) &&
i->name == name) {
++nErased;
i = m_dels.erase(i);
}
else {
++i;
}
}
return nErased;
}
std::ostream&
operator<<(std::ostream& os, const DelegationList& dl)
{
os << '[';
std::copy(dl.begin(), dl.end(), make_ostream_joiner(os, ','));
return os << ']';
}
} // namespace ndn
+264
View File
@@ -0,0 +1,264 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* 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.
*/
#ifndef NDN_DELEGATION_LIST_HPP
#define NDN_DELEGATION_LIST_HPP
#include "ndn-cxx/delegation.hpp"
#include <initializer_list>
namespace ndn {
/** \brief represents a list of Delegations
* \sa https://named-data.net/doc/ndn-tlv/link.html
*
* Delegations are stored in an std::vector, under the assumption that there is usually only a
* small number of Delegations, so that copying is acceptable when they are modified.
*/
class DelegationList
{
public:
class Error : public tlv::Error
{
public:
using tlv::Error::Error;
};
/** \brief construct an empty DelegationList
*/
DelegationList();
/** \brief construct a sorted DelegationList with specified delegations
*
* This is equivalent to inserting each delegation into an empty DelegationList with INS_REPLACE
* conflict resolution.
*/
DelegationList(std::initializer_list<Delegation> dels);
/** \brief decode a DelegationList
* \sa wireDecode
*/
explicit
DelegationList(const Block& block, bool wantSort = true);
/** \brief encode into wire format
* \param encoder either an EncodingBuffer or an EncodingEstimator
* \param type TLV-TYPE number, either Content (for \p Link) or ForwardingHint
* \throw std::invalid_argument \p type is invalid
* \throw Error there is no Delegation
*/
template<encoding::Tag TAG>
size_t
wireEncode(EncodingImpl<TAG>& encoder, uint32_t type = tlv::ForwardingHint) const;
/** \brief decode a DelegationList
* \param block either a Content block (from \p Link) or a ForwardingHint block
* \param wantSort if true, delegations are sorted
* \throw Error the block cannot be parsed as a list of Delegations
*/
void
wireDecode(const Block& block, bool wantSort = true);
bool
isSorted() const noexcept
{
return m_isSorted;
}
using const_iterator = std::vector<Delegation>::const_iterator;
const_iterator
begin() const noexcept
{
return m_dels.begin();
}
const_iterator
end() const noexcept
{
return m_dels.end();
}
NDN_CXX_NODISCARD bool
empty() const noexcept
{
return m_dels.empty();
}
size_t
size() const noexcept
{
return m_dels.size();
}
/** \brief get the i-th delegation
* \pre i < size()
*/
const Delegation&
operator[](size_t i) const
{
BOOST_ASSERT(i < size());
return m_dels[i];
}
/** \brief get the i-th delegation
* \throw std::out_of_range i >= size()
*/
const Delegation&
at(size_t i) const
{
return m_dels.at(i);
}
public: // modifiers
/** \brief sort the delegation list
* \post isSorted() == true
* \post Delegations are sorted in increasing preference order.
*
* A DelegationList can be constructed as sorted or unsorted. In most cases, it is recommended
* to use a sorted DelegationList. An unsorted DelegationList is useful for extracting the i-th
* delegation from a received ForwardingHint or Link object.
*
* This method turns an unsorted DelegationList into a sorted DelegationList.
* If access to unsorted DelegationList is not needed, it is more efficient to sort the
* DelegationList in wireDecode.
*/
void
sort();
/** \brief what to do when inserting a duplicate name
*/
enum InsertConflictResolution {
/** \brief existing delegation(s) with the same name are replaced with the new delegation
*/
INS_REPLACE,
/** \brief multiple delegations with the same name are kept in the DelegationList
* \note This is NOT RECOMMENDED by Link specification.
*/
INS_APPEND,
/** \brief new delegation is not inserted if an existing delegation has the same name
*/
INS_SKIP
};
/** \brief insert Delegation
* \return whether inserted
*/
bool
insert(uint64_t preference, const Name& name,
InsertConflictResolution onConflict = INS_REPLACE);
/** \brief insert Delegation
* \return whether inserted
*/
bool
insert(const Delegation& del, InsertConflictResolution onConflict = INS_REPLACE)
{
return this->insert(del.preference, del.name, onConflict);
}
/** \brief delete Delegation(s) with specified preference and name
* \return count of erased Delegation(s)
*/
size_t
erase(uint64_t preference, const Name& name)
{
return this->eraseImpl(preference, name);
}
/** \brief delete Delegation(s) with matching preference and name
* \return count of erased Delegation(s)
*/
size_t
erase(const Delegation& del)
{
return this->eraseImpl(del.preference, del.name);
}
/** \brief erase Delegation(s) with specified name
* \return count of erased Delegation(s)
*/
size_t
erase(const Name& name)
{
return this->eraseImpl(nullopt, name);
}
private:
static bool
isValidTlvType(uint32_t type);
void
insertImpl(uint64_t preference, const Name& name);
size_t
eraseImpl(optional<uint64_t> preference, const Name& name);
private: // non-member operators
// NOTE: the following "hidden friend" operators are available via
// argument-dependent lookup only and must be defined inline.
/** \brief Compare whether two DelegationLists are equal.
* \note Order matters! If two DelegationLists contain the same Delegations but at least one is
* unsorted, they may compare unequal if the Delegations appear in different order.
*/
friend bool
operator==(const DelegationList& lhs, const DelegationList& rhs)
{
return lhs.m_dels == rhs.m_dels;
}
friend bool
operator!=(const DelegationList& lhs, const DelegationList& rhs)
{
return lhs.m_dels != rhs.m_dels;
}
private:
bool m_isSorted;
/** \brief delegation container; its contents are sorted when \p m_isSorted is true
* \note This container is a member field rather than a base class, in order to ensure contents
* are sorted when \p m_isSorted is true.
* \note A vector is chosen instead of a std::set, so that the container can be unsorted when
* \p m_isSorted is false. This container is expected to have less than seven items, and
* therefore the overhead of moving items during insertion and deletion is small.
*/
std::vector<Delegation> m_dels;
};
#ifndef DOXYGEN
extern template size_t
DelegationList::wireEncode<encoding::EncoderTag>(EncodingBuffer&, uint32_t) const;
extern template size_t
DelegationList::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, uint32_t) const;
#endif
std::ostream&
operator<<(std::ostream& os, const DelegationList& dl);
} // namespace ndn
#endif // NDN_DELEGATION_LIST_HPP
+89
View File
@@ -0,0 +1,89 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* 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.
*/
#ifndef NDN_DELEGATION_HPP
#define NDN_DELEGATION_HPP
#include "ndn-cxx/name.hpp"
namespace ndn {
/** \brief Represents a %Delegation.
* \sa https://named-data.net/doc/NDN-packet-spec/0.3/link.html
*/
class Delegation
{
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 Delegation& lhs, const Delegation& rhs)
{
return !(lhs != rhs);
}
friend bool
operator!=(const Delegation& lhs, const Delegation& rhs)
{
return lhs.preference != rhs.preference ||
lhs.name != rhs.name;
}
friend bool
operator<(const Delegation& lhs, const Delegation& rhs)
{
return std::tie(lhs.preference, lhs.name) <
std::tie(rhs.preference, rhs.name);
}
friend bool
operator<=(const Delegation& lhs, const Delegation& rhs)
{
return !(rhs < lhs);
}
friend bool
operator>(const Delegation& lhs, const Delegation& rhs)
{
return rhs < lhs;
}
friend bool
operator>=(const Delegation& lhs, const Delegation& rhs)
{
return !(lhs < rhs);
}
friend std::ostream&
operator<<(std::ostream& os, const Delegation& d)
{
return os << d.name << '(' << d.preference << ')';
}
public:
uint64_t preference;
Name name;
};
} // namespace ndn
#endif // NDN_DELEGATION_HPP
+17 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,11 +19,22 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_DETAIL_ASIO_FWD_HPP
#define NDN_CXX_DETAIL_ASIO_FWD_HPP
#ifndef NDN_DETAIL_ASIO_FWD_HPP
#define NDN_DETAIL_ASIO_FWD_HPP
namespace boost::asio {
#include <boost/version.hpp>
namespace boost {
namespace asio {
#if BOOST_VERSION >= 106600
class io_context;
} // namespace boost::asio
using io_service = io_context;
#else
class io_service;
#endif // BOOST_VERSION >= 106600
#endif // NDN_CXX_DETAIL_ASIO_FWD_HPP
} // namespace asio
} // namespace boost
#endif // NDN_DETAIL_ASIO_FWD_HPP
+5 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -21,7 +21,8 @@
#include "ndn-cxx/detail/cancel-handle.hpp"
namespace ndn::detail {
namespace ndn {
namespace detail {
void
CancelHandle::cancel() const
@@ -32,4 +33,5 @@ CancelHandle::cancel() const
}
}
} // namespace ndn::detail
} // namespace detail
} // namespace ndn
+11 -14
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,18 +19,15 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_DETAIL_CANCEL_HANDLE_HPP
#define NDN_CXX_DETAIL_CANCEL_HANDLE_HPP
#ifndef NDN_DETAIL_CANCEL_HANDLE_HPP
#define NDN_DETAIL_CANCEL_HANDLE_HPP
#include "ndn-cxx/detail/common.hpp"
/**
* \brief Contains implementation details that are not part of the ndn-cxx public API.
*/
namespace ndn::detail {
namespace ndn {
namespace detail {
/**
* \brief Handle to cancel an operation.
/** \brief Handle to cancel an operation.
*/
class CancelHandle
{
@@ -55,13 +52,12 @@ private:
inline
CancelHandle::CancelHandle() noexcept = default;
/**
* \brief Cancels an operation automatically upon destruction.
/** \brief Cancels an operation automatically upon destruction.
*/
template<typename HandleT>
class ScopedCancelHandle
{
static_assert(std::is_convertible_v<HandleT*, CancelHandle*>,
static_assert(std::is_convertible<HandleT*, CancelHandle*>::value,
"HandleT must publicly derive from CancelHandle");
public:
@@ -137,6 +133,7 @@ private:
template<typename T>
ScopedCancelHandle<T>::ScopedCancelHandle() noexcept = default;
} // namespace ndn::detail
} // namespace detail
} // namespace ndn
#endif // NDN_CXX_DETAIL_CANCEL_HANDLE_HPP
#endif // NDN_DETAIL_CANCEL_HANDLE_HPP
+8 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,8 +19,8 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_DETAIL_CF_RELEASER_OSX_HPP
#define NDN_CXX_DETAIL_CF_RELEASER_OSX_HPP
#ifndef NDN_DETAIL_CF_RELEASER_OSX_HPP
#define NDN_DETAIL_CF_RELEASER_OSX_HPP
#include "ndn-cxx/detail/common.hpp"
@@ -30,7 +30,8 @@
#include <CoreFoundation/CoreFoundation.h>
namespace ndn::detail {
namespace ndn {
namespace detail {
/**
* @brief Helper class to wrap CoreFoundation object pointers
@@ -144,6 +145,7 @@ private:
T m_typeRef;
};
} // namespace ndn::detail
} // namespace detail
} // namespace ndn
#endif // NDN_CXX_DETAIL_CF_RELEASER_OSX_HPP
#endif // NDN_DETAIL_CF_RELEASER_OSX_HPP
+7 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -21,7 +21,9 @@
#include "ndn-cxx/detail/cf-string-osx.hpp"
namespace ndn::detail::cfstring {
namespace ndn {
namespace detail {
namespace cfstring {
CFReleaser<CFStringRef>
fromBuffer(const uint8_t* buf, size_t buflen)
@@ -64,4 +66,6 @@ toStdString(CFStringRef cfStr)
return str;
}
} // namespace ndn::detail::cfstring
} // namespace cfstring
} // namespace detail
} // namespace ndn
+10 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,8 +19,8 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_DETAIL_CF_STRING_OSX_HPP
#define NDN_CXX_DETAIL_CF_STRING_OSX_HPP
#ifndef NDN_DETAIL_CF_STRING_OSX_HPP
#define NDN_DETAIL_CF_STRING_OSX_HPP
#include "ndn-cxx/detail/common.hpp"
@@ -36,7 +36,9 @@
* This file contains utilities to deal with Apple Core Foundation's CFString and related types.
*/
namespace ndn::detail::cfstring {
namespace ndn {
namespace detail {
namespace cfstring {
/**
* @brief Create a CFString by copying bytes from a raw buffer
@@ -59,6 +61,8 @@ fromStdString(const std::string& str);
std::string
toStdString(CFStringRef cfStr);
} // namespace ndn::detail::cfstring
} // namespace cfstring
} // namespace detail
} // namespace ndn
#endif // NDN_CXX_DETAIL_CF_STRING_OSX_HPP
#endif // NDN_DETAIL_CF_STRING_OSX_HPP
+19 -14
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 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).
*
@@ -25,14 +25,14 @@
* Aliases imported in this file MUST NOT be used outside of ndn-cxx.
*/
#ifndef NDN_CXX_DETAIL_COMMON_HPP
#define NDN_CXX_DETAIL_COMMON_HPP
#ifndef NDN_DETAIL_COMMON_HPP
#define NDN_DETAIL_COMMON_HPP
#include "ndn-cxx/detail/config.hpp"
// require C++17
#if __cplusplus < 201703L
#error "ndn-cxx applications must be compiled using the C++17 standard (-std=c++17)"
// require C++14
#if __cplusplus < 201402L
#error "ndn-cxx applications must be compiled using the C++14 standard (-std=c++14)"
#endif
// ndn-cxx specific macros declared in this and other headers must have NDN_CXX_ prefix
@@ -49,14 +49,15 @@
#define NDN_CXX_PROTECTED_WITH_TESTS_ELSE_PRIVATE private
#endif
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iosfwd>
#include <limits>
#include <memory>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
@@ -68,19 +69,23 @@ using std::weak_ptr;
using std::make_shared;
using std::make_unique;
using std::to_string;
using std::static_pointer_cast;
using std::dynamic_pointer_cast;
using std::const_pointer_cast;
using std::function;
using std::bind;
using std::ref;
using std::cref;
using namespace std::string_literals;
using namespace std::string_view_literals;
} // namespace ndn
using namespace std::placeholders;
#include <boost/version.hpp>
/// \cond
// Bug 2109 workaround
#if BOOST_VERSION < 107600
#define BOOST_BIND_NO_PLACEHOLDERS
#include <boost/is_placeholder.hpp>
namespace boost {
@@ -103,10 +108,10 @@ NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER(8)
NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER(9)
#undef NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER
} // namespace boost
#endif // BOOST_VERSION < 107600
/// \endcond
#include <boost/assert.hpp>
#include <boost/concept_check.hpp>
#include <boost/core/noncopyable.hpp>
namespace ndn {
@@ -116,4 +121,4 @@ using boost::noncopyable;
#include "ndn-cxx/util/backports.hpp"
#include "ndn-cxx/util/exception.hpp"
#endif // NDN_CXX_DETAIL_COMMON_HPP
#endif // NDN_DETAIL_COMMON_HPP
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,24 +19,24 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_DETAIL_PACKET_BASE_HPP
#define NDN_CXX_DETAIL_PACKET_BASE_HPP
#ifndef NDN_DETAIL_PACKET_BASE_HPP
#define NDN_DETAIL_PACKET_BASE_HPP
#include "ndn-cxx/detail/tag-host.hpp"
namespace ndn {
/** \brief Base class to allow simple management of packet tags.
/** \brief base class to allow simple management of packet tags
*/
class PacketBase : public TagHost
{
public:
/** \brief Get the value of the CongestionMark tag.
/** \brief get the value of the CongestionMark tag
*/
uint64_t
getCongestionMark() const;
/** \brief Set the CongestionMark tag to the specified value.
/** \brief set the CongestionMark tag to the specified value
*/
void
setCongestionMark(uint64_t mark);
@@ -44,4 +44,4 @@ public:
} // namespace ndn
#endif // NDN_CXX_DETAIL_PACKET_BASE_HPP
#endif // NDN_DETAIL_PACKET_BASE_HPP
+19 -23
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,8 +19,8 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_DETAIL_TAG_HOST_HPP
#define NDN_CXX_DETAIL_TAG_HOST_HPP
#ifndef NDN_DETAIL_TAG_HOST_HPP
#define NDN_DETAIL_TAG_HOST_HPP
#include "ndn-cxx/detail/common.hpp"
#include "ndn-cxx/tag.hpp"
@@ -29,34 +29,29 @@
namespace ndn {
/**
* \brief Base class to store tag information, e.g., inside Interest and Data packets.
/** \brief Base class to store tag information (e.g., inside Interest and Data packets)
*/
class TagHost
{
public:
/**
* \brief Get a tag item.
* \tparam T type of the tag, which must be a subclass of ndn::Tag
* \retval nullptr if no Tag of type T is stored
/** \brief get a tag item
* \tparam T type of the tag, which must be a subclass of ndn::Tag
* \retval nullptr if no Tag of type T is stored
*/
template<typename T>
shared_ptr<T>
getTag() const;
/**
* \brief Set (add or replace) a tag item.
* \tparam T type of the tag, which must be a subclass of ndn::Tag
* \note Tag can be set even on a const tag host instance
/** \brief set a tag item
* \tparam T type of the tag, which must be a subclass of ndn::Tag
* \note Tag can be set even on a const tag host instance
*/
template<typename T>
void
setTag(shared_ptr<T> tag) const;
/**
* \brief Remove a tag item.
* \tparam T type of the tag, which must be a subclass of ndn::Tag
* \note Tag can be removed even on a const tag host instance
/** \brief remove tag item
* \note Tag can be removed even on a const tag host instance
*/
template<typename T>
void
@@ -70,19 +65,20 @@ template<typename T>
shared_ptr<T>
TagHost::getTag() const
{
static_assert(std::is_convertible_v<T*, Tag*>, "T must inherit from ndn::Tag");
static_assert(std::is_base_of<Tag, T>::value, "T must inherit from Tag");
if (auto it = m_tags.find(T::getTypeId()); it != m_tags.end()) {
return std::static_pointer_cast<T>(it->second);
auto it = m_tags.find(T::getTypeId());
if (it == m_tags.end()) {
return nullptr;
}
return nullptr;
return static_pointer_cast<T>(it->second);
}
template<typename T>
void
TagHost::setTag(shared_ptr<T> tag) const
{
static_assert(std::is_convertible_v<T*, Tag*>, "T must inherit from ndn::Tag");
static_assert(std::is_base_of<Tag, T>::value, "T must inherit from Tag");
if (tag == nullptr) {
m_tags.erase(T::getTypeId());
@@ -101,4 +97,4 @@ TagHost::removeTag() const
} // namespace ndn
#endif // NDN_CXX_DETAIL_TAG_HOST_HPP
#endif // NDN_DETAIL_TAG_HOST_HPP
+87 -98
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -23,37 +23,10 @@
#include <boost/endian/conversion.hpp>
namespace ndn::encoding {
namespace ndn {
namespace encoding {
// ---- empty ----
template<Tag TAG>
size_t
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
{
size_t length = encoder.prependVarNumber(0);
length += encoder.prependVarNumber(type);
return length;
}
template size_t
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
template size_t
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
Block
makeEmptyBlock(uint32_t type)
{
EncodingEstimator estimator;
size_t totalLength = prependEmptyBlock(estimator, type);
EncodingBuffer encoder(totalLength, 0);
prependEmptyBlock(encoder, type);
return encoder.block();
}
namespace endian = boost::endian;
// ---- non-negative integer ----
@@ -61,11 +34,12 @@ template<Tag TAG>
size_t
prependNonNegativeIntegerBlock(EncodingImpl<TAG>& encoder, uint32_t type, uint64_t value)
{
size_t length = encoder.prependNonNegativeInteger(value);
length += encoder.prependVarNumber(length);
length += encoder.prependVarNumber(type);
size_t valueLength = encoder.prependNonNegativeInteger(value);
size_t totalLength = valueLength;
totalLength += encoder.prependVarNumber(valueLength);
totalLength += encoder.prependVarNumber(type);
return length;
return totalLength;
}
template size_t
@@ -93,6 +67,63 @@ readNonNegativeInteger(const Block& block)
return tlv::readNonNegativeInteger(block.value_size(), begin, block.value_end());
}
// ---- empty ----
template<Tag TAG>
size_t
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
{
size_t totalLength = encoder.prependVarNumber(0);
totalLength += encoder.prependVarNumber(type);
return totalLength;
}
template size_t
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
template size_t
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
Block
makeEmptyBlock(uint32_t type)
{
EncodingEstimator estimator;
size_t totalLength = prependEmptyBlock(estimator, type);
EncodingBuffer encoder(totalLength, 0);
prependEmptyBlock(encoder, type);
return encoder.block();
}
// ---- string ----
template<Tag TAG>
size_t
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value)
{
return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(value.data()), value.size());
}
template size_t
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
template size_t
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
Block
makeStringBlock(uint32_t type, const std::string& value)
{
return makeBinaryBlock(type, value.data(), value.size());
}
std::string
readString(const Block& block)
{
return std::string(reinterpret_cast<const char*>(block.value()), block.value_size());
}
// ---- double ----
static_assert(std::numeric_limits<double>::is_iec559, "This code requires IEEE-754 doubles");
@@ -103,8 +134,8 @@ prependDoubleBlock(EncodingImpl<TAG>& encoder, uint32_t type, double value)
{
uint64_t temp = 0;
std::memcpy(&temp, &value, 8);
boost::endian::native_to_big_inplace(temp);
return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(&temp), 8});
endian::native_to_big_inplace(temp);
return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(&temp), 8);
}
template size_t
@@ -131,80 +162,38 @@ readDouble(const Block& block)
if (block.value_size() != 8) {
NDN_THROW(tlv::Error("Invalid length for double (must be 8)"));
}
return boost::endian::endian_load<double, 8, boost::endian::order::big>(block.value());
#if BOOST_VERSION >= 107100
return endian::endian_load<double, 8, endian::order::big>(block.value());
#else
uint64_t temp = 0;
std::memcpy(&temp, block.value(), 8);
endian::big_to_native_inplace(temp);
double d = 0;
std::memcpy(&d, &temp, 8);
return d;
#endif
}
// ---- binary ----
template<Tag TAG>
size_t
prependBinaryBlock(EncodingImpl<TAG>& encoder, uint32_t type, span<const uint8_t> value)
{
size_t length = encoder.prependBytes(value);
length += encoder.prependVarNumber(length);
length += encoder.prependVarNumber(type);
return length;
}
template size_t
prependBinaryBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, span<const uint8_t>);
template size_t
prependBinaryBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, span<const uint8_t>);
Block
makeBinaryBlock(uint32_t type, span<const uint8_t> value)
makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length)
{
EncodingEstimator estimator;
size_t totalLength = prependBinaryBlock(estimator, type, value);
size_t totalLength = estimator.prependByteArrayBlock(type, value, length);
EncodingBuffer encoder(totalLength, 0);
prependBinaryBlock(encoder, type, value);
encoder.prependByteArrayBlock(type, value, length);
return encoder.block();
}
// ---- string ----
template<Tag TAG>
size_t
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, std::string_view value)
Block
makeBinaryBlock(uint32_t type, const char* value, size_t length)
{
return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
return makeBinaryBlock(type, reinterpret_cast<const uint8_t*>(value), length);
}
template size_t
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, std::string_view);
template size_t
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, std::string_view);
std::string
readString(const Block& block)
{
return std::string(reinterpret_cast<const char*>(block.value()), block.value_size());
}
// ---- block ----
template<Tag TAG>
size_t
prependBlock(EncodingImpl<TAG>& encoder, const Block& block)
{
if (block.hasWire()) {
return encoder.prependBytes(block);
}
else {
// FIXME: blindly calling Block::value_bytes() is not safe if the value is not wire-encoded
return prependBinaryBlock(encoder, block.type(), block.value_bytes());
}
}
template size_t
prependBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, const Block&);
template size_t
prependBlock<EncoderTag>(EncodingImpl<EncoderTag>&, const Block&);
} // namespace ndn::encoding
} // namespace encoding
} // namespace ndn
+131 -211
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,8 +19,8 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_ENCODING_BLOCK_HELPERS_HPP
#define NDN_CXX_ENCODING_BLOCK_HELPERS_HPP
#ifndef NDN_ENCODING_BLOCK_HELPERS_HPP
#define NDN_ENCODING_BLOCK_HELPERS_HPP
#include "ndn-cxx/encoding/block.hpp"
#include "ndn-cxx/encoding/encoding-buffer.hpp"
@@ -29,30 +29,6 @@
namespace ndn {
namespace encoding {
/** @brief Prepend an empty TLV element.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
* @details The TLV element has zero-length TLV-VALUE.
* @sa makeEmptyBlock
*/
template<Tag TAG>
size_t
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
extern template size_t
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
extern template size_t
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
/** @brief Create an empty TLV block.
* @param type TLV-TYPE number
* @return A TLV block with zero-length TLV-VALUE
* @sa prependEmptyBlock
*/
Block
makeEmptyBlock(uint32_t type);
/** @brief Prepend a TLV element containing a non-negative integer.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
@@ -92,7 +68,7 @@ readNonNegativeInteger(const Block& block);
* represented in R
*/
template<typename R>
std::enable_if_t<std::is_integral_v<R>, R>
std::enable_if_t<std::is_integral<R>::value, R>
readNonNegativeIntegerAs(const Block& block)
{
uint64_t value = readNonNegativeInteger(block);
@@ -111,12 +87,68 @@ readNonNegativeIntegerAs(const Block& block)
* function may trigger unspecified behavior.
*/
template<typename R>
std::enable_if_t<std::is_enum_v<R>, R>
std::enable_if_t<std::is_enum<R>::value, R>
readNonNegativeIntegerAs(const Block& block)
{
return static_cast<R>(readNonNegativeIntegerAs<std::underlying_type_t<R>>(block));
}
/** @brief Prepend an empty TLV element.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
* @details The TLV element has zero-length TLV-VALUE.
* @sa makeEmptyBlock
*/
template<Tag TAG>
size_t
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
extern template size_t
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
extern template size_t
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
/** @brief Create an empty TLV block.
* @param type TLV-TYPE number
* @return A TLV block with zero-length TLV-VALUE
* @sa prependEmptyBlock
*/
Block
makeEmptyBlock(uint32_t type);
/** @brief Prepend a TLV element containing a string.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
* @param value string value, may contain NUL octets
* @sa makeStringBlock, readString
*/
template<Tag TAG>
size_t
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value);
extern template size_t
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
extern template size_t
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
/** @brief Create a TLV block containing a string.
* @param type TLV-TYPE number
* @param value string value, may contain NUL octets
* @sa prependStringBlock, readString
*/
Block
makeStringBlock(uint32_t type, const std::string& value);
/** @brief Read TLV-VALUE of a TLV element as a string.
* @param block the TLV element
* @return a string, may contain NUL octets
* @sa prependStringBlock, makeStringBlock
*/
std::string
readString(const Block& block);
/** @brief Prepend a TLV element containing an IEEE 754 double-precision floating-point number.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
@@ -149,165 +181,96 @@ makeDoubleBlock(uint32_t type, double value);
double
readDouble(const Block& block);
/**
* @brief Prepend a TLV element containing a sequence of raw bytes.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
* @param value range of bytes to use as TLV-VALUE
* @sa makeBinaryBlock
*/
template<Tag TAG>
size_t
prependBinaryBlock(EncodingImpl<TAG>& encoder, uint32_t type, span<const uint8_t> value);
extern template size_t
prependBinaryBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, span<const uint8_t>);
extern template size_t
prependBinaryBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, span<const uint8_t>);
/**
* @brief Create a TLV block copying the TLV-VALUE from a byte range.
* @param type TLV-TYPE number
* @param value range of bytes to use as TLV-VALUE
* @sa prependBinaryBlock
/** @brief Create a TLV block copying TLV-VALUE from raw buffer.
* @param type TLV-TYPE number
* @param value raw buffer as TLV-VALUE
* @param length length of value buffer
* @sa Encoder::prependByteArrayBlock
*/
Block
makeBinaryBlock(uint32_t type, span<const uint8_t> value);
makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length);
/** @brief Create a TLV block copying TLV-VALUE from raw buffer.
* @param type TLV-TYPE number
* @param value raw buffer as TLV-VALUE
* @param length length of value buffer
* @sa Encoder::prependByteArrayBlock
*/
Block
makeBinaryBlock(uint32_t type, const char* value, size_t length);
namespace detail {
/**
* @brief Create a binary block copying from RandomAccessIterator.
/** @brief Create a binary block copying from RandomAccessIterator.
*/
template<class Iterator>
Block
makeBinaryBlockFast(uint32_t type, Iterator first, Iterator last)
class BinaryBlockFast
{
public:
BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
EncodingEstimator estimator;
size_t valueLength = last - first;
size_t totalLength = valueLength;
totalLength += estimator.prependVarNumber(valueLength);
totalLength += estimator.prependVarNumber(type);
static Block
makeBlock(uint32_t type, Iterator first, Iterator last)
{
EncodingEstimator estimator;
size_t valueLength = last - first;
size_t totalLength = valueLength;
totalLength += estimator.prependVarNumber(valueLength);
totalLength += estimator.prependVarNumber(type);
EncodingBuffer encoder(totalLength, 0);
encoder.prependRange(first, last);
encoder.prependVarNumber(valueLength);
encoder.prependVarNumber(type);
EncodingBuffer encoder(totalLength, 0);
encoder.prependRange(first, last);
encoder.prependVarNumber(valueLength);
encoder.prependVarNumber(type);
return encoder.block();
}
return encoder.block();
}
};
/**
* @brief Create a binary block copying from generic InputIterator.
/** @brief Create a binary block copying from generic InputIterator.
*/
template<class Iterator>
Block
makeBinaryBlockSlow(uint32_t type, Iterator first, Iterator last)
class BinaryBlockSlow
{
public:
BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
// Reserve 4 bytes in front, common for 1(type)-3(length) encoding.
// Actual size will be adjusted as necessary by the encoder.
EncodingBuffer encoder(4, 4);
size_t valueLength = encoder.appendRange(first, last);
encoder.prependVarNumber(valueLength);
encoder.prependVarNumber(type);
static Block
makeBlock(uint32_t type, Iterator first, Iterator last)
{
// reserve 4 bytes in front (common for 1(type)-3(length) encoding
// Actual size will be adjusted as necessary by the encoder
EncodingBuffer encoder(4, 4);
size_t valueLength = encoder.appendRange(first, last);
encoder.prependVarNumber(valueLength);
encoder.prependVarNumber(type);
return encoder.block();
}
return encoder.block();
}
};
} // namespace detail
/**
* @brief Create a TLV block copying TLV-VALUE from iterators.
* @tparam Iterator an InputIterator dereferenceable to a 1-octet type; a faster implementation is
* automatically selected for RandomAccessIterator
* @param type TLV-TYPE number
* @param first begin iterator
* @param last past-the-end iterator
* @sa prependBinaryBlock
/** @brief Create a TLV block copying TLV-VALUE from iterators.
* @tparam Iterator an InputIterator dereferencable to an 1-octet type; faster implementation is
* available for RandomAccessIterator
* @param type TLV-TYPE number
* @param first begin iterator
* @param last past-the-end iterator
*/
template<class Iterator>
Block
makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
{
if constexpr (std::is_base_of_v<std::random_access_iterator_tag,
typename std::iterator_traits<Iterator>::iterator_category>)
return detail::makeBinaryBlockFast(type, first, last);
else
return detail::makeBinaryBlockSlow(type, first, last);
using BinaryBlockHelper = std::conditional_t<
std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<Iterator>::iterator_category>::value,
detail::BinaryBlockFast<Iterator>,
detail::BinaryBlockSlow<Iterator>>;
return BinaryBlockHelper::makeBlock(type, first, last);
}
/**
* @brief Create a TLV block copying the TLV-VALUE from a char buffer.
* @param type TLV-TYPE number
* @param value raw buffer as TLV-VALUE
* @param length length of value buffer
* @deprecated Use makeStringBlock()
*/
[[deprecated("use makeStringBlock()")]]
inline Block
makeBinaryBlock(uint32_t type, const char* value, size_t length)
{
return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value), length});
}
/**
* @brief Prepend a TLV element containing a string.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
* @param value string value, may contain NUL octets
* @sa makeStringBlock, readString
*/
template<Tag TAG>
size_t
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, std::string_view value);
extern template size_t
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, std::string_view);
extern template size_t
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, std::string_view);
/**
* @brief Create a TLV block containing a string.
* @param type TLV-TYPE number
* @param value string value, may contain NUL octets
* @sa prependStringBlock, readString
*/
inline Block
makeStringBlock(uint32_t type, std::string_view value)
{
return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
}
/**
* @brief Read the TLV-VALUE of a TLV element as a string.
* @param block the TLV element
* @return a string, may contain NUL octets
* @sa prependStringBlock, makeStringBlock
*/
std::string
readString(const Block& block);
/**
* @brief Prepend a TLV element.
* @param encoder an EncodingBuffer or EncodingEstimator
* @param block the TLV element
*/
template<Tag TAG>
size_t
prependBlock(EncodingImpl<TAG>& encoder, const Block& block);
extern template size_t
prependBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, const Block&);
extern template size_t
prependBlock<EncoderTag>(EncodingImpl<EncoderTag>&, const Block&);
/** @brief Prepend a TLV element containing a nested TLV element.
* @tparam U type that satisfies WireEncodableWithEncodingBuffer concept
* @param encoder an EncodingBuffer or EncodingEstimator
@@ -321,10 +284,12 @@ prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, const U& value)
{
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<U>));
size_t length = value.wireEncode(encoder);
length += encoder.prependVarNumber(length);
length += encoder.prependVarNumber(type);
return length;
size_t valueLength = value.wireEncode(encoder);
size_t totalLength = valueLength;
totalLength += encoder.prependVarNumber(valueLength);
totalLength += encoder.prependVarNumber(type);
return totalLength;
}
/** @brief Create a TLV block containing a nested TLV element.
@@ -342,66 +307,21 @@ makeNestedBlock(uint32_t type, const U& value)
EncodingBuffer encoder(totalLength, 0);
prependNestedBlock(encoder, type, value);
return encoder.block();
}
/** @brief Prepend a TLV element containing a sequence of nested TLV elements.
* @tparam I bidirectional iterator to a type that satisfies WireEncodableWithEncodingBuffer concept
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number for outer TLV element
* @param first begin iterator to inner TLV elements
* @param last past-end iterator to inner TLV elements
* @sa makeNestedBlock
*/
template<Tag TAG, class I>
size_t
prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, I first, I last)
{
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<typename std::iterator_traits<I>::value_type>));
auto rfirst = std::make_reverse_iterator(last);
auto rlast = std::make_reverse_iterator(first);
size_t length = 0;
for (auto i = rfirst; i != rlast; ++i) {
length += i->wireEncode(encoder);
}
length += encoder.prependVarNumber(length);
length += encoder.prependVarNumber(type);
return length;
}
/** @brief Create a TLV block containing a sequence of nested TLV elements.
* @tparam I bidirectional iterator to a type that satisfies WireEncodableWithEncodingBuffer concept
* @param type TLV-TYPE number for outer TLV element
* @param first begin iterator to inner TLV elements
* @param last past-end iterator to inner TLV elements
* @sa prependNestedBlock
*/
template<class I>
Block
makeNestedBlock(uint32_t type, I first, I last)
{
EncodingEstimator estimator;
size_t totalLength = prependNestedBlock(estimator, type, first, last);
EncodingBuffer encoder(totalLength, 0);
prependNestedBlock(encoder, type, first, last);
return encoder.block();
}
} // namespace encoding
using encoding::makeEmptyBlock;
using encoding::makeNonNegativeIntegerBlock;
using encoding::readNonNegativeInteger;
using encoding::readNonNegativeIntegerAs;
using encoding::makeBinaryBlock;
using encoding::makeEmptyBlock;
using encoding::makeStringBlock;
using encoding::readString;
using encoding::makeBinaryBlock;
using encoding::makeNestedBlock;
} // namespace ndn
#endif // NDN_CXX_ENCODING_BLOCK_HELPERS_HPP
#endif // NDN_ENCODING_BLOCK_HELPERS_HPP
+132 -143
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -25,22 +25,19 @@
#include "ndn-cxx/encoding/buffer-stream.hpp"
#include "ndn-cxx/encoding/encoding-buffer.hpp"
#include "ndn-cxx/encoding/tlv.hpp"
#include "ndn-cxx/security/transform/hex-decode.hpp"
#include "ndn-cxx/security/transform/step-source.hpp"
#include "ndn-cxx/security/transform/stream-sink.hpp"
#include "ndn-cxx/security/transform.hpp"
#include "ndn-cxx/util/ostream-joiner.hpp"
#include "ndn-cxx/util/scope.hpp"
#include "ndn-cxx/util/string-helper.hpp"
#include <boost/asio/buffer.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <algorithm>
#include <cstring>
namespace ndn {
constexpr size_t MAX_SIZE_OF_BLOCK_FROM_STREAM = MAX_NDN_PACKET_SIZE;
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Block>));
const size_t MAX_SIZE_OF_BLOCK_FROM_STREAM = MAX_NDN_PACKET_SIZE;
// ---- constructor, creation, assignment ----
@@ -51,30 +48,6 @@ Block::Block(const Block&) = default;
Block&
Block::operator=(const Block&) = default;
Block::Block(span<const uint8_t> buffer)
{
auto pos = buffer.begin();
const auto end = buffer.end();
m_type = tlv::readType(pos, end);
uint64_t length = tlv::readVarNumber(pos, end);
// pos now points to TLV-VALUE
BOOST_ASSERT(pos <= end);
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
NDN_THROW(Error("Not enough bytes in the buffer to fully parse TLV"));
}
std::advance(pos, length);
// pos now points to the end of the TLV
m_buffer = std::make_shared<Buffer>(buffer.begin(), pos);
m_begin = m_buffer->begin();
m_end = m_buffer->end();
m_valueBegin = std::prev(m_end, length);
m_valueEnd = m_buffer->end();
m_size = m_buffer->size();
}
Block::Block(const EncodingBuffer& buffer)
: Block(buffer.getBuffer(), buffer.begin(), buffer.end(), true)
{
@@ -92,9 +65,9 @@ Block::Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_
, m_end(end)
, m_valueBegin(m_begin)
, m_valueEnd(m_end)
, m_size(static_cast<size_t>(std::distance(m_begin, m_end)))
, m_size(m_end - m_begin)
{
if (m_buffer->empty()) {
if (m_buffer->size() == 0) {
NDN_THROW(std::invalid_argument("Buffer is empty"));
}
@@ -114,7 +87,7 @@ Block::Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_
}
}
Block::Block(const Block& block, Block::const_iterator begin, Block::const_iterator end,
Block::Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
bool verifyLength)
: Block(block.m_buffer, begin, end, verifyLength)
{
@@ -129,10 +102,34 @@ Block::Block(ConstBufferPtr buffer, uint32_t type,
, m_valueBegin(valueBegin)
, m_valueEnd(valueEnd)
, m_type(type)
, m_size(static_cast<size_t>(std::distance(m_begin, m_end)))
, m_size(m_end - m_begin)
{
}
Block::Block(const uint8_t* buf, size_t bufSize)
{
const uint8_t* pos = buf;
const uint8_t* const end = buf + bufSize;
m_type = tlv::readType(pos, end);
uint64_t length = tlv::readVarNumber(pos, end);
// pos now points to TLV-VALUE
BOOST_ASSERT(pos <= end);
if (length > static_cast<uint64_t>(end - pos)) {
NDN_THROW(Error("Not enough bytes in the buffer to fully parse TLV"));
}
BOOST_ASSERT(pos > buf);
uint64_t typeLengthSize = static_cast<uint64_t>(pos - buf);
m_size = typeLengthSize + length;
m_buffer = make_shared<Buffer>(buf, m_size);
m_begin = m_buffer->begin();
m_end = m_valueEnd = m_buffer->end();
m_valueBegin = m_begin + typeLengthSize;
}
Block::Block(uint32_t type)
: m_type(type)
, m_size(tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(0))
@@ -161,63 +158,6 @@ Block::Block(uint32_t type, const Block& value)
m_size = tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(value_size()) + value_size();
}
std::tuple<bool, Block>
Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
{
auto begin = std::next(buffer->begin(), offset);
auto pos = begin;
const auto end = buffer->end();
uint32_t type = 0;
bool isOk = tlv::readType(pos, end, type);
if (!isOk) {
return {false, {}};
}
uint64_t length = 0;
isOk = tlv::readVarNumber(pos, end, length);
if (!isOk) {
return {false, {}};
}
// pos now points to TLV-VALUE
BOOST_ASSERT(pos <= end);
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
return {false, {}};
}
return {true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length)};
}
std::tuple<bool, Block>
Block::fromBuffer(span<const uint8_t> buffer)
{
auto pos = buffer.begin();
const auto end = buffer.end();
uint32_t type = 0;
bool isOk = tlv::readType(pos, end, type);
if (!isOk) {
return {false, {}};
}
uint64_t length = 0;
isOk = tlv::readVarNumber(pos, end, length);
if (!isOk) {
return {false, {}};
}
// pos now points to TLV-VALUE
BOOST_ASSERT(pos <= end);
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
return {false, {}};
}
std::advance(pos, length);
// pos now points to the end of the TLV
auto b = std::make_shared<Buffer>(buffer.begin(), pos);
return {true, Block(b, type, b->begin(), b->end(), std::prev(b->end(), length), b->end())};
}
Block
Block::fromStream(std::istream& is)
{
@@ -236,7 +176,7 @@ Block::fromStream(std::istream& is)
}
EncodingBuffer eb(tlSize + length, length);
uint8_t* valueBuf = eb.data();
uint8_t* valueBuf = eb.buf();
is.read(reinterpret_cast<char*>(valueBuf), length);
if (length != static_cast<uint64_t>(is.gcount())) {
NDN_THROW(Error("Not enough bytes from stream to fully parse TLV"));
@@ -250,6 +190,60 @@ Block::fromStream(std::istream& is)
return Block(eb.getBuffer());
}
std::tuple<bool, Block>
Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
{
auto begin = buffer->begin() + offset;
auto pos = begin;
uint32_t type = 0;
bool isOk = tlv::readType(pos, buffer->end(), type);
if (!isOk) {
return std::make_tuple(false, Block());
}
uint64_t length = 0;
isOk = tlv::readVarNumber(pos, buffer->end(), length);
if (!isOk) {
return std::make_tuple(false, Block());
}
// pos now points to TLV-VALUE
if (length > static_cast<uint64_t>(buffer->end() - pos)) {
return std::make_tuple(false, Block());
}
return std::make_tuple(true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length));
}
std::tuple<bool, Block>
Block::fromBuffer(const uint8_t* buf, size_t bufSize)
{
const uint8_t* pos = buf;
const uint8_t* const end = buf + bufSize;
uint32_t type = 0;
bool isOk = tlv::readType(pos, end, type);
if (!isOk) {
return std::make_tuple(false, Block());
}
uint64_t length = 0;
isOk = tlv::readVarNumber(pos, end, length);
if (!isOk) {
return std::make_tuple(false, Block());
}
// pos now points to TLV-VALUE
if (length > static_cast<uint64_t>(end - pos)) {
return std::make_tuple(false, Block());
}
size_t typeLengthSize = pos - buf;
auto b = make_shared<Buffer>(buf, pos + length);
return std::make_tuple(true, Block(b, type, b->begin(), b->end(),
b->begin() + typeLengthSize, b->end()));
}
// ---- wire format ----
void
@@ -265,7 +259,7 @@ Block::resetWire() noexcept
m_begin = m_end = m_valueBegin = m_valueEnd = {};
}
Block::const_iterator
Buffer::const_iterator
Block::begin() const
{
if (!hasWire())
@@ -274,7 +268,7 @@ Block::begin() const
return m_begin;
}
Block::const_iterator
Buffer::const_iterator
Block::end() const
{
if (!hasWire())
@@ -284,7 +278,7 @@ Block::end() const
}
const uint8_t*
Block::data() const
Block::wire() const
{
if (!hasWire())
NDN_THROW(Error("Underlying wire buffer is empty"));
@@ -307,15 +301,20 @@ Block::size() const
const uint8_t*
Block::value() const noexcept
{
return value_size() > 0 ? &*m_valueBegin : nullptr;
return hasValue() ? &*m_valueBegin : nullptr;
}
size_t
Block::value_size() const noexcept
{
return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
}
Block
Block::blockFromValue() const
{
if (value_size() == 0) {
NDN_THROW(Error("Cannot construct block from empty TLV-VALUE"));
}
if (!hasValue())
NDN_THROW(Error("Block has no TLV-VALUE"));
return Block(*this, m_valueBegin, m_valueEnd, true);
}
@@ -328,11 +327,12 @@ Block::parse() const
if (!m_elements.empty() || value_size() == 0)
return;
auto begin = value_begin();
auto end = value_end();
Buffer::const_iterator begin = value_begin();
Buffer::const_iterator end = value_end();
while (begin != end) {
auto pos = begin;
Buffer::const_iterator pos = begin;
uint32_t type = tlv::readType(pos, end);
uint64_t length = tlv::readVarNumber(pos, end);
if (length > static_cast<uint64_t>(end - pos)) {
@@ -342,7 +342,7 @@ Block::parse() const
}
// pos now points to TLV-VALUE of sub element
auto subEnd = std::next(pos, length);
Buffer::const_iterator subEnd = pos + length;
m_elements.emplace_back(m_buffer, type, begin, subEnd, pos, subEnd);
begin = subEnd;
@@ -413,12 +413,13 @@ Block::encode(EncodingBuffer& encoder)
const Block&
Block::get(uint32_t type) const
{
if (auto it = find(type); it != m_elements.end()) {
auto it = this->find(type);
if (it != m_elements.end()) {
return *it;
}
NDN_THROW(Error("No sub-element of type " + std::to_string(type) +
" found in block of type " + std::to_string(m_type)));
NDN_THROW(Error("No sub-element of type " + to_string(type) +
" found in block of type " + to_string(m_type)));
}
Block::element_const_iterator
@@ -459,13 +460,6 @@ Block::push_back(const Block& element)
m_elements.push_back(element);
}
void
Block::push_back(Block&& element)
{
resetWire();
m_elements.push_back(std::move(element));
}
Block::element_iterator
Block::insert(Block::element_const_iterator pos, const Block& element)
{
@@ -477,50 +471,47 @@ Block::insert(Block::element_const_iterator pos, const Block& element)
Block::operator boost::asio::const_buffer() const
{
return {data(), size()};
return boost::asio::const_buffer(wire(), size());
}
bool
Block::equals(const Block& other) const noexcept
operator==(const Block& lhs, const Block& rhs)
{
return type() == other.type() &&
value_size() == other.value_size() &&
(value_size() == 0 ||
std::equal(value_begin(), value_end(), other.value_begin()));
return lhs.type() == rhs.type() &&
lhs.value_size() == rhs.value_size() &&
(lhs.value_size() == 0 ||
std::memcmp(lhs.value(), rhs.value(), lhs.value_size()) == 0);
}
void
Block::print(std::ostream& os) const
std::ostream&
operator<<(std::ostream& os, const Block& block)
{
auto oldFlags = os.flags(std::ios_base::dec);
auto restoreFlags = make_scope_exit([&] {
os.flags(oldFlags);
});
auto oldFmt = os.flags(std::ios_base::dec);
if (!isValid()) {
if (!block.isValid()) {
os << "[invalid]";
}
else if (!m_elements.empty()) {
else if (!block.m_elements.empty()) {
EncodingEstimator estimator;
size_t tlvLength = encodeValue(estimator);
os << type() << '[' << tlvLength << "]={";
std::copy(elements_begin(), elements_end(), make_ostream_joiner(os, ','));
size_t tlvLength = block.encodeValue(estimator);
os << block.type() << '[' << tlvLength << "]={";
std::copy(block.elements_begin(), block.elements_end(), make_ostream_joiner(os, ','));
os << '}';
}
else if (value_size() > 0) {
os << type() << '[' << value_size() << "]=";
printHex(os, value_bytes(), true);
else if (block.value_size() > 0) {
os << block.type() << '[' << block.value_size() << "]=";
printHex(os, block.value(), block.value_size(), true);
}
else {
os << type() << "[empty]";
os << block.type() << "[empty]";
}
os.flags(oldFmt);
return os;
}
inline namespace literals {
inline namespace block_literals {
Block
operator ""_block(const char* input, std::size_t len)
operator "" _block(const char* input, std::size_t len)
{
namespace t = security::transform;
t::StepSource ss;
@@ -529,7 +520,7 @@ operator ""_block(const char* input, std::size_t len)
for (const char* end = input + len; input != end; ++input) {
if (std::strchr("0123456789ABCDEF", *input) != nullptr) {
ss.write({reinterpret_cast<const uint8_t*>(input), 1});
ss.write(reinterpret_cast<const uint8_t*>(input), 1);
}
}
@@ -543,6 +534,4 @@ operator ""_block(const char* input, std::size_t len)
return Block(os.buf());
}
} // inline namespace block_literals
} // inline namespace literals
} // namespace ndn
+124 -207
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 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,25 +27,21 @@
#include "ndn-cxx/encoding/buffer.hpp"
#include "ndn-cxx/encoding/encoding-buffer-fwd.hpp"
#include "ndn-cxx/encoding/tlv.hpp"
#include "ndn-cxx/util/span.hpp"
#include <boost/operators.hpp>
namespace boost::asio {
namespace boost {
namespace asio {
class const_buffer;
} // namespace boost::asio
} // namespace asio
} // namespace boost
namespace ndn {
/**
* @brief Represents a TLV element of the NDN packet format.
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
/** @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 : private boost::equality_comparable<Block>
class Block
{
public:
using value_type = Buffer::value_type;
using const_iterator = Buffer::const_iterator;
using element_container = std::vector<Block>;
using element_iterator = element_container::iterator;
using element_const_iterator = element_container::const_iterator;
@@ -80,15 +76,6 @@ public: // construction, assignment
Block&
operator=(Block&&) noexcept;
/** @brief Parse Block from a byte range
* @param buffer sequence of bytes containing a TLV element; the element must be found at
* the beginning of the buffer but does not need to span the entire buffer
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH exceeds the size of @p buffer
* @note This constructor copies the TLV element octets to an internal buffer.
*/
explicit
Block(span<const uint8_t> buffer);
/** @brief Parse Block from an EncodingBuffer
* @param buffer an EncodingBuffer containing one TLV element
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
@@ -98,8 +85,8 @@ public: // construction, assignment
/** @brief Parse Block from a wire Buffer
* @param buffer a Buffer containing one TLV element
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
* @note This constructor takes shared ownership of @p buffer.
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
*/
explicit
Block(const ConstBufferPtr& buffer);
@@ -111,6 +98,7 @@ public: // construction, assignment
* @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
* @throw std::invalid_argument @p buffer is empty, or [@p begin,@p end) range is not within @p buffer
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
* @note This overload automatically detects TLV-TYPE and position of TLV-VALUE.
*/
Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
bool verifyLength = true);
@@ -123,7 +111,7 @@ public: // construction, assignment
* @throw std::invalid_argument [@p begin,@p end) range is not within @p block
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
*/
Block(const Block& block, Block::const_iterator begin, Block::const_iterator end,
Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
bool verifyLength = true);
/** @brief Create a Block from a wire Buffer without parsing
@@ -138,6 +126,14 @@ public: // construction, assignment
Buffer::const_iterator begin, Buffer::const_iterator end,
Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd);
/** @brief Parse Block from a raw buffer
* @param buf pointer to the first octet of a TLV element
* @param bufSize size of the raw buffer; may be greater than the actual size of the TLV element
* @throw tlv::Error Type-Length parsing fails, or size of TLV-VALUE exceeds @p bufSize
* @note This overload copies the TLV element octets into an internal wire buffer.
*/
Block(const uint8_t* buf, size_t bufSize);
/** @brief Create a zero-length Block with the specified TLV-TYPE
* @param type TLV-TYPE
*/
@@ -156,25 +152,6 @@ public: // construction, assignment
*/
Block(uint32_t type, const Block& value);
/** @brief Try to parse Block from a wire buffer
* @param buffer a Buffer containing a TLV element at offset @p offset
* @param offset begin position of the TLV element within @p buffer
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
* @note This function does not throw upon decoding failure.
*/
[[nodiscard]] static std::tuple<bool, Block>
fromBuffer(ConstBufferPtr buffer, size_t offset = 0);
/** @brief Try to parse Block from a byte range
* @param buffer sequence of bytes containing a TLV element; the element must be found at
* the beginning of the buffer but does not need to span the entire buffer
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
* @note This overload copies the TLV element octets to an internal buffer.
* @note This function does not throw upon decoding failure.
*/
[[nodiscard]] static std::tuple<bool, Block>
fromBuffer(span<const uint8_t> buffer);
/** @brief Parse Block from an input stream
* @throw tlv::Error TLV-LENGTH is zero or exceeds upper bound
* @warning If decoding fails, bytes are still consumed from the input stream.
@@ -182,6 +159,25 @@ public: // construction, assignment
static Block
fromStream(std::istream& is);
/** @brief Try to parse Block from a wire buffer
* @param buffer a Buffer containing a TLV element at offset @p offset
* @param offset begin position of the TLV element within @p buffer
* @note This function does not throw upon decoding failure.
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
*/
NDN_CXX_NODISCARD static std::tuple<bool, Block>
fromBuffer(ConstBufferPtr buffer, size_t offset);
/** @brief Try to parse Block from a raw buffer
* @param buf pointer to the first octet of a TLV element
* @param bufSize size of the raw buffer; may be greater than the actual size of the TLV element
* @note This function does not throw upon decoding failure.
* @note This overload copies the TLV element octets into an internal wire buffer.
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
*/
NDN_CXX_NODISCARD static std::tuple<bool, Block>
fromBuffer(const uint8_t* buf, size_t bufSize);
public: // wire format
/** @brief Check if the Block is valid
*
@@ -223,48 +219,33 @@ public: // wire format
return m_buffer != nullptr && m_begin != m_end;
}
/**
* @brief Returns an iterator to the beginning of the encoded wire.
* @pre `hasWire() == true`
/** @brief Get begin iterator of encoded wire
* @pre `hasWire() == true`
*/
const_iterator
Buffer::const_iterator
begin() const;
/**
* @brief Returns an iterator past-the-end of the encoded wire.
* @pre `hasWire() == true`
/** @brief Get end iterator of encoded wire
* @pre `hasWire() == true`
*/
const_iterator
Buffer::const_iterator
end() const;
/**
* @brief Returns the size of the encoded wire, i.e., of the whole TLV.
* @pre `isValid() == true`
* @sa value_size()
/** @brief Return a raw pointer to the beginning of the encoded wire
* @pre `hasWire() == true`
* @sa value()
*/
const uint8_t*
wire() const;
/** @brief Return the size of the encoded wire, i.e. of the whole TLV
* @pre `isValid() == true`
* @sa value_size()
*/
size_t
size() const;
/**
* @brief Returns a raw pointer to the beginning of the encoded wire, i.e., the whole TLV.
* @pre `hasWire() == true`
* @sa value()
*/
const uint8_t*
data() const;
/**
* @deprecated Use data()
*/
[[deprecated("use data()")]]
const uint8_t*
wire() const
{
return data();
}
/**
* @brief Returns the underlying buffer.
/** @brief Get underlying buffer
*/
ConstBufferPtr
getBuffer() const
@@ -273,23 +254,21 @@ public: // wire format
}
public: // type and value
/**
* @brief Return the TLV-TYPE of the Block.
* @note This will return tlv::Invalid if isValid() is false.
/** @brief Return the TLV-TYPE of the Block
* @note This will return tlv::Invalid if isValid() is false.
*/
uint32_t
type() const noexcept
type() const
{
return m_type;
}
/**
* @brief Check if the Block has a non-empty TLV-VALUE.
/** @brief Check if the Block has a non-empty TLV-VALUE
*
* This property reflects whether the underlying buffer contains a TLV-VALUE. If this is false,
* TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
* This property reflects whether the underlying buffer contains a TLV-VALUE. If this is false,
* TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
*
* @sa value_size()
* @sa value_size()
*/
bool
hasValue() const noexcept
@@ -297,59 +276,36 @@ public: // type and value
return m_buffer != nullptr;
}
/**
* @brief Get begin iterator of TLV-VALUE.
* @pre `hasValue() == true`
/** @brief Get begin iterator of TLV-VALUE
* @pre `hasValue() == true`
*/
const_iterator
value_begin() const noexcept
Buffer::const_iterator
value_begin() const
{
return m_valueBegin;
}
/**
* @brief Get end iterator of TLV-VALUE.
* @pre `hasValue() == true`
/** @brief Get end iterator of TLV-VALUE
* @pre `hasValue() == true`
*/
const_iterator
value_end() const noexcept
Buffer::const_iterator
value_end() const
{
return m_valueEnd;
}
/**
* @brief Return the size of TLV-VALUE, i.e., the TLV-LENGTH.
* @sa size()
*/
size_t
value_size() const noexcept
{
return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
}
/**
* @brief Return a read-only view of TLV-VALUE as a contiguous range of bytes.
*/
span<const uint8_t>
value_bytes() const noexcept
{
if (hasValue())
return {m_valueBegin, m_valueEnd};
else
return {};
}
/**
* @brief Return a raw pointer to the beginning of TLV-VALUE.
* @sa value_bytes(), data()
/** @brief Return a raw pointer to the beginning of TLV-VALUE
* @sa wire()
*/
const uint8_t*
value() const noexcept;
/**
* @brief Return a new Block constructed from the TLV-VALUE of this Block.
* @pre `value_size() > 0`
/** @brief Return the size of TLV-VALUE, aka TLV-LENGTH
* @sa size()
*/
size_t
value_size() const noexcept;
Block
blockFromValue() const;
@@ -371,14 +327,14 @@ public: // sub-elements
encode();
/** @brief Return the first sub-element of the specified TLV-TYPE
* @pre parse() has been called
* @pre parse() has been executed
* @throw tlv::Error a sub-element of the specified type does not exist
*/
const Block&
get(uint32_t type) const;
/** @brief Find the first sub-element of the specified TLV-TYPE
* @pre parse() has been called
* @pre parse() has been executed
* @return iterator in elements() to the found sub-element, or elements_end() if no such
* sub-element exists in elements()
*/
@@ -386,7 +342,7 @@ public: // sub-elements
find(uint32_t type) const;
/** @brief Remove all sub-elements of the specified TLV-TYPE
* @pre parse() has been called
* @pre parse() has been executed
* @post `find(type) == elements_end()`
*/
void
@@ -402,18 +358,11 @@ public: // sub-elements
element_iterator
erase(element_const_iterator first, element_const_iterator last);
/**
* @brief Append a sub-element.
/** @brief Append a sub-element
*/
void
push_back(const Block& element);
/**
* @brief Append a sub-element.
*/
void
push_back(Block&& element);
/** @brief Insert a sub-element
* @param pos position of the new sub-element
* @param element new sub-element to insert
@@ -422,110 +371,62 @@ public: // sub-elements
element_iterator
insert(element_const_iterator pos, const Block& element);
/**
* @brief Get container of sub-elements.
* @pre parse() has been called.
/** @brief Get container of sub-elements
* @pre parse() has been executed
*/
const element_container&
elements() const noexcept
elements() const
{
return m_elements;
}
/**
* @brief Equivalent to `elements().begin()`.
/** @brief Equivalent to elements().begin()
*/
element_const_iterator
elements_begin() const noexcept
elements_begin() const
{
return m_elements.begin();
}
/**
* @brief Equivalent to `elements().end()`.
/** @brief Equivalent to elements().end()
*/
element_const_iterator
elements_end() const noexcept
elements_end() const
{
return m_elements.end();
}
/**
* @brief Equivalent to `elements().size()`.
/** @brief Equivalent to elements().size()
*/
size_t
elements_size() const noexcept
elements_size() const
{
return m_elements.size();
}
public: // misc
/**
* @brief Implicit conversion to `boost::asio::const_buffer`.
/** @brief Implicit conversion to `boost::asio::const_buffer`
*/
operator boost::asio::const_buffer() const;
private:
/**
* @brief Estimate Block size as if sub-elements are encoded into TLV-VALUE.
/** @brief Estimate Block size as if sub-elements are encoded into TLV-VALUE
*/
size_t
encode(EncodingEstimator& estimator) const;
/**
* @brief Estimate TLV-LENGTH as if sub-elements are encoded into TLV-VALUE.
/** @brief Estimate TLV-LENGTH as if sub-elements are encoded into TLV-VALUE
*/
size_t
encodeValue(EncodingEstimator& estimator) const;
/**
* @brief Encode sub-elements into TLV-VALUE and prepend Block to encoder.
* @post TLV-VALUE contains sub-elements from elements()
* @post internal buffer and iterators point to Encoder's buffer
/** @brief Encode sub-elements into TLV-VALUE and prepend Block to encoder
* @post TLV-VALUE contains sub-elements from elements()
* @post internal buffer and iterators point to Encoder's buffer
*/
size_t
encode(EncodingBuffer& encoder);
/**
* @brief Returns whether this Block has the same TLV-TYPE/TLV-LENGTH/TLV-VALUE as @p other.
*/
bool
equals(const Block& other) const noexcept;
void
print(std::ostream& os) const;
private: // non-member operators
// NOTE: the following "hidden friend" operators are available via
// argument-dependent lookup only and must be defined inline.
// boost::equality_comparable provides != operator.
/**
* @brief Compare whether two Blocks have the same TLV-TYPE, TLV-LENGTH, and TLV-VALUE.
*/
friend bool
operator==(const Block& lhs, const Block& rhs) noexcept
{
return lhs.equals(rhs);
}
/**
* @brief Print @p block to @p os.
*
* Default-constructed Block is printed as: `[invalid]`.
* Zero-length Block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
* Non-zero-length Block on which parse() has not been called is printed as: `TT[LL]=VVVV`,
* where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE in hexadecimal.
* Block on which parse() has been called is printed as: `TT[LL]={SUB,SUB}`,
* where each SUB is a sub-element printed using this format.
*/
friend std::ostream&
operator<<(std::ostream& os, const Block& block)
{
block.print(os);
return os;
}
protected:
/** @brief Underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields
*
@@ -544,19 +445,29 @@ protected:
uint32_t m_type = tlv::Invalid; ///< TLV-TYPE
/**
* @brief Total size including Type-Length-Value.
/** @brief Total size including Type-Length-Value
*
* This field is meaningful only if isValid() is true.
* This field is meaningful only if isValid() is true.
*/
size_t m_size = 0;
/**
* @brief Contains the sub-elements.
/** @brief Contains the sub-elements
*
* This field is valid only if parse() has been called on the Block instance.
* This field is valid only if parse() has been executed.
*/
mutable element_container m_elements;
/** @brief Print @p block to @p os.
*
* Default-constructed Block is printed as: `[invalid]`.
* Zero-length Block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
* Non-zero-length Block on which parse() has not been called is printed as: `TT[LL]=VVVV`,
* where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE in hexadecimal.
* Block on which parse() has been called is printed as: `TT[LL]={SUB,SUB}`,
* where each SUB is a sub-element printed using this format.
*/
friend std::ostream&
operator<<(std::ostream& os, const Block& block);
};
inline
@@ -565,8 +476,16 @@ Block::Block(Block&&) noexcept = default;
inline Block&
Block::operator=(Block&&) noexcept = default;
inline namespace literals {
inline namespace block_literals {
/** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE
*/
bool
operator==(const Block& lhs, const Block& rhs);
inline bool
operator!=(const Block& lhs, const Block& rhs)
{
return !(lhs == rhs);
}
/** @brief Construct a Block from hexadecimal @p input.
* @param input a string containing hexadecimal bytes and comments.
@@ -575,17 +494,15 @@ inline namespace block_literals {
* @throw std::invalid_argument input is empty or has an odd number of hexadecimal digits.
* @throw tlv::Error @p input cannot be parsed into a valid Block.
*
* Example:
* Example
* @code
* Block nameBlock = "0706 080141 080142"_block;
* Block nackBlock = "FD032005 reason(no-route)=FD03210196"_block;
* @endcode
*/
Block
operator ""_block(const char* input, std::size_t len);
operator "" _block(const char* input, std::size_t len);
} // inline namespace block_literals
} // inline namespace literals
} // namespace ndn
#endif // NDN_CXX_ENCODING_BLOCK_HPP
+9 -15
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -24,13 +24,13 @@
namespace ndn {
namespace detail {
BufferSink::BufferSink(Buffer& container)
BufferAppendDevice::BufferAppendDevice(Buffer& container)
: m_container(container)
{
}
std::streamsize
BufferSink::write(const char_type* s, std::streamsize n)
BufferAppendDevice::write(const char_type* s, std::streamsize n)
{
m_container.insert(m_container.end(), s, s + n);
return n;
@@ -39,27 +39,21 @@ BufferSink::write(const char_type* s, std::streamsize n)
} // namespace detail
OBufferStream::OBufferStream()
: m_buffer(std::make_shared<Buffer>())
: m_buffer(make_shared<Buffer>())
, m_device(*m_buffer)
{
open(detail::BufferSink{*m_buffer});
open(m_device);
}
OBufferStream::~OBufferStream() noexcept
OBufferStream::~OBufferStream()
{
try {
close();
}
catch (...) {
// ignore
}
close();
}
shared_ptr<Buffer>
OBufferStream::buf()
{
if (is_open()) {
flush();
}
flush();
return m_buffer;
}
+29 -27
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2022 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -21,68 +21,70 @@
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#ifndef NDN_CXX_ENCODING_BUFFER_STREAM_HPP
#define NDN_CXX_ENCODING_BUFFER_STREAM_HPP
#ifndef NDN_ENCODING_BUFFER_STREAM_HPP
#define NDN_ENCODING_BUFFER_STREAM_HPP
#include "ndn-cxx/encoding/buffer.hpp"
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/stream.hpp>
namespace ndn {
namespace detail {
/**
* @brief (implementation detail) A Boost.Iostreams.Sink that appends to a Buffer.
/** @brief (implementation detail) a Boost.Iostreams.Sink which appends to an \p ndn::Buffer
*/
class BufferSink : public boost::iostreams::sink
class BufferAppendDevice
{
public:
typedef char char_type;
typedef boost::iostreams::sink_tag category;
explicit
BufferSink(Buffer& container);
BufferAppendDevice(Buffer& container);
std::streamsize
write(const char_type* s, std::streamsize n);
private:
protected:
Buffer& m_container;
};
} // namespace detail
/**
* @brief An output stream that writes to a Buffer.
/** @brief implements an output stream that constructs \p ndn::Buffer
*
* The benefit of using stream interface is that it provides automatic buffering of
* written data and eliminates (or reduces) overhead of resizing the underlying buffer
* when writing small pieces of data.
* The benefit of using stream interface is that it provides automatic buffering of
* written data and eliminates (or reduces) overhead of resizing the underlying buffer
* when writing small pieces of data.
*
* Usage example:
* @code
* OBufferStream obuf;
* obuf << "foo";
* obuf.put(0);
* obuf.write(anotherBuffer, anotherBufferSize);
* std::shared_ptr<Buffer> buf = obuf.buf();
* @endcode
* Usage example:
* @code
* OBufferStream obuf;
* obuf.put(0);
* obuf.write(anotherBuffer, anotherBufferSize);
* shared_ptr<Buffer> buf = obuf.buf();
* @endcode
*/
class OBufferStream : public boost::iostreams::stream<detail::BufferSink>
class OBufferStream : public boost::iostreams::stream<detail::BufferAppendDevice>
{
public:
OBufferStream();
~OBufferStream() noexcept override;
~OBufferStream();
/**
* @brief Return a shared pointer to the underlying buffer.
* Flush written data to the stream and return shared pointer to the underlying buffer
*/
shared_ptr<Buffer>
buf();
private:
shared_ptr<Buffer> m_buffer;
BufferPtr m_buffer;
detail::BufferAppendDevice m_device;
};
} // namespace ndn
#endif // NDN_CXX_ENCODING_BUFFER_STREAM_HPP
#endif // NDN_ENCODING_BUFFER_STREAM_HPP
+4 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2021 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -21,12 +21,11 @@
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#ifndef NDN_CXX_ENCODING_BUFFER_HPP
#define NDN_CXX_ENCODING_BUFFER_HPP
#ifndef NDN_ENCODING_BUFFER_HPP
#define NDN_ENCODING_BUFFER_HPP
#include "ndn-cxx/detail/common.hpp"
#include <initializer_list>
#include <vector>
namespace ndn {
@@ -92,13 +91,6 @@ public:
{
}
/** @brief Creates a Buffer with the contents of an initializer list
*/
Buffer(std::initializer_list<uint8_t> il)
: std::vector<uint8_t>(il)
{
}
/** @return pointer to the first byte of the buffer, cast to the requested type T
*/
template<class T>
@@ -130,14 +122,9 @@ Buffer::Buffer(Buffer&&) noexcept = default;
inline Buffer&
Buffer::operator=(Buffer&&) noexcept = default;
/** \cond */
std::ostream&
boost_test_print_type(std::ostream&, const Buffer&);
/** \endcond */
using BufferPtr = shared_ptr<Buffer>;
using ConstBufferPtr = shared_ptr<const Buffer>;
} // namespace ndn
#endif // NDN_CXX_ENCODING_BUFFER_HPP
#endif // NDN_ENCODING_BUFFER_HPP
+102 -30
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -23,7 +23,8 @@
#include <boost/endian/conversion.hpp>
namespace ndn::encoding {
namespace ndn {
namespace encoding {
namespace endian = boost::endian;
@@ -34,7 +35,7 @@ Encoder::Encoder(size_t totalReserve, size_t reserveFromBack)
}
Encoder::Encoder(const Block& block)
: m_buffer(std::const_pointer_cast<Buffer>(block.getBuffer()))
: m_buffer(const_pointer_cast<Buffer>(block.getBuffer()))
, m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
, m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
{
@@ -94,40 +95,68 @@ Encoder::reserve(size_t size, bool addInFront)
}
size_t
Encoder::prependBytes(span<const uint8_t> bytes)
Encoder::prependByte(uint8_t value)
{
return prependRange(bytes.begin(), bytes.end());
reserveFront(1);
m_begin--;
*m_begin = value;
return 1;
}
size_t
Encoder::appendBytes(span<const uint8_t> bytes)
Encoder::appendByte(uint8_t value)
{
return appendRange(bytes.begin(), bytes.end());
reserveBack(1);
*m_end = value;
m_end++;
return 1;
}
size_t
Encoder::prependByteArray(const uint8_t* array, size_t length)
{
reserveFront(length);
m_begin -= length;
std::copy(array, array + length, m_begin);
return length;
}
size_t
Encoder::appendByteArray(const uint8_t* array, size_t length)
{
reserveBack(length);
std::copy(array, array + length, m_end);
m_end += length;
return length;
}
size_t
Encoder::prependVarNumber(uint64_t varNumber)
{
if (varNumber < 253) {
prependBytes({static_cast<uint8_t>(varNumber)});
prependByte(static_cast<uint8_t>(varNumber));
return 1;
}
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
prependBytes({253});
prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
prependByte(253);
return 3;
}
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
prependBytes({254});
prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
prependByte(254);
return 5;
}
else {
uint64_t value = endian::native_to_big(varNumber);
prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
prependBytes({255});
prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
prependByte(255);
return 9;
}
}
@@ -136,25 +165,25 @@ size_t
Encoder::appendVarNumber(uint64_t varNumber)
{
if (varNumber < 253) {
appendBytes({static_cast<uint8_t>(varNumber)});
appendByte(static_cast<uint8_t>(varNumber));
return 1;
}
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
appendBytes({253});
appendByte(253);
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
return 3;
}
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
appendBytes({254});
appendByte(254);
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
return 5;
}
else {
appendBytes({255});
appendByte(255);
uint64_t value = endian::native_to_big(varNumber);
appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
return 9;
}
}
@@ -163,19 +192,19 @@ size_t
Encoder::prependNonNegativeInteger(uint64_t varNumber)
{
if (varNumber <= std::numeric_limits<uint8_t>::max()) {
return prependBytes({static_cast<uint8_t>(varNumber)});
return prependByte(static_cast<uint8_t>(varNumber));
}
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
return prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
}
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
return prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
}
else {
uint64_t value = endian::native_to_big(varNumber);
return prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
}
}
@@ -183,20 +212,63 @@ size_t
Encoder::appendNonNegativeInteger(uint64_t varNumber)
{
if (varNumber <= std::numeric_limits<uint8_t>::max()) {
return appendBytes({static_cast<uint8_t>(varNumber)});
return appendByte(static_cast<uint8_t>(varNumber));
}
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
return appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
}
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
return appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
}
else {
uint64_t value = endian::native_to_big(varNumber);
return appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
}
}
} // namespace ndn::encoding
size_t
Encoder::prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
{
size_t totalLength = prependByteArray(array, arraySize);
totalLength += prependVarNumber(arraySize);
totalLength += prependVarNumber(type);
return totalLength;
}
size_t
Encoder::appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
{
size_t totalLength = appendVarNumber(type);
totalLength += appendVarNumber(arraySize);
totalLength += appendByteArray(array, arraySize);
return totalLength;
}
size_t
Encoder::prependBlock(const Block& block)
{
if (block.hasWire()) {
return prependByteArray(block.wire(), block.size());
}
else {
return prependByteArrayBlock(block.type(), block.value(), block.value_size());
}
}
size_t
Encoder::appendBlock(const Block& block)
{
if (block.hasWire()) {
return appendByteArray(block.wire(), block.size());
}
else {
return appendByteArrayBlock(block.type(), block.value(), block.value_size());
}
}
} // namespace encoding
} // namespace ndn
+138 -77
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,36 +19,45 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_ENCODING_ENCODER_HPP
#define NDN_CXX_ENCODING_ENCODER_HPP
#ifndef NDN_ENCODING_ENCODER_HPP
#define NDN_ENCODING_ENCODER_HPP
#include "ndn-cxx/encoding/block.hpp"
#include <algorithm>
namespace ndn::encoding {
namespace ndn {
namespace encoding {
/**
* @brief Helper class to perform TLV encoding.
*
* The interface of this class (mostly) matches that of the Estimator class.
*
* @brief Helper class to perform TLV encoding
* Interface of this class (mostly) matches interface of Estimator class
* @sa Estimator
*/
class Encoder : noncopyable
{
public: // common interface between Encoder and Estimator
/**
* @brief Prepend a sequence of bytes
* @brief Prepend a byte
*/
size_t
prependBytes(span<const uint8_t> bytes);
prependByte(uint8_t value);
/**
* @brief Append a sequence of bytes
* @brief Append a byte
*/
size_t
appendBytes(span<const uint8_t> bytes);
appendByte(uint8_t value);
/**
* @brief Prepend a byte array @p array of length @p length
*/
size_t
prependByteArray(const uint8_t* array, size_t length);
/**
* @brief Append a byte array @p array of length @p length
*/
size_t
appendByteArray(const uint8_t* array, size_t length);
/**
* @brief Prepend range of bytes from the range [@p first, @p last)
@@ -65,33 +74,57 @@ public: // common interface between Encoder and Estimator
appendRange(Iterator first, Iterator last);
/**
* @brief Prepend @p number encoded as a VAR-NUMBER in NDN-TLV format
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
size_t
prependVarNumber(uint64_t number);
prependVarNumber(uint64_t varNumber);
/**
* @brief Append @p number encoded as a VAR-NUMBER in NDN-TLV format
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
size_t
appendVarNumber(uint64_t number);
appendVarNumber(uint64_t varNumber);
/**
* @brief Prepend @p integer encoded as a NonNegativeInteger in NDN-TLV format
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
* @brief Prepend non-negative integer @p integer of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
size_t
prependNonNegativeInteger(uint64_t integer);
/**
* @brief Append @p integer encoded as a NonNegativeInteger in NDN-TLV format
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
* @brief Append non-negative integer @p integer of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
size_t
appendNonNegativeInteger(uint64_t integer);
/**
* @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
*/
size_t
prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
/**
* @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
*/
size_t
appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
/**
* @brief Prepend TLV block @p block
*/
size_t
prependBlock(const Block& block);
/**
* @brief Append TLV block @p block
*/
size_t
appendBlock(const Block& block);
public: // unique interface to the Encoder
using value_type = Buffer::value_type;
using iterator = Buffer::iterator;
@@ -150,83 +183,56 @@ public: // unique interface to the Encoder
* @brief Get size of the underlying buffer
*/
size_t
capacity() const noexcept
{
return m_buffer->size();
}
capacity() const noexcept;
/**
* @brief Get underlying buffer
*/
shared_ptr<Buffer>
getBuffer() const noexcept
{
return m_buffer;
}
getBuffer() const noexcept;
public: // accessors
/**
* @brief Returns an iterator pointing to the first byte of the encoded buffer
* @brief Get an iterator pointing to the first byte of the encoded buffer
*/
iterator
begin() noexcept
{
return m_begin;
}
begin();
/**
* @brief Returns an iterator pointing to the first byte of the encoded buffer
*/
const_iterator
begin() const noexcept
{
return m_begin;
}
/**
* @brief Returns an iterator pointing to the past-the-end byte of the encoded buffer
* @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
*/
iterator
end() noexcept
{
return m_end;
}
end();
/**
* @brief Returns an iterator pointing to the past-the-end byte of the encoded buffer
* @brief Get an iterator pointing to the first byte of the encoded buffer
*/
const_iterator
end() const noexcept
{
return m_end;
}
begin() const;
/**
* @brief Returns a pointer to the first byte of the encoded buffer
* @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
*/
const_iterator
end() const;
/**
* @brief Get a pointer to the first byte of the encoded buffer
*/
uint8_t*
data() noexcept
{
return &*m_begin;
}
buf();
/**
* @brief Returns a pointer to the first byte of the encoded buffer
* @brief Get a pointer to the first byte of the encoded buffer
*/
const uint8_t*
data() const noexcept
{
return &*m_begin;
}
buf() const;
/**
* @brief Returns the size of the encoded buffer
* @brief Get the size of the encoded buffer
*/
size_t
size() const noexcept
{
return static_cast<size_t>(std::distance(m_begin, m_end));
}
size() const noexcept;
/**
* @brief Create Block from the underlying buffer
@@ -247,17 +253,71 @@ private:
iterator m_end;
};
inline size_t
Encoder::size() const noexcept
{
return m_end - m_begin;
}
inline shared_ptr<Buffer>
Encoder::getBuffer() const noexcept
{
return m_buffer;
}
inline size_t
Encoder::capacity() const noexcept
{
return m_buffer->size();
}
inline Buffer::iterator
Encoder::begin()
{
return m_begin;
}
inline Buffer::iterator
Encoder::end()
{
return m_end;
}
inline Buffer::const_iterator
Encoder::begin() const
{
return m_begin;
}
inline Buffer::const_iterator
Encoder::end() const
{
return m_end;
}
inline uint8_t*
Encoder::buf()
{
return &(*m_begin);
}
inline const uint8_t*
Encoder::buf() const
{
return &(*m_begin);
}
template<class Iterator>
size_t
Encoder::prependRange(Iterator first, Iterator last)
{
using ValueType = typename std::iterator_traits<Iterator>::value_type;
static_assert(sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>);
static_assert(sizeof(ValueType) == 1 && !std::is_same<ValueType, bool>::value, "");
size_t length = std::distance(first, last);
reserveFront(length);
std::advance(m_begin, -length);
m_begin -= length;
std::copy(first, last, m_begin);
return length;
}
@@ -267,16 +327,17 @@ size_t
Encoder::appendRange(Iterator first, Iterator last)
{
using ValueType = typename std::iterator_traits<Iterator>::value_type;
static_assert(sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>);
static_assert(sizeof(ValueType) == 1 && !std::is_same<ValueType, bool>::value, "");
size_t length = std::distance(first, last);
reserveBack(length);
std::copy(first, last, m_end);
std::advance(m_end, length);
m_end += length;
return length;
}
} // namespace ndn::encoding
} // namespace encoding
} // namespace ndn
#endif // NDN_CXX_ENCODING_ENCODER_HPP
#endif // NDN_ENCODING_ENCODER_HPP
+4 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2021 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,8 +19,8 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_ENCODING_ENCODING_BUFFER_FWD_HPP
#define NDN_CXX_ENCODING_ENCODING_BUFFER_FWD_HPP
#ifndef NDN_ENCODING_ENCODING_BUFFER_FWD_HPP
#define NDN_ENCODING_ENCODING_BUFFER_FWD_HPP
#include "ndn-cxx/detail/common.hpp"
@@ -58,4 +58,4 @@ using encoding::EncodingEstimator;
template size_t \
ClassName::wireEncode<::ndn::encoding::EstimatorTag>(::ndn::EncodingEstimator&) const \
#endif // NDN_CXX_ENCODING_ENCODING_BUFFER_FWD_HPP
#endif // NDN_ENCODING_ENCODING_BUFFER_FWD_HPP
+8 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,14 +19,15 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_ENCODING_ENCODING_BUFFER_HPP
#define NDN_CXX_ENCODING_ENCODING_BUFFER_HPP
#ifndef NDN_ENCODING_ENCODING_BUFFER_HPP
#define NDN_ENCODING_ENCODING_BUFFER_HPP
#include "ndn-cxx/encoding/encoding-buffer-fwd.hpp"
#include "ndn-cxx/encoding/encoder.hpp"
#include "ndn-cxx/encoding/estimator.hpp"
namespace ndn::encoding {
namespace ndn {
namespace encoding {
/**
* @brief EncodingImpl specialization for actual TLV encoding
@@ -61,6 +62,7 @@ public:
}
};
} // namespace ndn::encoding
} // namespace encoding
} // namespace ndn
#endif // NDN_CXX_ENCODING_ENCODING_BUFFER_HPP
#endif // NDN_ENCODING_ENCODING_BUFFER_HPP
+107
View File
@@ -0,0 +1,107 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* 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.
*/
#include "ndn-cxx/encoding/estimator.hpp"
namespace ndn {
namespace encoding {
size_t
Estimator::prependVarNumber(uint64_t varNumber) const noexcept
{
if (varNumber < 253) {
return 1;
}
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
return 3;
}
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
return 5;
}
else {
return 9;
}
}
size_t
Estimator::appendVarNumber(uint64_t varNumber) const noexcept
{
return prependVarNumber(varNumber);
}
size_t
Estimator::prependNonNegativeInteger(uint64_t varNumber) const noexcept
{
if (varNumber <= std::numeric_limits<uint8_t>::max()) {
return 1;
}
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
return 2;
}
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
return 4;
}
else {
return 8;
}
}
size_t
Estimator::appendNonNegativeInteger(uint64_t varNumber) const noexcept
{
return prependNonNegativeInteger(varNumber);
}
size_t
Estimator::prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
{
size_t totalLength = arraySize;
totalLength += prependVarNumber(arraySize);
totalLength += prependVarNumber(type);
return totalLength;
}
size_t
Estimator::appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
{
return prependByteArrayBlock(type, array, arraySize);
}
size_t
Estimator::prependBlock(const Block& block) const
{
if (block.hasWire()) {
return block.size();
}
else {
return prependByteArrayBlock(block.type(), block.value(), block.value_size());
}
}
size_t
Estimator::appendBlock(const Block& block) const
{
return prependBlock(block);
}
} // namespace encoding
} // namespace ndn
+80 -46
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,98 +19,132 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_ENCODING_ESTIMATOR_HPP
#define NDN_CXX_ENCODING_ESTIMATOR_HPP
#ifndef NDN_ENCODING_ESTIMATOR_HPP
#define NDN_ENCODING_ESTIMATOR_HPP
#include "ndn-cxx/encoding/block.hpp"
namespace ndn::encoding {
namespace ndn {
namespace encoding {
/**
* @brief Helper class to estimate size of TLV encoding.
*
* The interface of this class (mostly) matches that of the Encoder class.
*
* @brief Helper class to estimate size of TLV encoding
* Interface of this class (mostly) matches interface of Encoder class
* @sa Encoder
*/
class Estimator : noncopyable
{
public: // common interface between Encoder and Estimator
/**
* @brief Prepend a sequence of bytes
* @brief Prepend a byte
*/
constexpr size_t
prependBytes(span<const uint8_t> bytes) const noexcept
prependByte(uint8_t) const noexcept
{
return bytes.size();
return 1;
}
/**
* @brief Append a sequence of bytes
* @brief Append a byte
*/
constexpr size_t
appendBytes(span<const uint8_t> bytes) const noexcept
appendByte(uint8_t) const noexcept
{
return bytes.size();
return 1;
}
/**
* @brief Prepend bytes from the range [@p first, @p last)
* @brief Prepend a byte array @p array of length @p length
*/
constexpr size_t
prependByteArray(const uint8_t*, size_t length) const noexcept
{
return length;
}
/**
* @brief Append a byte array @p array of length @p length
*/
constexpr size_t
appendByteArray(const uint8_t*, size_t length) const noexcept
{
return length;
}
/**
* @brief Prepend range of bytes from the range [@p first, @p last)
*/
template<class Iterator>
constexpr size_t
size_t
prependRange(Iterator first, Iterator last) const noexcept
{
return static_cast<size_t>(std::distance(first, last));
return std::distance(first, last);
}
/**
* @brief Append bytes from the range [@p first, @p last)
* @brief Append range of bytes from the range [@p first, @p last)
*/
template<class Iterator>
constexpr size_t
size_t
appendRange(Iterator first, Iterator last) const noexcept
{
return static_cast<size_t>(std::distance(first, last));
return std::distance(first, last);
}
/**
* @brief Prepend @p n in VarNumber encoding
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
constexpr size_t
prependVarNumber(uint64_t n) const noexcept
{
return tlv::sizeOfVarNumber(n);
}
size_t
prependVarNumber(uint64_t varNumber) const noexcept;
/**
* @brief Append @p n in VarNumber encoding
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
constexpr size_t
appendVarNumber(uint64_t n) const noexcept
{
return tlv::sizeOfVarNumber(n);
}
size_t
appendVarNumber(uint64_t varNumber) const noexcept;
/**
* @brief Prepend @p n in NonNegativeInteger encoding
* @brief Prepend non-negative integer @p integer of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
constexpr size_t
prependNonNegativeInteger(uint64_t n) const noexcept
{
return tlv::sizeOfNonNegativeInteger(n);
}
size_t
prependNonNegativeInteger(uint64_t integer) const noexcept;
/**
* @brief Append @p n in NonNegativeInteger encoding
* @brief Append non-negative integer @p integer of NDN TLV encoding
* @sa http://named-data.net/doc/ndn-tlv/
*/
constexpr size_t
appendNonNegativeInteger(uint64_t n) const noexcept
{
return tlv::sizeOfNonNegativeInteger(n);
}
size_t
appendNonNegativeInteger(uint64_t integer) const noexcept;
/**
* @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
*/
size_t
prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept;
/**
* @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
*/
size_t
appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept;
/**
* @brief Prepend TLV block @p block
*/
size_t
prependBlock(const Block& block) const;
/**
* @brief Append TLV block @p block
*/
size_t
appendBlock(const Block& block) const;
};
} // namespace ndn::encoding
} // namespace encoding
} // namespace ndn
#endif // NDN_CXX_ENCODING_ESTIMATOR_HPP
#endif // NDN_ENCODING_ESTIMATOR_HPP
+17 -11
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 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).
*
@@ -29,7 +29,8 @@
#include <map>
#include <ostream>
namespace ndn::nfd {
namespace ndn {
namespace nfd {
std::ostream&
operator<<(std::ostream& os, FaceScope faceScope)
@@ -121,8 +122,8 @@ operator>>(std::istream& is, RouteOrigin& routeOrigin)
routeOrigin = ROUTE_ORIGIN_STATIC;
else {
// To reject negative numbers, we parse as a wider signed type, and compare with the range.
using RouteOriginUnderlyingType = std::underlying_type_t<RouteOrigin>;
static_assert(std::numeric_limits<RouteOriginUnderlyingType>::max() <= std::numeric_limits<int>::max());
static_assert(std::numeric_limits<std::underlying_type_t<RouteOrigin>>::max() <=
std::numeric_limits<int>::max(), "");
int v = -1;
try {
@@ -131,8 +132,8 @@ operator>>(std::istream& is, RouteOrigin& routeOrigin)
catch (const boost::bad_lexical_cast&) {
}
if (v >= std::numeric_limits<RouteOriginUnderlyingType>::min() &&
v <= std::numeric_limits<RouteOriginUnderlyingType>::max()) {
if (v >= std::numeric_limits<std::underlying_type_t<RouteOrigin>>::min() &&
v <= std::numeric_limits<std::underlying_type_t<RouteOrigin>>::max()) {
routeOrigin = static_cast<RouteOrigin>(v);
}
else {
@@ -175,13 +176,17 @@ operator<<(std::ostream& os, RouteFlags routeFlags)
return os << "none";
}
static const std::map<RouteFlags, std::string_view> knownBits = {
{ROUTE_FLAG_CHILD_INHERIT, "child-inherit"sv},
{ROUTE_FLAG_CAPTURE, "capture"sv}
static const std::map<RouteFlags, std::string> knownBits = {
{ROUTE_FLAG_CHILD_INHERIT, "child-inherit"},
{ROUTE_FLAG_CAPTURE, "capture"}
};
auto join = make_ostream_joiner(os, '|');
for (auto [bit, token] : knownBits) {
for (const auto& pair : knownBits) {
RouteFlags bit = ROUTE_FLAGS_NONE;
std::string token;
std::tie(bit, token) = pair;
if ((routeFlags & bit) != 0) {
join = token;
routeFlags = static_cast<RouteFlags>(routeFlags & ~bit);
@@ -195,4 +200,5 @@ operator<<(std::ostream& os, RouteFlags routeFlags)
return os;
}
} // namespace ndn::nfd
} // namespace nfd
} // namespace ndn
+12 -12
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2023 Regents of the University of California.
* Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -19,16 +19,15 @@
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_CXX_ENCODING_NFD_CONSTANTS_HPP
#define NDN_CXX_ENCODING_NFD_CONSTANTS_HPP
#ifndef NDN_ENCODING_NFD_CONSTANTS_HPP
#define NDN_ENCODING_NFD_CONSTANTS_HPP
#include <cstdint>
#include <iosfwd>
#include <limits>
#include "ndn-cxx/detail/common.hpp"
namespace ndn::nfd {
namespace ndn {
namespace nfd {
inline constexpr uint64_t INVALID_FACE_ID = 0;
const uint64_t INVALID_FACE_ID = 0;
/** \ingroup management
*/
@@ -87,7 +86,7 @@ std::ostream&
operator<<(std::ostream& os, FaceEventKind faceEventKind);
/** \ingroup management
* \brief CS enablement flags.
* \brief CS enablement flags
* \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
*/
enum CsFlagBit {
@@ -108,7 +107,7 @@ enum RouteOrigin : uint16_t {
ROUTE_ORIGIN_STATIC = 255,
};
/** \brief Extract RouteOrigin from stream.
/** \brief extract RouteOrigin from stream
* \post if the first token in \p contains a valid RouteOrigin as string or numeric value, it is
* extracted into \p routeOrigin ; otherwise, \p routeOrigin is set to \p ROUTE_ORIGIN_NONE ,
* and failbit is set on \p is
@@ -130,6 +129,7 @@ enum RouteFlags : uint64_t {
std::ostream&
operator<<(std::ostream& os, RouteFlags routeFlags);
} // namespace ndn::nfd
} // namespace nfd
} // namespace ndn
#endif // NDN_CXX_ENCODING_NFD_CONSTANTS_HPP
#endif // NDN_ENCODING_NFD_CONSTANTS_HPP
Loaded 100 of 720 files, more files were not shown because too many files have changed in this diff. Show more