Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a46d41df0e | ||
|
|
922330b1e0 | ||
|
|
bce3cb528b | ||
|
|
7015694293 | ||
|
|
69692abf50 | ||
|
|
32e7609edf | ||
|
|
d47cd63b1b | ||
|
|
f59e58f202 | ||
|
|
5200904303 | ||
|
|
dda258af14 | ||
|
|
3e7fc83c12 | ||
|
|
f84bac5a7a | ||
|
|
f4cfed1a61 | ||
|
|
9f8b10e350 | ||
|
|
04d5ce685d | ||
|
|
952d6fd3d7 | ||
|
|
b53fe6444b | ||
|
|
a4d7fe0f22 | ||
|
|
457f135980 | ||
|
|
d657d53eea | ||
|
|
359135cfb2 | ||
|
|
4f8dd96fbf | ||
|
|
812d615717 | ||
|
|
e4b2238b33 | ||
|
|
1705744468 | ||
|
|
c0822fa4a5 | ||
|
|
7b8e797c32 | ||
|
|
9c33b90fd3 | ||
|
|
5f35f64d9a | ||
|
|
a3148081ce | ||
|
|
782a1d1621 | ||
|
|
67f797f9a3 | ||
|
|
21e0193e5c | ||
|
|
e34a2825f1 | ||
|
|
45898d2215 | ||
|
|
bd72431945 | ||
|
|
87fc0f8d6f | ||
|
|
981db808cb | ||
|
|
1cb619e63b | ||
|
|
ded17426c6 | ||
|
|
e4d745d41f | ||
|
|
43bb2315ea | ||
|
|
3bdc1decf6 | ||
|
|
30c37ab9bf | ||
|
|
c14a8acf39 | ||
|
|
971d9621ce | ||
|
|
3406dc9742 | ||
|
|
85a36632a7 | ||
|
|
7a36ac7d9d | ||
|
|
057d149fda | ||
|
|
7003e0bc66 | ||
|
|
3cf75dc10b | ||
|
|
068a71d6f0 | ||
|
|
0064c1dd91 | ||
|
|
cdf7845986 | ||
|
|
8dc473a724 | ||
|
|
6f09ab6cde | ||
|
|
cfb1a315ed | ||
|
|
63086448bf | ||
|
|
47456e7d98 | ||
|
|
b922c8891c | ||
|
|
9e5b8af1f5 | ||
|
|
6a88b5f435 | ||
|
|
d9c520bed9 | ||
|
|
d214744ab8 | ||
|
|
2a58815ee3 |
No files matched your search
+30
-9
@@ -1,9 +1,30 @@
|
||||
.DS*
|
||||
.waf-1*
|
||||
.waf3-*
|
||||
.lock*
|
||||
*.pyc
|
||||
*.pyo
|
||||
build/
|
||||
VERSION
|
||||
unit-tests.conf
|
||||
# Emacs
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
.\#*
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
||||
|
||||
# Waf build system
|
||||
/build/
|
||||
.waf-*-*/
|
||||
.waf3-*-*/
|
||||
.lock-waf*
|
||||
|
||||
# Compiled python code
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# Other
|
||||
/unit-tests.conf
|
||||
/VERSION
|
||||
@@ -32,3 +32,18 @@ if has Ubuntu $NODE_LABELS; then
|
||||
sudo easy_install --upgrade gcovr
|
||||
fi
|
||||
fi
|
||||
|
||||
if has CentOS $NODE_LABELS; then
|
||||
sudo yum -y install yum-utils pkgconfig libpcap-devel \
|
||||
openssl-devel libtranslit-icu \
|
||||
python-devel sqlite-devel \
|
||||
devtoolset-7-libasan-devel \
|
||||
devtoolset-7-liblsan-devel
|
||||
sudo yum -y groupinstall 'Development Tools'
|
||||
|
||||
svn checkout https://github.com/cmscaltech/sandie-ndn/trunk/packaging/RPMS/x86_64
|
||||
sudo rpm -U --force x86_64/boost-license*
|
||||
sudo rpm -U --force x86_64/boost-doc-html*
|
||||
sudo rpm -U --force x86_64/libboost*
|
||||
sudo rpm -U --force x86_64/boost-devel*
|
||||
fi
|
||||
@@ -37,14 +37,14 @@ fi
|
||||
|
||||
sudo rm -f /usr/local/bin/ndnsec*
|
||||
sudo rm -fr /usr/local/include/ndn-cxx
|
||||
sudo rm -f /usr/local/lib/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx.pc
|
||||
sudo rm -f /usr/local/lib{,64}/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
|
||||
|
||||
pushd ndn-cxx >/dev/null
|
||||
|
||||
./waf configure --color=yes --enable-shared --disable-static --without-osx-keychain
|
||||
./waf build --color=yes -j${WAF_JOBS:-1}
|
||||
sudo env "PATH=$PATH" ./waf install --color=yes
|
||||
sudo_preserve_env PATH -- ./waf install --color=yes
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
@@ -17,7 +17,7 @@ elif [[ -z $DISABLE_ASAN ]]; then
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
|
||||
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
|
||||
# Configure/build in optimized mode with tests
|
||||
@@ -25,14 +25,14 @@ if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
|
||||
# Configure/build in optimized mode without tests, but with "other tests"
|
||||
./waf --color=yes configure --with-other-tests
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
|
||||
# Cleanup
|
||||
sudo env "PATH=$PATH" ./waf --color=yes distclean
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
fi
|
||||
|
||||
# Configure/build in debug mode with tests and without precompiled headers
|
||||
@@ -42,4 +42,4 @@ fi
|
||||
# (tests will be run against debug version)
|
||||
|
||||
# Install
|
||||
sudo env "PATH=$PATH" ./waf --color=yes install
|
||||
sudo_preserve_env PATH -- ./waf --color=yes install
|
||||
@@ -41,6 +41,9 @@ ASAN_OPTIONS+=":strict_string_checks=true"
|
||||
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
|
||||
export ASAN_OPTIONS
|
||||
|
||||
export BOOST_TEST_BUILD_INFO=1
|
||||
export BOOST_TEST_COLOR_OUTPUT=1
|
||||
|
||||
# First run all tests as unprivileged user
|
||||
./build/unit-tests-core $(ut_log_args core)
|
||||
./build/unit-tests-daemon $(ut_log_args daemon)
|
||||
@@ -48,7 +51,9 @@ export ASAN_OPTIONS
|
||||
./build/unit-tests-tools $(ut_log_args tools)
|
||||
|
||||
# Then use sudo to run those tests that need superuser powers
|
||||
sudo -E ./build/unit-tests-core -t TestPrivilegeHelper $(ut_log_args core-privilege)
|
||||
sudo -E ./build/unit-tests-daemon -t Face/*Ethernet* $(ut_log_args daemon-ethernet)
|
||||
sudo -E ./build/unit-tests-daemon -t Face/TestUdpFactory $(ut_log_args daemon-udp-factory)
|
||||
sudo -E ./build/unit-tests-daemon -t Mgmt/TestGeneralConfigSection/UserAndGroupConfig,NoUserConfig $(ut_log_args daemon-user-config)
|
||||
sudo_preserve_env ASAN_OPTIONS BOOST_TEST_COLOR_OUTPUT -- \
|
||||
./build/unit-tests-core -t TestPrivilegeHelper $(ut_log_args core-privilege)
|
||||
sudo_preserve_env ASAN_OPTIONS BOOST_TEST_COLOR_OUTPUT -- \
|
||||
./build/unit-tests-daemon -t Face/*Ethernet* $(ut_log_args daemon-ethernet)
|
||||
sudo_preserve_env ASAN_OPTIONS BOOST_TEST_COLOR_OUTPUT -- \
|
||||
./build/unit-tests-daemon -t Face/TestUdpFactory $(ut_log_args daemon-udp)
|
||||
@@ -13,13 +13,13 @@ Environment Variables Used in Build Scripts
|
||||
|
||||
* `[OS_TYPE]`: `Linux`
|
||||
* `[DISTRO_TYPE]`: `Ubuntu`
|
||||
* `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04`
|
||||
* `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`
|
||||
|
||||
Possible values for OS X / macOS:
|
||||
|
||||
* `[OS_TYPE]`: `OSX`
|
||||
* `[DISTRO_TYPE]`: `OSX` (can be absent)
|
||||
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12`
|
||||
* `[DISTRO_VERSION]`: `OSX-10.11`, `OSX-10.12`, `OSX-10.13`
|
||||
|
||||
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
|
||||
the build scripts can perform different tasks.
|
||||
|
||||
@@ -16,3 +16,22 @@ has() {
|
||||
set ${saved_xtrace}
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
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[@]}" "$@"
|
||||
}
|
||||
+40
-57
@@ -1,5 +1,5 @@
|
||||
language: cpp
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
sudo: required
|
||||
env:
|
||||
global:
|
||||
@@ -10,101 +10,84 @@ matrix:
|
||||
include:
|
||||
# Linux/gcc
|
||||
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
|
||||
- os: linux
|
||||
env: COMPILER=g++-4.8
|
||||
- os: linux
|
||||
env: COMPILER=g++-4.9
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-4.9
|
||||
- os: linux
|
||||
env: COMPILER=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-5
|
||||
- os: linux
|
||||
env: COMPILER=g++-6
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-6
|
||||
- os: linux
|
||||
env: COMPILER=g++-7
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-7
|
||||
- os: linux
|
||||
env: COMPILER=g++-8
|
||||
|
||||
# Linux/clang
|
||||
# https://apt.llvm.org/
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.5
|
||||
addons:
|
||||
apt:
|
||||
packages: clang-3.5
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.6
|
||||
addons:
|
||||
apt:
|
||||
packages: clang-3.6
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-precise-3.7", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.7
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.8
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-precise-3.8", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.8
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.9 DISABLE_ASAN=yes
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-3.9", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-3.9
|
||||
env: COMPILER=clang++-3.9
|
||||
- os: linux
|
||||
env: COMPILER=clang++-4.0
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-4.0", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-4.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-5.0
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty-5.0", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-5.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-6.0
|
||||
addons:
|
||||
apt:
|
||||
sources: ["llvm-toolchain-trusty", "ubuntu-toolchain-r-test"]
|
||||
packages: clang-6.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-7
|
||||
- os: linux
|
||||
env: COMPILER=clang++-8
|
||||
|
||||
# macOS/clang
|
||||
# https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
|
||||
# https://docs.travis-ci.com/user/reference/osx/#OS-X-Version
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
env: OSX_VERSION=10.11
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
env: OSX_VERSION=10.11
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
env: OSX_VERSION=10.12
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
env: OSX_VERSION=10.12
|
||||
- os: osx
|
||||
osx_image: xcode9.4
|
||||
env: OSX_VERSION=10.13
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
env: OSX_VERSION=10.13
|
||||
|
||||
allow_failures:
|
||||
- env: COMPILER=clang++-6.0
|
||||
- env: COMPILER=clang++-3.6
|
||||
- env: COMPILER=clang++-3.7 DISABLE_ASAN=yes
|
||||
- env: COMPILER=clang++-8
|
||||
|
||||
fast_finish: true
|
||||
|
||||
install: |
|
||||
case ${COMPILER} in
|
||||
g++-[6789])
|
||||
travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
travis_retry sudo apt-get -qq update
|
||||
travis_retry sudo apt-get -qy install "${COMPILER}"
|
||||
;;
|
||||
clang++-*)
|
||||
CLANG_VERSION=${COMPILER/clang++}
|
||||
if [[ ${CLANG_VERSION} != "-3."* ]]; then
|
||||
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/xenial/ llvm-toolchain-xenial${CLANG_VERSION/-8} main"
|
||||
fi
|
||||
travis_retry sudo apt-get -qq update
|
||||
travis_retry sudo apt-get -qy install "clang${CLANG_VERSION}"
|
||||
;;
|
||||
esac
|
||||
|
||||
before_script:
|
||||
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-14.04"; fi
|
||||
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-16.04"; fi
|
||||
- if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi
|
||||
- if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi
|
||||
- ${CXX:-c++} --version
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
#
|
||||
# Copyright (c) 2014, Regents of the University of California
|
||||
#
|
||||
# GPL 3.0 license, see the COPYING.md file for more information
|
||||
|
||||
from waflib import Configure
|
||||
|
||||
BOOST_ASIO_HAS_KQUEUE_CHECK = '''
|
||||
#include <boost/asio.hpp>
|
||||
#if defined(BOOST_ASIO_HAS_KQUEUE) and BOOST_VERSION == 105600
|
||||
#error "Ethernet face support cannot be enabled on this platform with boost 1.56"
|
||||
#endif
|
||||
'''
|
||||
|
||||
@Configure.conf
|
||||
def check_asio_pcap_support(conf):
|
||||
# https://svn.boost.org/trac/boost/ticket/10367
|
||||
if conf.check_cxx(msg='Checking if Ethernet face support can be enabled',
|
||||
fragment=BOOST_ASIO_HAS_KQUEUE_CHECK,
|
||||
features='cxx', use='BOOST', mandatory=False):
|
||||
conf.define('HAVE_ASIO_PCAP_SUPPORT', 1)
|
||||
conf.env['HAVE_ASIO_PCAP_SUPPORT'] = True
|
||||
+6
-2
@@ -54,8 +54,7 @@ from waflib import Utils, Logs, Errors
|
||||
from waflib.Configure import conf
|
||||
from waflib.TaskGen import feature, after_method
|
||||
|
||||
BOOST_LIBS = ['/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu',
|
||||
'/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
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 = '''
|
||||
@@ -404,6 +403,11 @@ def check_boost(self, *k, **kw):
|
||||
|
||||
var = kw.get('uselib_store', 'BOOST')
|
||||
|
||||
self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
|
||||
if self.env.DPKG_ARCHITECTURE:
|
||||
deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
|
||||
BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())
|
||||
|
||||
self.start_msg('Checking boost includes')
|
||||
self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
|
||||
versions = self.boost_get_version(inc)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
from waflib import TaskGen, Logs
|
||||
from waflib import TaskGen
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage',
|
||||
help='''Set compiler flags for gcc to enable code coverage information''')
|
||||
opt.add_option('--with-coverage', action='store_true', default=False,
|
||||
help='Add compiler flags to enable code coverage information')
|
||||
|
||||
def configure(conf):
|
||||
if conf.options.with_coverage:
|
||||
if not conf.options.debug:
|
||||
conf.fatal("Code coverage flags require debug mode compilation (add --debug)")
|
||||
conf.fatal('Code coverage flags require debug mode compilation (add --debug)')
|
||||
conf.check_cxx(cxxflags=['-fprofile-arcs', '-ftest-coverage', '-fPIC'],
|
||||
linkflags=['-fprofile-arcs'], uselib_store='GCOV', mandatory=True)
|
||||
|
||||
|
||||
@@ -1,44 +1,45 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
from waflib import Logs, Configure, Utils
|
||||
from waflib import Configure, Logs, Utils
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug',
|
||||
help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''')
|
||||
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
|
||||
help='Compile in debugging mode with minimal optimizations (-O0 or -Og)')
|
||||
|
||||
def configure(conf):
|
||||
conf.start_msg('Checking C++ compiler version')
|
||||
|
||||
cxx = conf.env['CXX_NAME'] # CXX_NAME is the generic name of the compiler
|
||||
ccver = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
cxx = conf.env.CXX_NAME # generic name of the compiler
|
||||
ccver = tuple(int(i) for i in conf.env.CC_VERSION)
|
||||
ccverstr = '.'.join(conf.env.CC_VERSION)
|
||||
errmsg = ''
|
||||
warnmsg = ''
|
||||
if cxx == 'gcc':
|
||||
if ccver < (4, 8, 2):
|
||||
if ccver < (5, 3, 0):
|
||||
errmsg = ('The version of gcc you are using is too old.\n'
|
||||
'The minimum supported gcc version is 4.8.2.')
|
||||
'The minimum supported gcc version is 5.3.0.')
|
||||
conf.flags = GccFlags()
|
||||
elif cxx == 'clang':
|
||||
if ccver < (3, 4, 0):
|
||||
if ccver < (3, 6, 0):
|
||||
errmsg = ('The version of clang you are using is too old.\n'
|
||||
'The minimum supported clang version is 3.4.0.')
|
||||
'The minimum supported clang version is 3.6.0.')
|
||||
conf.flags = ClangFlags()
|
||||
else:
|
||||
warnmsg = 'Note: %s compiler is unsupported' % cxx
|
||||
conf.flags = CompilerFlags()
|
||||
|
||||
if errmsg:
|
||||
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED')
|
||||
conf.end_msg(ccverstr, color='RED')
|
||||
conf.fatal(errmsg)
|
||||
elif warnmsg:
|
||||
conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW')
|
||||
conf.end_msg(ccverstr, color='YELLOW')
|
||||
Logs.warn(warnmsg)
|
||||
else:
|
||||
conf.end_msg('.'.join(conf.env['CC_VERSION']))
|
||||
conf.end_msg(ccverstr)
|
||||
|
||||
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
|
||||
|
||||
# General flags are always applied (e.g., selecting C++11 mode)
|
||||
# General flags are always applied (e.g., selecting C++ language standard)
|
||||
generalFlags = conf.flags.getGeneralFlags(conf)
|
||||
conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
|
||||
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
|
||||
@@ -53,10 +54,10 @@ def check_compiler_flags(conf):
|
||||
extraFlags = conf.flags.getDebugFlags(conf)
|
||||
if conf.areCustomCxxflagsPresent:
|
||||
missingFlags = [x for x in extraFlags['CXXFLAGS'] if x not in conf.env.CXXFLAGS]
|
||||
if len(missingFlags) > 0:
|
||||
Logs.warn("Selected debug mode, but CXXFLAGS is set to a custom value '%s'"
|
||||
% " ".join(conf.env.CXXFLAGS))
|
||||
Logs.warn("Default flags '%s' are not activated" % " ".join(missingFlags))
|
||||
if missingFlags:
|
||||
Logs.warn('Selected debug mode, but CXXFLAGS is set to a custom value "%s"'
|
||||
% ' '.join(conf.env.CXXFLAGS))
|
||||
Logs.warn('Default flags "%s" will not be used' % ' '.join(missingFlags))
|
||||
else:
|
||||
extraFlags = conf.flags.getOptimizedFlags(conf)
|
||||
|
||||
@@ -106,6 +107,9 @@ def add_supported_linkflags(self, linkflags):
|
||||
|
||||
|
||||
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': []}
|
||||
@@ -124,7 +128,7 @@ class GccBasicFlags(CompilerFlags):
|
||||
"""
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++11']
|
||||
flags['CXXFLAGS'] += ['-std=c++14']
|
||||
return flags
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
@@ -160,25 +164,19 @@ class GccBasicFlags(CompilerFlags):
|
||||
class GccFlags(GccBasicFlags):
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccFlags, self).getDebugFlags(conf)
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
if version < (5, 1, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccFlags, self).getOptimizedFlags(conf)
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
if version < (5, 1, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
return flags
|
||||
|
||||
class ClangFlags(GccBasicFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getGeneralFlags(conf)
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
if Utils.unversioned_sys_platform() == 'darwin' and version >= (9, 0, 0): # Bug #4296
|
||||
if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0):
|
||||
# Bug #4296
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include']] # for MacPorts
|
||||
return flags
|
||||
@@ -188,15 +186,13 @@ class ClangFlags(GccBasicFlags):
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wextra-semi',
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-error=deprecated-register',
|
||||
'-Wno-error=infinite-recursion', # Bug #3358
|
||||
'-Wno-error=keyword-macro', # Bug #3235
|
||||
'-Wno-error=unneeded-internal-declaration', # Bug #1588
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
version = self.getCompilerVersion(conf)
|
||||
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
|
||||
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
|
||||
if version < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
@@ -206,7 +202,9 @@ class ClangFlags(GccBasicFlags):
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
version = self.getCompilerVersion(conf)
|
||||
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
|
||||
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
|
||||
if version < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
return flags
|
||||
@@ -4,10 +4,10 @@ from waflib import Options, Logs
|
||||
from waflib.Configure import conf
|
||||
|
||||
def addDependencyOptions(self, opt, name, extraHelp=''):
|
||||
opt.add_option('--with-%s' % name, type='string', default=None,
|
||||
dest='with_%s' % name,
|
||||
opt.add_option('--with-%s' % name, metavar='PATH',
|
||||
help='Path to %s, e.g., /usr/local %s' % (name, extraHelp))
|
||||
setattr(Options.OptionsContext, "addDependencyOptions", addDependencyOptions)
|
||||
|
||||
setattr(Options.OptionsContext, 'addDependencyOptions', addDependencyOptions)
|
||||
|
||||
@conf
|
||||
def checkDependency(self, name, **kw):
|
||||
@@ -18,8 +18,8 @@ def checkDependency(self, name, **kw):
|
||||
kw['mandatory'] = kw.get('mandatory', True)
|
||||
|
||||
if root:
|
||||
isOk = self.check_cxx(includes="%s/include" % root,
|
||||
libpath="%s/lib" % root,
|
||||
isOk = self.check_cxx(includes='%s/include' % root,
|
||||
libpath='%s/lib' % root,
|
||||
**kw)
|
||||
else:
|
||||
isOk = self.check_cxx(**kw)
|
||||
|
||||
+5
-10
@@ -52,7 +52,7 @@ Note that precompiled header must have multiple inclusion guards. If the guards
|
||||
"""
|
||||
|
||||
import os
|
||||
from waflib import Task, TaskGen, Logs, Utils
|
||||
from waflib import Task, TaskGen, Utils
|
||||
from waflib.Tools import c_preproc, cxx
|
||||
|
||||
|
||||
@@ -67,11 +67,6 @@ def options(opt):
|
||||
|
||||
def configure(conf):
|
||||
if (conf.options.with_pch and conf.env['COMPILER_CXX'] in PCH_COMPILER_OPTIONS.keys()):
|
||||
if Utils.unversioned_sys_platform() == "darwin" and conf.env['CXX_NAME'] == 'clang':
|
||||
version = tuple(int(i) for i in conf.env['CC_VERSION'])
|
||||
if version < (6, 1, 0):
|
||||
# Issue #2804
|
||||
return
|
||||
conf.env.WITH_PCH = True
|
||||
flags = PCH_COMPILER_OPTIONS[conf.env['COMPILER_CXX']]
|
||||
conf.env.CXXPCH_F = flags[0]
|
||||
@@ -95,8 +90,8 @@ def apply_pch(self):
|
||||
|
||||
if getattr(self, 'name', None):
|
||||
try:
|
||||
task = self.bld.pch_tasks[self.name]
|
||||
self.bld.fatal("Duplicated 'pch' task with name %r" % self.name)
|
||||
task = self.bld.pch_tasks["%s.%s" % (self.name, self.idx)]
|
||||
self.bld.fatal("Duplicated 'pch' task with name %r" % "%s.%s" % (self.name, self.idx))
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -109,7 +104,7 @@ def apply_pch(self):
|
||||
|
||||
self.pch_task = task
|
||||
if getattr(self, 'name', None):
|
||||
self.bld.pch_tasks[self.name] = task
|
||||
self.bld.pch_tasks["%s.%s" % (self.name, self.idx)] = task
|
||||
|
||||
@TaskGen.feature('cxx')
|
||||
@TaskGen.after_method('process_source', 'propagate_uselib_vars')
|
||||
@@ -134,7 +129,7 @@ def add_pch(self):
|
||||
x.env.append_value('CXXFLAGS', self.env['CXXPCH_F'] + [pch.target])
|
||||
|
||||
class gchx(Task.Task):
|
||||
run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${CXXPCH_FLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXXPCH_F:SRC} ${CXX_SRC_F}${SRC[0].abspath()} ${CXX_TGT_F}${TGT[0].abspath()}'
|
||||
run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CXXPCH_FLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXXPCH_F:SRC} ${CXX_SRC_F}${SRC[0].abspath()} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}'
|
||||
scan = c_preproc.scan
|
||||
color = 'BLUE'
|
||||
ext_out=['.h']
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
#
|
||||
# Copyright (c) 2014, Regents of the University of California
|
||||
#
|
||||
# GPL 3.0 license, see the COPYING.md file for more information
|
||||
|
||||
from waflib import Configure
|
||||
|
||||
IS_MOVE_CONSTRUCTIBLE_CHECK = '''
|
||||
#include <type_traits>
|
||||
static_assert(std::is_move_constructible<int>::value, "");
|
||||
'''
|
||||
|
||||
def configure(conf):
|
||||
if conf.check_cxx(msg='Checking for std::is_move_constructible',
|
||||
fragment=IS_MOVE_CONSTRUCTIBLE_CHECK,
|
||||
features='cxx', mandatory=False):
|
||||
conf.define('HAVE_IS_MOVE_CONSTRUCTIBLE', 1)
|
||||
conf.env['HAVE_IS_MOVE_CONSTRUCTIBLE'] = True
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
#
|
||||
# Copyright (c) 2014, Regents of the University of California
|
||||
# Copyright (c) 2014-2018, Regents of the University of California
|
||||
#
|
||||
# GPL 3.0 license, see the COPYING.md file for more information
|
||||
|
||||
@@ -15,8 +15,9 @@ BOOST_ASIO_HAS_LOCAL_SOCKETS_CHECK = '''
|
||||
|
||||
def addUnixOptions(self, opt):
|
||||
opt.add_option('--force-unix-socket', action='store_true', default=False,
|
||||
dest='force_unix_socket', help='''Forcefully enable Unix sockets support''')
|
||||
setattr(Options.OptionsContext, "addUnixOptions", addUnixOptions)
|
||||
help='Forcefully enable Unix sockets support')
|
||||
|
||||
setattr(Options.OptionsContext, 'addUnixOptions', addUnixOptions)
|
||||
|
||||
def configure(conf):
|
||||
def boost_asio_has_local_sockets():
|
||||
@@ -26,4 +27,4 @@ def configure(conf):
|
||||
|
||||
if conf.options.force_unix_socket or boost_asio_has_local_sockets():
|
||||
conf.define('HAVE_UNIX_SOCKETS', 1)
|
||||
conf.env['HAVE_UNIX_SOCKETS'] = True
|
||||
conf.env.HAVE_UNIX_SOCKETS = True
|
||||
+14
-17
@@ -6,7 +6,8 @@ import re
|
||||
def addWebsocketOptions(self, opt):
|
||||
opt.add_option('--without-websocket', action='store_false', default=True,
|
||||
dest='with_websocket', help='Disable WebSocket face support')
|
||||
setattr(Options.OptionsContext, "addWebsocketOptions", addWebsocketOptions)
|
||||
|
||||
setattr(Options.OptionsContext, 'addWebsocketOptions', addWebsocketOptions)
|
||||
|
||||
@Configure.conf
|
||||
def checkWebsocket(self, **kw):
|
||||
@@ -15,7 +16,7 @@ def checkWebsocket(self, **kw):
|
||||
|
||||
isMandatory = kw.get('mandatory', True)
|
||||
|
||||
self.start_msg('Checking for WebSocket includes')
|
||||
self.start_msg('Checking for WebSocket++ includes')
|
||||
|
||||
try:
|
||||
websocketDir = self.path.find_dir('websocketpp/websocketpp')
|
||||
@@ -24,40 +25,36 @@ def checkWebsocket(self, **kw):
|
||||
|
||||
versionFile = websocketDir.find_node('version.hpp')
|
||||
if not websocketDir:
|
||||
raise Errors.WafError('Corrupted: WebSocket version file not found')
|
||||
raise Errors.WafError('WebSocket++ version file not found')
|
||||
|
||||
try:
|
||||
txt = versionFile.read()
|
||||
except (OSError, IOError):
|
||||
raise Errors.WafError('Corrupted: cannot read WebSocket version file')
|
||||
raise Errors.WafError('Cannot read WebSocket++ version file')
|
||||
|
||||
version = [None, None, None]
|
||||
# Looking for the following:
|
||||
# static int const major_version = 0;
|
||||
# static int const minor_version = 7;
|
||||
# static int const patch_version = 0;
|
||||
|
||||
version = [None, None, None]
|
||||
|
||||
majorVersion = re.compile('^static int const major_version = (\\d+);$', re.M)
|
||||
version[0] = majorVersion.search(txt)
|
||||
|
||||
minorVersion = re.compile('^static int const minor_version = (\\d+);$', re.M)
|
||||
version[1] = minorVersion.search(txt)
|
||||
|
||||
patchVersion = re.compile('^static int const patch_version = (\\d+);$', re.M)
|
||||
version[2] = patchVersion.search(txt)
|
||||
|
||||
if not version[0] or not version[1] or not version[2]:
|
||||
raise Errors.WafError('Corrupted: cannot detect websocket version')
|
||||
raise Errors.WafError('Cannot detect WebSocket++ version')
|
||||
|
||||
self.env['WEBSOCKET_VERSION'] = [i.group(1) for i in version]
|
||||
self.env.WEBSOCKET_VERSION = [i.group(1) for i in version]
|
||||
|
||||
# todo: version checking, if necessary
|
||||
|
||||
self.end_msg('.'.join(self.env['WEBSOCKET_VERSION']))
|
||||
self.end_msg('.'.join(self.env.WEBSOCKET_VERSION))
|
||||
|
||||
self.env['INCLUDES_WEBSOCKET'] = websocketDir.parent.abspath()
|
||||
self.env['HAVE_WEBSOCKET'] = True
|
||||
self.env.INCLUDES_WEBSOCKET = websocketDir.parent.abspath()
|
||||
self.env.HAVE_WEBSOCKET = True
|
||||
self.define('HAVE_WEBSOCKET', 1)
|
||||
self.define('_WEBSOCKETPP_CPP11_STL_', 1)
|
||||
|
||||
@@ -65,12 +62,12 @@ def checkWebsocket(self, **kw):
|
||||
if isMandatory:
|
||||
self.end_msg(str(error), color='RED')
|
||||
Logs.warn('If you are using git NFD repository, checkout websocketpp submodule: ')
|
||||
Logs.warn(' git submodule init && git submodule update')
|
||||
Logs.warn(' git submodule update --init')
|
||||
Logs.warn('Otherwise, manually download and extract websocketpp library:')
|
||||
Logs.warn(' mkdir websocketpp')
|
||||
Logs.warn(' curl -L https://github.com/zaphoyd/websocketpp/archive/0.7.0.tar.gz > websocket.tar.gz')
|
||||
Logs.warn(' tar zxf websocket.tar.gz -C websocketpp/ --strip 1')
|
||||
Logs.warn(' tar xf websocket.tar.gz -C websocketpp/ --strip 1')
|
||||
Logs.warn('Alternatively, WebSocket support can be disabled with --without-websocket')
|
||||
self.fatal("The configuration failed")
|
||||
self.fatal('The configuration failed')
|
||||
else:
|
||||
self.end_msg(str(error))
|
||||
+9
-5
@@ -139,7 +139,7 @@ There is a
|
||||
for Python. It applies many of the provisions from the C++ guide, in
|
||||
addition to some other Python-specific things.
|
||||
|
||||
Some NDN projects are writtin in JavaScript, and there is a [style guide](https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/) for that language, too.
|
||||
Some NDN projects are written in JavaScript, and there is a [style guide](https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/) for that language, too.
|
||||
|
||||
#### Commit Messages ####
|
||||
|
||||
@@ -151,7 +151,7 @@ understand the timeline of a project. Commit messages should:
|
||||
they change. A good rule of thumb is a maximum length of 65
|
||||
characters.
|
||||
- If including a body, leave a blank line between the first line and
|
||||
the rest, and ensure that it's no longer than 72 characters.
|
||||
the rest, and ensure that each line is no longer than 72 characters.
|
||||
- Include Redmine issue numbers. The exact syntax is given below.
|
||||
- Be written in an imperative mood. E.g. `"Make foo a bar"` and not
|
||||
`"Foo is now a bar"`
|
||||
@@ -162,6 +162,10 @@ To explain, the anatomy of a typical commit message is like this:
|
||||
|
||||
docs: write contributing guide and code of conduct
|
||||
|
||||
This commit adds a guide that may be useful for new-comers to NDN in
|
||||
becoming productive contributors. This commit also adds a code of
|
||||
conduct.
|
||||
|
||||
refs: #3898
|
||||
Change-Id: Ife89360305027dba9020f0b298793c1121ae1fd6c
|
||||
|
||||
@@ -315,7 +319,7 @@ Once you have a commit message you are happy with, simply run `git
|
||||
push HEAD:refs/for/master`.
|
||||
|
||||
**Note:** Gerrit separates commits into patch sets by the unique
|
||||
`Change-Id`s. As a result, it is important that you either:
|
||||
`Change-Id`s. As a result, you must either:
|
||||
|
||||
* Squash your various commits into one with `git rebase -i
|
||||
<initial commit>`, ensuring that the ultimate `Change-Id` in the
|
||||
@@ -470,8 +474,8 @@ repetitive, you have a few options:
|
||||
|
||||
* Git has an alias system that you can use to specify certain
|
||||
commands. For example, you can use `git config --global alias.pg
|
||||
"push origin HEAD:refs/for/master"` to make `git pg` push to Gerrit. You
|
||||
can [learn about git aliases.](https://githowto.com/aliases)
|
||||
"push origin HEAD:refs/for/master"` to make `git pg` push to
|
||||
Gerrit. [Learn about git aliases here.](https://githowto.com/aliases)
|
||||
|
||||
* If using Linux or macOS, it is relatively simple to create a shell
|
||||
alias: `alias gs="git status"` for example, or `alias gitpush="git
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ The simplest way to run tests, is just to run the compiled binary without any pa
|
||||
# Run NFD RIB management tests
|
||||
./build/unit-tests-rib
|
||||
|
||||
However, [Boost.Test framework](http://www.boost.org/doc/libs/1_54_0/libs/test/doc/html/index.html)
|
||||
However, [Boost.Test framework](https://www.boost.org/doc/libs/1_58_0/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:
|
||||
@@ -93,5 +93,5 @@ or `-p` to show progress bar:
|
||||
|
||||
There are many more command line options available, information about
|
||||
which can be obtained either from the command line using `--help`
|
||||
switch, or online on [Boost.Test library](http://www.boost.org/doc/libs/1_54_0/libs/test/doc/html/index.html)
|
||||
switch, or online on [Boost.Test library](https://www.boost.org/doc/libs/1_58_0/libs/test/doc/html/index.html)
|
||||
website.
|
||||
@@ -1,67 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NFD_CORE_ASSERTS_HPP
|
||||
#define NFD_CORE_ASSERTS_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include <boost/concept/assert.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nfd {
|
||||
namespace detail {
|
||||
|
||||
// As of Boost 1.54.0, the internal implementation of BOOST_CONCEPT_ASSERT does not allow
|
||||
// multiple assertions on the same line, so we have to combine multiple concepts together.
|
||||
|
||||
template<typename T>
|
||||
class StlForwardIteratorConcept : public boost::ForwardIterator<T>
|
||||
, public boost::DefaultConstructible<T>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace nfd
|
||||
|
||||
/** \brief assert T is default constructible
|
||||
* \sa http://en.cppreference.com/w/cpp/concept/DefaultConstructible
|
||||
*/
|
||||
#define NFD_ASSERT_DEFAULT_CONSTRUCTIBLE(T) \
|
||||
static_assert(std::is_default_constructible<T>::value, \
|
||||
#T " must be default-constructible"); \
|
||||
BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<T>))
|
||||
|
||||
/** \brief assert T is a forward iterator
|
||||
* \sa http://en.cppreference.com/w/cpp/concept/ForwardIterator
|
||||
* \note A forward iterator should be default constructible, but boost::ForwardIterator follows
|
||||
* SGI standard which doesn't require DefaultConstructible, so a separate check is needed.
|
||||
*/
|
||||
#define NFD_ASSERT_FORWARD_ITERATOR(T) \
|
||||
BOOST_CONCEPT_ASSERT((::nfd::detail::StlForwardIteratorConcept<T>)); \
|
||||
static_assert(std::is_default_constructible<T>::value, \
|
||||
#T " must be default-constructible")
|
||||
|
||||
#endif // NFD_CORE_ASSERTS_HPP
|
||||
+6
-8
@@ -46,10 +46,10 @@
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@@ -59,7 +59,6 @@
|
||||
#include <ndn-cxx/data.hpp>
|
||||
#include <ndn-cxx/delegation.hpp>
|
||||
#include <ndn-cxx/delegation-list.hpp>
|
||||
#include <ndn-cxx/exclude.hpp>
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/name.hpp>
|
||||
#include <ndn-cxx/encoding/block.hpp>
|
||||
@@ -85,25 +84,24 @@ using std::shared_ptr;
|
||||
using std::unique_ptr;
|
||||
using std::weak_ptr;
|
||||
using std::make_shared;
|
||||
using ndn::make_unique;
|
||||
using std::enable_shared_from_this;
|
||||
using std::make_unique;
|
||||
|
||||
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 ndn::optional;
|
||||
using ndn::nullopt;
|
||||
using ndn::to_string;
|
||||
|
||||
using ndn::Block;
|
||||
using ndn::Data;
|
||||
using ndn::Delegation;
|
||||
using ndn::DelegationList;
|
||||
using ndn::Exclude;
|
||||
using ndn::FaceUri;
|
||||
using ndn::Interest;
|
||||
using ndn::Name;
|
||||
|
||||
+10
-11
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -34,24 +34,23 @@ namespace nfd {
|
||||
|
||||
/** \brief a config file section
|
||||
*/
|
||||
typedef boost::property_tree::ptree ConfigSection;
|
||||
using ConfigSection = boost::property_tree::ptree;
|
||||
|
||||
/** \brief an optional config file section
|
||||
*/
|
||||
typedef boost::optional<const ConfigSection&> OptionalConfigSection;
|
||||
using OptionalConfigSection = boost::optional<const ConfigSection&>;
|
||||
|
||||
/** \brief callback to process a config file section
|
||||
*/
|
||||
typedef function<void(const ConfigSection& section,
|
||||
bool isDryRun,
|
||||
const std::string& filename)> ConfigSectionHandler;
|
||||
using ConfigSectionHandler = std::function<void(const ConfigSection& section, bool isDryRun,
|
||||
const std::string& filename)>;
|
||||
|
||||
/** \brief callback to process a config file section without a \p ConfigSectionHandler
|
||||
*/
|
||||
typedef function<void(const std::string& filename,
|
||||
const std::string& sectionName,
|
||||
const ConfigSection& section,
|
||||
bool isDryRun)> UnknownConfigSectionHandler;
|
||||
using UnknownConfigSectionHandler = std::function<void(const std::string& filename,
|
||||
const std::string& sectionName,
|
||||
const ConfigSection& section,
|
||||
bool isDryRun)>;
|
||||
|
||||
/** \brief configuration file parsing utility
|
||||
*/
|
||||
|
||||
+42
-3
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -34,8 +34,9 @@ void
|
||||
resetGlobalScheduler();
|
||||
} // namespace scheduler
|
||||
|
||||
|
||||
static boost::thread_specific_ptr<boost::asio::io_service> g_ioService;
|
||||
static boost::asio::io_service* g_mainIoService = nullptr;
|
||||
static boost::asio::io_service* g_ribIoService = nullptr;
|
||||
|
||||
boost::asio::io_service&
|
||||
getGlobalIoService()
|
||||
@@ -53,4 +54,42 @@ resetGlobalIoService()
|
||||
g_ioService.reset();
|
||||
}
|
||||
|
||||
void
|
||||
setMainIoService(boost::asio::io_service* mainIo)
|
||||
{
|
||||
g_mainIoService = mainIo;
|
||||
}
|
||||
|
||||
void
|
||||
setRibIoService(boost::asio::io_service* ribIo)
|
||||
{
|
||||
g_ribIoService = ribIo;
|
||||
}
|
||||
|
||||
boost::asio::io_service&
|
||||
getMainIoService()
|
||||
{
|
||||
BOOST_ASSERT(g_mainIoService != nullptr);
|
||||
return *g_mainIoService;
|
||||
}
|
||||
|
||||
boost::asio::io_service&
|
||||
getRibIoService()
|
||||
{
|
||||
BOOST_ASSERT(g_ribIoService != nullptr);
|
||||
return *g_ribIoService;
|
||||
}
|
||||
|
||||
void
|
||||
runOnMainIoService(const std::function<void()>& f)
|
||||
{
|
||||
getMainIoService().post(f);
|
||||
}
|
||||
|
||||
void
|
||||
runOnRibIoService(const std::function<void()>& f)
|
||||
{
|
||||
getRibIoService().post(f);
|
||||
}
|
||||
|
||||
} // namespace nfd
|
||||
+29
-7
@@ -1,11 +1,11 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology
|
||||
/*
|
||||
* Copyright (c) 2014-2018 Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
@@ -34,6 +34,28 @@ namespace nfd {
|
||||
boost::asio::io_service&
|
||||
getGlobalIoService();
|
||||
|
||||
void
|
||||
setMainIoService(boost::asio::io_service* mainIo);
|
||||
|
||||
void
|
||||
setRibIoService(boost::asio::io_service* ribIo);
|
||||
|
||||
/** \brief run a function on the main io_service instance
|
||||
*/
|
||||
void
|
||||
runOnMainIoService(const std::function<void()>& f);
|
||||
|
||||
/** \brief run a function on the RIB io_service instance
|
||||
*/
|
||||
void
|
||||
runOnRibIoService(const std::function<void()>& f);
|
||||
|
||||
boost::asio::io_service&
|
||||
getMainIoService();
|
||||
|
||||
boost::asio::io_service&
|
||||
getRibIoService();
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
/** \brief delete the global io_service instance
|
||||
*
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "log-config-section.hpp"
|
||||
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
#include <ndn-cxx/util/logging.hpp>
|
||||
|
||||
namespace nfd {
|
||||
namespace log {
|
||||
|
||||
static ndn::util::LogLevel
|
||||
parseLogLevel(const ConfigSection& item, const std::string& key)
|
||||
{
|
||||
try {
|
||||
return ndn::util::parseLogLevel(item.get_value<std::string>());
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid setting for log." + key + ": " + e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
onConfig(const ConfigSection& section, bool isDryRun, const std::string&)
|
||||
{
|
||||
// log
|
||||
// {
|
||||
// ; default_level specifies the logging level for modules
|
||||
// ; that are not explicitly named. All debugging levels
|
||||
// ; listed above the selected value are enabled.
|
||||
//
|
||||
// default_level INFO
|
||||
//
|
||||
// ; You may also override the default for specific modules:
|
||||
//
|
||||
// FibManager DEBUG
|
||||
// Forwarder WARN
|
||||
// }
|
||||
|
||||
auto defaultLevel = ndn::util::LogLevel::INFO;
|
||||
auto item = section.get_child_optional("default_level");
|
||||
if (item) {
|
||||
defaultLevel = parseLogLevel(*item, "default_level");
|
||||
}
|
||||
if (!isDryRun) {
|
||||
// default_level applies only to NFD loggers
|
||||
ndn::util::Logging::setLevel("nfd.*", defaultLevel);
|
||||
}
|
||||
|
||||
for (const auto& i : section) {
|
||||
if (i.first == "default_level") {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
auto level = parseLogLevel(i.second, i.first);
|
||||
if (!isDryRun) {
|
||||
if (i.first.find('.') == std::string::npos)
|
||||
// backward compat: assume unqualified logger names refer to NFD loggers
|
||||
ndn::util::Logging::setLevel("nfd." + i.first, level);
|
||||
else
|
||||
ndn::util::Logging::setLevel(i.first, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setConfigFile(ConfigFile& config)
|
||||
{
|
||||
config.addSectionHandler("log", &onConfig);
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
} // namespace nfd
|
||||
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NFD_CORE_LOG_CONFIG_SECTION_HPP
|
||||
#define NFD_CORE_LOG_CONFIG_SECTION_HPP
|
||||
|
||||
#include "config-file.hpp"
|
||||
|
||||
namespace nfd {
|
||||
namespace log {
|
||||
|
||||
void
|
||||
setConfigFile(ConfigFile& config);
|
||||
|
||||
} // namespace log
|
||||
} // namespace nfd
|
||||
|
||||
#endif // NFD_CORE_LOG_CONFIG_SECTION_HPP
|
||||
@@ -1,228 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "logger-factory.hpp"
|
||||
|
||||
#include <ndn-cxx/util/logging.hpp>
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_CUSTOM_LOGGER
|
||||
#error "This file should not be compiled when custom logger is used"
|
||||
#endif
|
||||
|
||||
namespace nfd {
|
||||
|
||||
NFD_LOG_INIT("LoggerFactory");
|
||||
|
||||
LoggerFactory&
|
||||
LoggerFactory::getInstance()
|
||||
{
|
||||
static LoggerFactory globalLoggerFactory;
|
||||
|
||||
return globalLoggerFactory;
|
||||
}
|
||||
|
||||
LoggerFactory::LoggerFactory()
|
||||
: m_defaultLevel(LOG_INFO)
|
||||
{
|
||||
m_levelNames["NONE"] = LOG_NONE;
|
||||
m_levelNames["ERROR"] = LOG_ERROR;
|
||||
m_levelNames["WARN"] = LOG_WARN;
|
||||
m_levelNames["INFO"] = LOG_INFO;
|
||||
m_levelNames["DEBUG"] = LOG_DEBUG;
|
||||
m_levelNames["TRACE"] = LOG_TRACE;
|
||||
m_levelNames["ALL"] = LOG_ALL;
|
||||
|
||||
// Let ndn-cxx logging facility initialize Boost.Log backend,
|
||||
// so that only one sink is attached to Boost.Log core.
|
||||
ndn::util::Logging::setDestination(std::clog);
|
||||
}
|
||||
|
||||
LoggerFactory::~LoggerFactory()
|
||||
{
|
||||
ndn::util::Logging::flush();
|
||||
}
|
||||
|
||||
void
|
||||
LoggerFactory::setConfigFile(ConfigFile& config)
|
||||
{
|
||||
config.addSectionHandler("log", bind(&LoggerFactory::onConfig, this, _1, _2, _3));
|
||||
}
|
||||
|
||||
LogLevel
|
||||
LoggerFactory::parseLevel(const std::string& level)
|
||||
{
|
||||
std::string upperLevel = boost::to_upper_copy(level);
|
||||
|
||||
// std::cerr << "parsing level: " << upperLevel << std::endl;;
|
||||
// std::cerr << "# levels: " << m_levelNames.size() << std::endl;
|
||||
// std::cerr << m_levelNames.begin()->first << std::endl;
|
||||
|
||||
LevelMap::const_iterator levelIt = m_levelNames.find(upperLevel);
|
||||
if (levelIt != m_levelNames.end()) {
|
||||
return levelIt->second;
|
||||
}
|
||||
try {
|
||||
uint32_t levelNo = boost::lexical_cast<uint32_t>(level);
|
||||
|
||||
if ((boost::lexical_cast<uint32_t>(LOG_NONE) <= levelNo &&
|
||||
levelNo <= boost::lexical_cast<uint32_t>(LOG_TRACE)) ||
|
||||
levelNo == LOG_ALL) {
|
||||
return static_cast<LogLevel>(levelNo);
|
||||
}
|
||||
}
|
||||
catch (const boost::bad_lexical_cast& error) {
|
||||
}
|
||||
|
||||
BOOST_THROW_EXCEPTION(LoggerFactory::Error("Unsupported logging level \"" + level + "\""));
|
||||
}
|
||||
|
||||
LogLevel
|
||||
LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
|
||||
{
|
||||
std::string levelString;
|
||||
try {
|
||||
levelString = item.get_value<std::string>();
|
||||
}
|
||||
catch (const boost::property_tree::ptree_error& error) {
|
||||
}
|
||||
|
||||
if (levelString.empty()) {
|
||||
BOOST_THROW_EXCEPTION(LoggerFactory::Error("No logging level found for option \"" + key + "\""));
|
||||
}
|
||||
|
||||
return parseLevel(levelString);
|
||||
}
|
||||
|
||||
void
|
||||
LoggerFactory::onConfig(const ConfigSection& section,
|
||||
bool isDryRun,
|
||||
const std::string& filename)
|
||||
{
|
||||
// log
|
||||
// {
|
||||
// ; default_level specifies the logging level for modules
|
||||
// ; that are not explicitly named. All debugging levels
|
||||
// ; listed above the selected value are enabled.
|
||||
//
|
||||
// default_level INFO
|
||||
//
|
||||
// ; You may also override the default for specific modules:
|
||||
//
|
||||
// FibManager DEBUG
|
||||
// Forwarder WARN
|
||||
// }
|
||||
|
||||
if (!isDryRun) {
|
||||
ConfigSection::const_assoc_iterator item = section.find("default_level");
|
||||
if (item != section.not_found()) {
|
||||
LogLevel level = extractLevel(item->second, "default_level");
|
||||
setDefaultLevel(level);
|
||||
}
|
||||
else {
|
||||
setDefaultLevel(LOG_INFO);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& i : section) {
|
||||
LogLevel level = extractLevel(i.second, i.first);
|
||||
|
||||
if (i.first == "default_level") {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
std::unique_lock<std::mutex> lock(m_loggersGuard);
|
||||
LoggerMap::iterator loggerIt = m_loggers.find(i.first);
|
||||
if (loggerIt == m_loggers.end()) {
|
||||
lock.unlock();
|
||||
NFD_LOG_DEBUG("Failed to configure logging level for module \"" <<
|
||||
i.first << "\" (module not found)");
|
||||
}
|
||||
else if (!isDryRun) {
|
||||
loggerIt->second.setLogLevel(level);
|
||||
lock.unlock();
|
||||
NFD_LOG_DEBUG("Changing level for module " << i.first << " to " << level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LoggerFactory::setDefaultLevel(LogLevel level)
|
||||
{
|
||||
// std::cerr << "changing to default_level " << level << std::endl;
|
||||
std::lock_guard<std::mutex> lock(m_loggersGuard);
|
||||
|
||||
m_defaultLevel = level;
|
||||
for (auto&& logger : m_loggers) {
|
||||
// std::cerr << "changing " << i->first << " to default " << m_defaultLevel << std::endl;
|
||||
logger.second.setLogLevel(m_defaultLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LoggerFactory::flushBackend()
|
||||
{
|
||||
ndn::util::Logging::flush();
|
||||
}
|
||||
|
||||
Logger&
|
||||
LoggerFactory::create(const std::string& moduleName)
|
||||
{
|
||||
return LoggerFactory::getInstance().createLogger(moduleName);
|
||||
}
|
||||
|
||||
Logger&
|
||||
LoggerFactory::createLogger(const std::string& moduleName)
|
||||
{
|
||||
// std::cerr << "creating logger for " << moduleName
|
||||
// << " with level " << m_defaultLevel << std::endl;
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_loggersGuard);
|
||||
|
||||
std::pair<LoggerMap::iterator, bool> loggerIt =
|
||||
m_loggers.insert(NameAndLogger(moduleName, Logger(moduleName, m_defaultLevel)));
|
||||
|
||||
return loggerIt.first->second;
|
||||
}
|
||||
|
||||
std::list<std::string>
|
||||
LoggerFactory::getModules() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_loggersGuard);
|
||||
|
||||
std::list<std::string> modules;
|
||||
for (const auto& loggerName : m_loggers | boost::adaptors::map_keys) {
|
||||
modules.push_back(loggerName);
|
||||
}
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
} // namespace nfd
|
||||
@@ -1,126 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NFD_CORE_LOGGER_FACTORY_HPP
|
||||
#define NFD_CORE_LOGGER_FACTORY_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#ifdef HAVE_CUSTOM_LOGGER
|
||||
#include "custom-logger-factory.hpp"
|
||||
#else
|
||||
|
||||
#include "config-file.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
class LoggerFactory : noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& error)
|
||||
: std::runtime_error(error)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static LoggerFactory&
|
||||
getInstance();
|
||||
|
||||
void
|
||||
setConfigFile(ConfigFile& config);
|
||||
|
||||
void
|
||||
onConfig(const ConfigSection& section, bool isDryRun, const std::string& filename);
|
||||
|
||||
std::list<std::string>
|
||||
getModules() const;
|
||||
|
||||
static Logger&
|
||||
create(const std::string& moduleName);
|
||||
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
|
||||
// these methods are used during unit-testing
|
||||
|
||||
LogLevel
|
||||
getDefaultLevel() const;
|
||||
|
||||
void
|
||||
setDefaultLevel(LogLevel level);
|
||||
|
||||
void
|
||||
flushBackend();
|
||||
|
||||
private:
|
||||
|
||||
LoggerFactory();
|
||||
|
||||
~LoggerFactory();
|
||||
|
||||
Logger&
|
||||
createLogger(const std::string& moduleName);
|
||||
|
||||
LogLevel
|
||||
parseLevel(const std::string& level);
|
||||
|
||||
LogLevel
|
||||
extractLevel(const ConfigSection& item, const std::string& key);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<std::string, LogLevel> LevelMap;
|
||||
typedef std::pair<std::string, LogLevel> NameAndLevel;
|
||||
|
||||
LevelMap m_levelNames;
|
||||
|
||||
typedef std::map<std::string, Logger> LoggerMap;
|
||||
typedef std::pair<std::string, Logger> NameAndLogger;
|
||||
|
||||
LoggerMap m_loggers;
|
||||
mutable std::mutex m_loggersGuard;
|
||||
|
||||
LogLevel m_defaultLevel;
|
||||
};
|
||||
|
||||
inline LogLevel
|
||||
LoggerFactory::getDefaultLevel() const
|
||||
{
|
||||
return m_defaultLevel;
|
||||
}
|
||||
|
||||
} // namespace nfd
|
||||
|
||||
#endif // HAVE_CUSTOM_LOGGER
|
||||
|
||||
#endif // NFD_CORE_LOGGER_FACTORY_HPP
|
||||
@@ -1,70 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "logger.hpp"
|
||||
|
||||
#ifdef HAVE_CUSTOM_LOGGER
|
||||
#error "This file should not be compiled when custom logger is used"
|
||||
#endif
|
||||
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
#include <cinttypes>
|
||||
#include <stdio.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
Logger::Logger(const std::string& name, LogLevel level)
|
||||
: m_moduleName(name)
|
||||
, m_enabledLogLevel(level)
|
||||
{
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const LoggerTimestamp&)
|
||||
{
|
||||
using namespace ndn::time;
|
||||
|
||||
static const microseconds::rep ONE_SECOND = 1000000;
|
||||
microseconds::rep microsecondsSinceEpoch = duration_cast<microseconds>(
|
||||
system_clock::now().time_since_epoch()).count();
|
||||
|
||||
// 10 (whole seconds) + '.' + 6 (fraction) + '\0'
|
||||
char buffer[10 + 1 + 6 + 1];
|
||||
BOOST_ASSERT_MSG(microsecondsSinceEpoch / ONE_SECOND <= 9999999999L,
|
||||
"whole seconds cannot fit in 10 characters");
|
||||
|
||||
static_assert(std::is_same<microseconds::rep, int_least64_t>::value,
|
||||
"PRIdLEAST64 is incompatible with microseconds::rep");
|
||||
// - std::snprintf not found in some environments
|
||||
// http://redmine.named-data.net/issues/2299 for more information
|
||||
snprintf(buffer, sizeof(buffer), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
|
||||
microsecondsSinceEpoch / ONE_SECOND,
|
||||
microsecondsSinceEpoch % ONE_SECOND);
|
||||
|
||||
return os << buffer;
|
||||
}
|
||||
|
||||
} // namespace nfd
|
||||
+14
-141
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -26,146 +26,19 @@
|
||||
#ifndef NFD_CORE_LOGGER_HPP
|
||||
#define NFD_CORE_LOGGER_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
|
||||
#ifdef HAVE_CUSTOM_LOGGER
|
||||
#include "custom-logger.hpp"
|
||||
#else
|
||||
#include <boost/log/common.hpp>
|
||||
#include <boost/log/sources/logger.hpp>
|
||||
#define NFD_LOG_INIT(name) NDN_LOG_INIT(nfd.name)
|
||||
#define NFD_LOG_MEMBER_DECL() NDN_LOG_MEMBER_DECL()
|
||||
#define NFD_LOG_MEMBER_DECL_SPECIALIZED(cls) NDN_LOG_MEMBER_DECL_SPECIALIZED(cls)
|
||||
#define NFD_LOG_MEMBER_INIT(cls, name) NDN_LOG_MEMBER_INIT(cls, nfd.name)
|
||||
#define NFD_LOG_MEMBER_INIT_SPECIALIZED(cls, name) NDN_LOG_MEMBER_INIT_SPECIALIZED(cls, nfd.name)
|
||||
|
||||
namespace nfd {
|
||||
|
||||
/** \brief indicates a log level
|
||||
* \note This type is internal. Logger should be accessed through NFD_LOG_* macros.
|
||||
*/
|
||||
enum LogLevel {
|
||||
LOG_FATAL = -1, // fatal (will be logged unconditionally)
|
||||
LOG_NONE = 0, // no messages
|
||||
LOG_ERROR = 1, // serious error messages
|
||||
LOG_WARN = 2, // warning messages
|
||||
LOG_INFO = 3, // informational messages
|
||||
LOG_DEBUG = 4, // debug messages
|
||||
LOG_TRACE = 5, // trace messages (most verbose)
|
||||
LOG_ALL = 255 // all messages
|
||||
};
|
||||
|
||||
/** \brief provides logging for a module
|
||||
* \note This type is internal. Logger should be accessed through NFD_LOG_* macros.
|
||||
* \note This type is copyable because logger can be declared as a field of
|
||||
* (usually template) classes, and shouldn't prevent those classes to be copyable.
|
||||
*/
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
Logger(const std::string& name, LogLevel level);
|
||||
|
||||
bool
|
||||
isEnabled(LogLevel level) const
|
||||
{
|
||||
return m_enabledLogLevel >= level;
|
||||
}
|
||||
|
||||
void
|
||||
setLogLevel(LogLevel level)
|
||||
{
|
||||
m_enabledLogLevel = level;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
getName() const
|
||||
{
|
||||
return m_moduleName;
|
||||
}
|
||||
|
||||
void
|
||||
setName(const std::string& name)
|
||||
{
|
||||
m_moduleName = name;
|
||||
}
|
||||
|
||||
public:
|
||||
boost::log::sources::logger boostLogger;
|
||||
|
||||
private:
|
||||
std::string m_moduleName;
|
||||
LogLevel m_enabledLogLevel;
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& output, const Logger& logger)
|
||||
{
|
||||
output << logger.getName();
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief a tag that writes a timestamp upon stream output
|
||||
*/
|
||||
struct LoggerTimestamp
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief write a timestamp to \p os
|
||||
* \note This function is thread-safe.
|
||||
*/
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const LoggerTimestamp&);
|
||||
|
||||
} // namespace nfd
|
||||
|
||||
#include "core/logger-factory.hpp"
|
||||
|
||||
namespace nfd {
|
||||
|
||||
#define NFD_LOG_INIT(name) \
|
||||
static ::nfd::Logger& g_logger = ::nfd::LoggerFactory::create(name)
|
||||
|
||||
#define NFD_LOG_INCLASS_DECLARE() \
|
||||
static ::nfd::Logger& g_logger
|
||||
|
||||
#define NFD_LOG_INCLASS_DEFINE(cls, name) \
|
||||
::nfd::Logger& cls::g_logger = ::nfd::LoggerFactory::create(name)
|
||||
|
||||
#define NFD_LOG_INCLASS_TEMPLATE_DEFINE(cls, name) \
|
||||
template<class T> \
|
||||
::nfd::Logger& cls<T>::g_logger = ::nfd::LoggerFactory::create(name)
|
||||
|
||||
#define NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(cls, specialization, name) \
|
||||
template<> \
|
||||
::nfd::Logger& cls<specialization>::g_logger = ::nfd::LoggerFactory::create(name)
|
||||
|
||||
#define NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(cls, s1, s2, name) \
|
||||
template<> \
|
||||
::nfd::Logger& cls<s1, s2>::g_logger = ::nfd::LoggerFactory::create(name)
|
||||
|
||||
#if (BOOST_VERSION >= 105900) && (BOOST_VERSION < 106000)
|
||||
// workaround Boost bug 11549
|
||||
#define NFD_BOOST_LOG(x) BOOST_LOG(x) << ""
|
||||
#else
|
||||
#define NFD_BOOST_LOG(x) BOOST_LOG(x)
|
||||
#endif
|
||||
|
||||
#define NFD_LOG_LINE(msg, expression) \
|
||||
::nfd::LoggerTimestamp{} << " "#msg": " << "[" << g_logger << "] " << expression
|
||||
|
||||
#define NFD_LOG(level, msg, expression) \
|
||||
do { \
|
||||
if (g_logger.isEnabled(::nfd::LOG_##level)) { \
|
||||
NFD_BOOST_LOG(g_logger.boostLogger) << NFD_LOG_LINE(msg, expression); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define NFD_LOG_TRACE(expression) NFD_LOG(TRACE, TRACE, expression)
|
||||
#define NFD_LOG_DEBUG(expression) NFD_LOG(DEBUG, DEBUG, expression)
|
||||
#define NFD_LOG_INFO(expression) NFD_LOG(INFO, INFO, expression)
|
||||
#define NFD_LOG_WARN(expression) NFD_LOG(WARN, WARNING, expression)
|
||||
#define NFD_LOG_ERROR(expression) NFD_LOG(ERROR, ERROR, expression)
|
||||
#define NFD_LOG_FATAL(expression) NFD_LOG(FATAL, FATAL, expression)
|
||||
|
||||
} // namespace nfd
|
||||
|
||||
#endif // HAVE_CUSTOM_LOGGER
|
||||
#define NFD_LOG_TRACE NDN_LOG_TRACE
|
||||
#define NFD_LOG_DEBUG NDN_LOG_DEBUG
|
||||
#define NFD_LOG_INFO NDN_LOG_INFO
|
||||
#define NFD_LOG_WARN NDN_LOG_WARN
|
||||
#define NFD_LOG_ERROR NDN_LOG_ERROR
|
||||
#define NFD_LOG_FATAL NDN_LOG_FATAL
|
||||
|
||||
#endif // NFD_CORE_LOGGER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -72,10 +72,10 @@ public:
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PROTECTED: // registrations to the dispatcher
|
||||
// difference from mgmt::ControlCommand: accepts nfd::ControlParameters
|
||||
typedef function<void(const ControlCommand& command,
|
||||
const Name& prefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation done)> ControlCommandHandler;
|
||||
using ControlCommandHandler = std::function<void(const ControlCommand& command,
|
||||
const Name& prefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation done)>;
|
||||
|
||||
template<typename Command>
|
||||
void
|
||||
@@ -161,7 +161,7 @@ ManagerBase::registerCommandHandler(const std::string& verb,
|
||||
m_dispatcher.addControlCommand<ControlParameters>(
|
||||
makeRelPrefix(verb),
|
||||
makeAuthorization(verb),
|
||||
bind(&ManagerBase::validateParameters, cref(*command), _1),
|
||||
bind(&ManagerBase::validateParameters, std::cref(*command), _1),
|
||||
bind(&ManagerBase::handleCommand, command, handler, _1, _2, _3, _4));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "network-interface-predicate.hpp"
|
||||
|
||||
#include "config-file.hpp"
|
||||
#include "network.hpp"
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
NetworkInterfacePredicate::NetworkInterfacePredicate()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void
|
||||
NetworkInterfacePredicate::clear()
|
||||
{
|
||||
m_whitelist = std::set<std::string>{"*"};
|
||||
m_blacklist.clear();
|
||||
}
|
||||
|
||||
static void
|
||||
parseList(std::set<std::string>& set, const boost::property_tree::ptree& list, const std::string& section)
|
||||
{
|
||||
set.clear();
|
||||
|
||||
for (const auto& item : list) {
|
||||
if (item.first == "*") {
|
||||
// insert wildcard
|
||||
set.insert(item.first);
|
||||
}
|
||||
else if (item.first == "ifname") {
|
||||
// very basic sanity check for interface names
|
||||
auto name = item.second.get_value<std::string>();
|
||||
if (name.empty()) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Empty interface name in \"" + section + "\" section"));
|
||||
}
|
||||
set.insert(name);
|
||||
}
|
||||
else if (item.first == "ether") {
|
||||
// validate ethernet address
|
||||
auto addr = item.second.get_value<std::string>();
|
||||
if (ndn::ethernet::Address::fromString(addr).isNull()) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Malformed ether address \"" + addr +
|
||||
"\" in \"" + section + "\" section"));
|
||||
}
|
||||
set.insert(addr);
|
||||
}
|
||||
else if (item.first == "subnet") {
|
||||
// example subnet: 10.0.0.0/8
|
||||
auto cidr = item.second.get_value<std::string>();
|
||||
if (!Network::isValidCidr(cidr)) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Malformed subnet declaration \"" + cidr +
|
||||
"\" in \"" + section + "\" section"));
|
||||
}
|
||||
set.insert(cidr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetworkInterfacePredicate::parseWhitelist(const boost::property_tree::ptree& list)
|
||||
{
|
||||
parseList(m_whitelist, list, "whitelist");
|
||||
}
|
||||
|
||||
void
|
||||
NetworkInterfacePredicate::parseBlacklist(const boost::property_tree::ptree& list)
|
||||
{
|
||||
parseList(m_blacklist, list, "blacklist");
|
||||
}
|
||||
|
||||
static bool
|
||||
doesMatchPattern(const std::string& ifname, const std::string& pattern)
|
||||
{
|
||||
// use fnmatch(3) to provide unix glob-style matching for interface names
|
||||
// fnmatch returns 0 if there is a match
|
||||
return ::fnmatch(pattern.data(), ifname.data(), 0) == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
doesMatchRule(const ndn::net::NetworkInterface& netif, const std::string& rule)
|
||||
{
|
||||
// if '/' is in rule, this is a subnet, check if IP in subnet
|
||||
if (rule.find('/') != std::string::npos) {
|
||||
Network n = boost::lexical_cast<Network>(rule);
|
||||
for (const auto& addr : netif.getNetworkAddresses()) {
|
||||
if (n.doesContain(addr.getIp())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rule == "*" ||
|
||||
doesMatchPattern(netif.getName(), rule) ||
|
||||
netif.getEthernetAddress().toString() == rule;
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkInterfacePredicate::operator()(const ndn::net::NetworkInterface& netif) const
|
||||
{
|
||||
return std::any_of(m_whitelist.begin(), m_whitelist.end(), bind(&doesMatchRule, cref(netif), _1)) &&
|
||||
std::none_of(m_blacklist.begin(), m_blacklist.end(), bind(&doesMatchRule, cref(netif), _1));
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkInterfacePredicate::operator==(const NetworkInterfacePredicate& other) const
|
||||
{
|
||||
return this->m_whitelist == other.m_whitelist &&
|
||||
this->m_blacklist == other.m_blacklist;
|
||||
}
|
||||
|
||||
} // namespace nfd
|
||||
@@ -1,79 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NFD_CORE_NETWORK_INTERFACE_PREDICATE_HPP
|
||||
#define NFD_CORE_NETWORK_INTERFACE_PREDICATE_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include <ndn-cxx/net/network-interface.hpp>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
/**
|
||||
* \brief Represents a predicate to accept or reject a NetworkInterfaceInfo.
|
||||
*
|
||||
* The predicate consists of a whitelist and a blacklist. Whitelist and blacklist can contain,
|
||||
* in no particular order, interface names (e.g., ifname eth0), mac addresses
|
||||
* (e.g., ether 85:3b:4d:d3:5f:c2), subnets (e.g., subnet 192.0.2.0/24) or a wildcard (*) that matches
|
||||
* all interfaces. A NetworkInterfaceInfo is accepted if it matches any entry in the whitelist and none
|
||||
* of the entries in the blacklist.
|
||||
*/
|
||||
class NetworkInterfacePredicate
|
||||
{
|
||||
public:
|
||||
NetworkInterfacePredicate();
|
||||
|
||||
/**
|
||||
* \brief Set the whitelist to "*" and clear the blacklist
|
||||
*/
|
||||
void
|
||||
clear();
|
||||
|
||||
void
|
||||
parseWhitelist(const boost::property_tree::ptree& list);
|
||||
|
||||
void
|
||||
parseBlacklist(const boost::property_tree::ptree& list);
|
||||
|
||||
bool
|
||||
operator()(const ndn::net::NetworkInterface& netif) const;
|
||||
|
||||
bool
|
||||
operator==(const NetworkInterfacePredicate& other) const;
|
||||
|
||||
bool
|
||||
operator!=(const NetworkInterfacePredicate& other) const
|
||||
{
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::string> m_whitelist;
|
||||
std::set<std::string> m_blacklist;
|
||||
};
|
||||
|
||||
} // namespace nfd
|
||||
|
||||
#endif // NFD_CORE_NETWORK_INTERFACE_PREDICATE_HPP
|
||||
@@ -0,0 +1,221 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "network-predicate.hpp"
|
||||
|
||||
#include "config-file.hpp"
|
||||
#include "network.hpp"
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
NetworkPredicateBase::NetworkPredicateBase()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
NetworkPredicateBase::~NetworkPredicateBase() = default;
|
||||
|
||||
void
|
||||
NetworkPredicateBase::clear()
|
||||
{
|
||||
m_whitelist = std::set<std::string>{"*"};
|
||||
m_blacklist.clear();
|
||||
}
|
||||
|
||||
void
|
||||
NetworkPredicateBase::parseList(std::set<std::string>& set, const boost::property_tree::ptree& list, const std::string& section)
|
||||
{
|
||||
set.clear();
|
||||
|
||||
for (const auto& item : list) {
|
||||
if (item.first == "*") {
|
||||
// insert wildcard
|
||||
set.insert(item.first);
|
||||
}
|
||||
else {
|
||||
if (!isRuleSupported(item.first)) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized rule \"" + item.first + "\" in \"" + section + "\" section"));
|
||||
}
|
||||
|
||||
auto value = item.second.get_value<std::string>();
|
||||
if (!isRuleValid(item.first, value)) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Malformed " + item.first + " \"" + value + "\" in \"" + section + "\" section"));
|
||||
}
|
||||
set.insert(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetworkPredicateBase::parseList(std::set<std::string>& set, std::initializer_list<std::pair<std::string, std::string>> list)
|
||||
{
|
||||
set.clear();
|
||||
|
||||
for (const auto& item : list) {
|
||||
if (item.first == "*") {
|
||||
// insert wildcard
|
||||
set.insert(item.first);
|
||||
}
|
||||
else {
|
||||
if (!isRuleSupported(item.first)) {
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Unrecognized rule \"" + item.first + "\""));
|
||||
}
|
||||
|
||||
if (!isRuleValid(item.first, item.second)) {
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Malformed " + item.first + " \"" + item.second + "\""));
|
||||
}
|
||||
set.insert(item.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetworkPredicateBase::parseWhitelist(const boost::property_tree::ptree& list)
|
||||
{
|
||||
parseList(m_whitelist, list, "whitelist");
|
||||
}
|
||||
|
||||
void
|
||||
NetworkPredicateBase::parseBlacklist(const boost::property_tree::ptree& list)
|
||||
{
|
||||
parseList(m_blacklist, list, "blacklist");
|
||||
}
|
||||
|
||||
void
|
||||
NetworkPredicateBase::assign(std::initializer_list<std::pair<std::string, std::string>> whitelist,
|
||||
std::initializer_list<std::pair<std::string, std::string>> blacklist)
|
||||
{
|
||||
parseList(m_whitelist, whitelist);
|
||||
parseList(m_blacklist, blacklist);
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkInterfacePredicate::isRuleSupported(const std::string& key)
|
||||
{
|
||||
return key == "ifname" || key == "ether" || key == "subnet";
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkInterfacePredicate::isRuleValid(const std::string& key, const std::string& value)
|
||||
{
|
||||
if (key == "ifname") {
|
||||
// very basic sanity check for interface names
|
||||
return !value.empty();
|
||||
}
|
||||
else if (key == "ether") {
|
||||
// validate ethernet address
|
||||
return !ndn::ethernet::Address::fromString(value).isNull();
|
||||
}
|
||||
else if (key == "subnet") {
|
||||
// example subnet: 10.0.0.0/8
|
||||
return Network::isValidCidr(value);
|
||||
}
|
||||
else {
|
||||
BOOST_THROW_EXCEPTION(std::logic_error("Only supported rules are expected"));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IpAddressPredicate::isRuleSupported(const std::string& key)
|
||||
{
|
||||
return key == "subnet";
|
||||
}
|
||||
|
||||
bool
|
||||
IpAddressPredicate::isRuleValid(const std::string& key, const std::string& value)
|
||||
{
|
||||
if (key == "subnet") {
|
||||
// example subnet: 10.0.0.0/8
|
||||
return Network::isValidCidr(value);
|
||||
}
|
||||
else {
|
||||
BOOST_THROW_EXCEPTION(std::logic_error("Only supported rules are expected"));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkPredicateBase::operator==(const NetworkPredicateBase& other) const
|
||||
{
|
||||
return this->m_whitelist == other.m_whitelist &&
|
||||
this->m_blacklist == other.m_blacklist;
|
||||
}
|
||||
|
||||
static bool
|
||||
doesMatchPattern(const std::string& ifname, const std::string& pattern)
|
||||
{
|
||||
// use fnmatch(3) to provide unix glob-style matching for interface names
|
||||
// fnmatch returns 0 if there is a match
|
||||
return ::fnmatch(pattern.data(), ifname.data(), 0) == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
doesNetifMatchRule(const ndn::net::NetworkInterface& netif, const std::string& rule)
|
||||
{
|
||||
// if '/' is in rule, this is a subnet, check if IP in subnet
|
||||
if (rule.find('/') != std::string::npos) {
|
||||
Network n = boost::lexical_cast<Network>(rule);
|
||||
for (const auto& addr : netif.getNetworkAddresses()) {
|
||||
if (n.doesContain(addr.getIp())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rule == "*" ||
|
||||
doesMatchPattern(netif.getName(), rule) ||
|
||||
netif.getEthernetAddress().toString() == rule;
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkInterfacePredicate::operator()(const ndn::net::NetworkInterface& netif) const
|
||||
{
|
||||
return std::any_of(m_whitelist.begin(), m_whitelist.end(), bind(&doesNetifMatchRule, std::cref(netif), _1)) &&
|
||||
std::none_of(m_blacklist.begin(), m_blacklist.end(), bind(&doesNetifMatchRule, std::cref(netif), _1));
|
||||
}
|
||||
|
||||
static bool
|
||||
doesAddressMatchRule(const boost::asio::ip::address& address, const std::string& rule)
|
||||
{
|
||||
// if '/' is in rule, this is a subnet, check if IP in subnet
|
||||
if (rule.find('/') != std::string::npos) {
|
||||
Network n = boost::lexical_cast<Network>(rule);
|
||||
if (n.doesContain(address)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return rule == "*";
|
||||
}
|
||||
|
||||
bool
|
||||
IpAddressPredicate::operator()(const boost::asio::ip::address& address) const
|
||||
{
|
||||
return std::any_of(m_whitelist.begin(), m_whitelist.end(), bind(&doesAddressMatchRule, std::cref(address), _1)) &&
|
||||
std::none_of(m_blacklist.begin(), m_blacklist.end(), bind(&doesAddressMatchRule, std::cref(address), _1));
|
||||
}
|
||||
|
||||
} // namespace nfd
|
||||
@@ -0,0 +1,133 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NFD_CORE_NETWORK_PREDICATE_HPP
|
||||
#define NFD_CORE_NETWORK_PREDICATE_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include <ndn-cxx/net/network-interface.hpp>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
class NetworkPredicateBase
|
||||
{
|
||||
public:
|
||||
NetworkPredicateBase();
|
||||
|
||||
virtual
|
||||
~NetworkPredicateBase();
|
||||
|
||||
/**
|
||||
* \brief Set the whitelist to "*" and clear the blacklist
|
||||
*/
|
||||
void
|
||||
clear();
|
||||
|
||||
void
|
||||
parseWhitelist(const boost::property_tree::ptree& list);
|
||||
|
||||
void
|
||||
parseBlacklist(const boost::property_tree::ptree& list);
|
||||
|
||||
void
|
||||
assign(std::initializer_list<std::pair<std::string, std::string>> whitelist,
|
||||
std::initializer_list<std::pair<std::string, std::string>> blacklist);
|
||||
|
||||
bool
|
||||
operator==(const NetworkPredicateBase& other) const;
|
||||
|
||||
bool
|
||||
operator!=(const NetworkPredicateBase& other) const
|
||||
{
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool
|
||||
isRuleSupported(const std::string& key) = 0;
|
||||
|
||||
virtual bool
|
||||
isRuleValid(const std::string& key, const std::string& value) = 0;
|
||||
|
||||
void
|
||||
parseList(std::set<std::string>& set, const boost::property_tree::ptree& list, const std::string& section);
|
||||
|
||||
void
|
||||
parseList(std::set<std::string>& set, std::initializer_list<std::pair<std::string, std::string>> list);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
std::set<std::string> m_whitelist;
|
||||
std::set<std::string> m_blacklist;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Represents a predicate to accept or reject a ndn::net::NetworkInterface.
|
||||
*
|
||||
* The predicate consists of a whitelist and a blacklist. Whitelist and blacklist can contain,
|
||||
* in no particular order, interface names (e.g., `ifname eth0`), MAC addresses (e.g., `ether
|
||||
* 85:3b:4d:d3:5f:c2`), IPv4 and IPv6 subnets (e.g., `subnet 192.0.2.0/24` or `subnet
|
||||
* 2001:db8:2::/64`), or a wildcard (`*`) that matches all interfaces. A
|
||||
* ndn::net::NetworkInterface is accepted if it matches any entry in the whitelist and none of
|
||||
* the entries in the blacklist.
|
||||
*/
|
||||
class NetworkInterfacePredicate : public NetworkPredicateBase
|
||||
{
|
||||
public:
|
||||
bool
|
||||
operator()(const ndn::net::NetworkInterface& netif) const;
|
||||
|
||||
private:
|
||||
bool
|
||||
isRuleSupported(const std::string& key) final;
|
||||
|
||||
bool
|
||||
isRuleValid(const std::string& key, const std::string& value) final;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Represents a predicate to accept or reject an IP address.
|
||||
*
|
||||
* The predicate consists of a whitelist and a blacklist. Whitelist and blacklist can contain,
|
||||
* in no particular order, IPv4 and IPv6 subnets (e.g., `subnet 192.0.2.0/24` or `subnet
|
||||
* 2001:db8:2::/64`) or a wildcard (`*`) that matches all IP addresses. An IP address is
|
||||
* accepted if it matches any entry in the whitelist and none of the entries in the blacklist.
|
||||
*/
|
||||
class IpAddressPredicate : public NetworkPredicateBase
|
||||
{
|
||||
public:
|
||||
bool
|
||||
operator()(const boost::asio::ip::address& address) const;
|
||||
|
||||
private:
|
||||
bool
|
||||
isRuleSupported(const std::string& key) final;
|
||||
|
||||
bool
|
||||
isRuleValid(const std::string& key, const std::string& value) final;
|
||||
};
|
||||
|
||||
} // namespace nfd
|
||||
|
||||
#endif // NFD_CORE_NETWORK_PREDICATE_HPP
|
||||
+44
-24
@@ -1,12 +1,12 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis
|
||||
* The University of Memphis.
|
||||
*
|
||||
* This file is part of NFD (Named Data Networking Forwarding Daemon).
|
||||
* See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
#include "network.hpp"
|
||||
|
||||
#include <ndn-cxx/net/address-converter.hpp>
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
@@ -66,28 +66,13 @@ Network::isValidCidr(const std::string& cidr)
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::system::error_code invalidIp;
|
||||
boost::asio::ip::address_v4::from_string(cidr.substr(0, pos), invalidIp);
|
||||
if (invalidIp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto prefixLenStr = cidr.substr(pos + 1);
|
||||
if (!std::all_of(prefixLenStr.begin(), prefixLenStr.end(), ::isdigit)) {
|
||||
return false;
|
||||
}
|
||||
int prefixLen = -1;
|
||||
try {
|
||||
prefixLen = boost::lexical_cast<int>(prefixLenStr);
|
||||
boost::lexical_cast<Network>(cidr);
|
||||
return true;
|
||||
}
|
||||
catch (const boost::bad_lexical_cast&) {
|
||||
return false;
|
||||
}
|
||||
if (prefixLen < 0 || prefixLen > 32) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
@@ -106,14 +91,44 @@ operator>>(std::istream& is, Network& network)
|
||||
|
||||
size_t position = networkStr.find('/');
|
||||
if (position == std::string::npos) {
|
||||
network.m_minAddress = ndn::ip::addressFromString(networkStr);
|
||||
network.m_maxAddress = ndn::ip::addressFromString(networkStr);
|
||||
try {
|
||||
network.m_minAddress = ip::address::from_string(networkStr);
|
||||
network.m_maxAddress = ip::address::from_string(networkStr);
|
||||
}
|
||||
catch (const boost::system::system_error&) {
|
||||
is.setstate(std::ios::failbit);
|
||||
return is;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ip::address address = ndn::ip::addressFromString(networkStr.substr(0, position));
|
||||
size_t mask = boost::lexical_cast<size_t>(networkStr.substr(position+1));
|
||||
boost::system::error_code ec;
|
||||
auto address = ip::address::from_string(networkStr.substr(0, position), ec);
|
||||
if (ec) {
|
||||
is.setstate(std::ios::failbit);
|
||||
return is;
|
||||
}
|
||||
|
||||
auto prefixLenStr = networkStr.substr(position + 1);
|
||||
if (!std::all_of(prefixLenStr.begin(), prefixLenStr.end(),
|
||||
[] (unsigned char c) { return std::isdigit(c); })) {
|
||||
is.setstate(std::ios::failbit);
|
||||
return is;
|
||||
}
|
||||
size_t mask;
|
||||
try {
|
||||
mask = boost::lexical_cast<size_t>(prefixLenStr);
|
||||
}
|
||||
catch (const boost::bad_lexical_cast&) {
|
||||
is.setstate(std::ios::failbit);
|
||||
return is;
|
||||
}
|
||||
|
||||
if (address.is_v4()) {
|
||||
if (mask > 32) {
|
||||
is.setstate(std::ios::failbit);
|
||||
return is;
|
||||
}
|
||||
|
||||
ip::address_v4::bytes_type maskBytes = boost::initialized_value;
|
||||
for (size_t i = 0; i < mask; i++) {
|
||||
size_t byteId = i / 8;
|
||||
@@ -134,6 +149,11 @@ operator>>(std::istream& is, Network& network)
|
||||
network.m_maxAddress = ip::address_v4(max);
|
||||
}
|
||||
else {
|
||||
if (mask > 128) {
|
||||
is.setstate(std::ios::failbit);
|
||||
return is;
|
||||
}
|
||||
|
||||
ip::address_v6::bytes_type maskBytes = boost::initialized_value;
|
||||
for (size_t i = 0; i < mask; i++) {
|
||||
size_t byteId = i / 8;
|
||||
|
||||
+15
-11
@@ -31,7 +31,7 @@
|
||||
|
||||
namespace nfd {
|
||||
|
||||
NFD_LOG_INIT("PrivilegeHelper");
|
||||
NFD_LOG_INIT(PrivilegeHelper);
|
||||
|
||||
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
|
||||
uid_t PrivilegeHelper::s_normalUid = ::geteuid();
|
||||
@@ -45,13 +45,13 @@ void
|
||||
PrivilegeHelper::initialize(const std::string& userName, const std::string& groupName)
|
||||
{
|
||||
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
|
||||
static const size_t MAX_GROUP_BUFFER_SIZE = 16384; // 16kB
|
||||
static const size_t MAX_GROUP_BUFFER_SIZE = 16384; // 16 KiB
|
||||
static const size_t MAX_PASSWD_BUFFER_SIZE = 16384;
|
||||
|
||||
static const size_t FALLBACK_GROUP_BUFFER_SIZE = 1024;
|
||||
static const size_t FALLBACK_PASSWD_BUFFER_SIZE = 1024;
|
||||
|
||||
NFD_LOG_TRACE("initializing privilege helper with user \"" << userName << "\""
|
||||
NFD_LOG_TRACE("initializing with user \"" << userName << "\""
|
||||
<< " group \"" << groupName << "\"");
|
||||
|
||||
// workflow from man getpwnam_r
|
||||
@@ -62,21 +62,20 @@ PrivilegeHelper::initialize(const std::string& userName, const std::string& grou
|
||||
if (groupSize == -1)
|
||||
groupSize = FALLBACK_GROUP_BUFFER_SIZE;
|
||||
|
||||
std::vector<char> groupBuffer(groupSize);
|
||||
std::vector<char> groupBuffer(static_cast<size_t>(groupSize));
|
||||
struct group group;
|
||||
struct group* groupResult = nullptr;
|
||||
|
||||
int errorCode = getgrnam_r(groupName.data(), &group,
|
||||
&groupBuffer[0], groupBuffer.size(), &groupResult);
|
||||
groupBuffer.data(), groupBuffer.size(), &groupResult);
|
||||
|
||||
while (errorCode == ERANGE) {
|
||||
if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
|
||||
throw Error("Cannot allocate large enough buffer for struct group");
|
||||
|
||||
groupBuffer.resize(groupBuffer.size() * 2);
|
||||
|
||||
errorCode = getgrnam_r(groupName.data(), &group,
|
||||
&groupBuffer[0], groupBuffer.size(), &groupResult);
|
||||
groupBuffer.data(), groupBuffer.size(), &groupResult);
|
||||
}
|
||||
|
||||
if (errorCode != 0 || !groupResult)
|
||||
@@ -91,21 +90,20 @@ PrivilegeHelper::initialize(const std::string& userName, const std::string& grou
|
||||
if (passwdSize == -1)
|
||||
passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;
|
||||
|
||||
std::vector<char> passwdBuffer(passwdSize);
|
||||
std::vector<char> passwdBuffer(static_cast<size_t>(passwdSize));
|
||||
struct passwd passwd;
|
||||
struct passwd* passwdResult = nullptr;
|
||||
|
||||
int errorCode = getpwnam_r(userName.data(), &passwd,
|
||||
&passwdBuffer[0], passwdBuffer.size(), &passwdResult);
|
||||
passwdBuffer.data(), passwdBuffer.size(), &passwdResult);
|
||||
|
||||
while (errorCode == ERANGE) {
|
||||
if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
|
||||
throw Error("Cannot allocate large enough buffer for struct passwd");
|
||||
|
||||
passwdBuffer.resize(passwdBuffer.size() * 2);
|
||||
|
||||
errorCode = getpwnam_r(userName.data(), &passwd,
|
||||
&passwdBuffer[0], passwdBuffer.size(), &passwdResult);
|
||||
passwdBuffer.data(), passwdBuffer.size(), &passwdResult);
|
||||
}
|
||||
|
||||
if (errorCode != 0 || !passwdResult)
|
||||
@@ -123,6 +121,9 @@ PrivilegeHelper::initialize(const std::string& userName, const std::string& grou
|
||||
void
|
||||
PrivilegeHelper::drop()
|
||||
{
|
||||
if (::geteuid() == s_normalUid && ::getegid() == s_normalGid)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
|
||||
NFD_LOG_TRACE("dropping to effective gid=" << s_normalGid);
|
||||
if (::setegid(s_normalGid) != 0)
|
||||
@@ -141,6 +142,9 @@ PrivilegeHelper::drop()
|
||||
void
|
||||
PrivilegeHelper::raise()
|
||||
{
|
||||
if (::geteuid() == s_privilegedUid && ::getegid() == s_privilegedGid)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
|
||||
NFD_LOG_TRACE("elevating to effective uid=" << s_privilegedUid);
|
||||
if (::seteuid(s_privilegedUid) != 0)
|
||||
|
||||
+11
-11
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -33,7 +33,7 @@ namespace nfd {
|
||||
/**
|
||||
* \brief implements the Mean-Deviation RTT estimator
|
||||
*
|
||||
* reference: ns3::RttMeanDeviation
|
||||
* \sa ns3::RttMeanDeviation
|
||||
*
|
||||
* This RttEstimator algorithm is designed for TCP, which is a continuous stream.
|
||||
* NDN Interest-Data traffic is not always a continuous stream,
|
||||
@@ -43,18 +43,18 @@ namespace nfd {
|
||||
class RttEstimator
|
||||
{
|
||||
public:
|
||||
typedef time::microseconds Duration;
|
||||
|
||||
static Duration
|
||||
getInitialRtt(void)
|
||||
{
|
||||
return time::seconds(1);
|
||||
}
|
||||
using Duration = time::microseconds;
|
||||
|
||||
RttEstimator(uint16_t maxMultiplier = 16,
|
||||
Duration minRto = time::milliseconds(1),
|
||||
Duration minRto = 1_ms,
|
||||
double gain = 0.1);
|
||||
|
||||
static Duration
|
||||
getInitialRtt()
|
||||
{
|
||||
return 1_s;
|
||||
}
|
||||
|
||||
void
|
||||
addMeasurement(Duration measure);
|
||||
|
||||
|
||||
+14
-15
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -27,6 +27,7 @@
|
||||
#define NFD_CORE_SCHEDULER_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
namespace nfd {
|
||||
@@ -34,40 +35,40 @@ namespace scheduler {
|
||||
|
||||
using ndn::Scheduler;
|
||||
|
||||
/** \class EventId
|
||||
* \brief Opaque type (shared_ptr) representing ID of a scheduled event
|
||||
/** \class nfd::scheduler::EventId
|
||||
* \brief Opaque handle for a scheduled event.
|
||||
*/
|
||||
using ndn::EventId;
|
||||
|
||||
using ndn::util::scheduler::EventCallback;
|
||||
|
||||
/** \brief schedule an event
|
||||
/** \brief Schedule an event.
|
||||
*/
|
||||
EventId
|
||||
schedule(time::nanoseconds after, const EventCallback& event);
|
||||
|
||||
/** \brief cancel a scheduled event
|
||||
/** \brief Cancel a scheduled event.
|
||||
*/
|
||||
void
|
||||
cancel(const EventId& eventId);
|
||||
|
||||
/** \brief cancels an event automatically upon destruction
|
||||
/** \brief Cancels an event automatically upon destruction.
|
||||
*/
|
||||
class ScopedEventId : noncopyable
|
||||
{
|
||||
public:
|
||||
ScopedEventId();
|
||||
|
||||
/** \brief implicit constructor from EventId
|
||||
/** \brief Implicit constructor from EventId.
|
||||
* \param event the event to be cancelled upon destruction
|
||||
*/
|
||||
ScopedEventId(const EventId& event);
|
||||
|
||||
/** \brief move constructor
|
||||
/** \brief Move constructor.
|
||||
*/
|
||||
ScopedEventId(ScopedEventId&& other);
|
||||
|
||||
/** \brief assigns an event
|
||||
/** \brief Assigns an event.
|
||||
*
|
||||
* If a different event has been assigned to this instance previously,
|
||||
* that event will be cancelled immediately.
|
||||
@@ -75,17 +76,16 @@ public:
|
||||
ScopedEventId&
|
||||
operator=(const EventId& event);
|
||||
|
||||
/** \brief cancels the event
|
||||
/** \brief Cancels the event.
|
||||
*/
|
||||
~ScopedEventId();
|
||||
|
||||
/** \brief cancels the event manually
|
||||
/** \brief Cancels the event manually.
|
||||
*/
|
||||
void
|
||||
cancel();
|
||||
|
||||
/** \brief releases the event so that it won't be disconnected
|
||||
* when this ScopedEventId is destructed
|
||||
/** \brief Releases the event so that it won't be cancelled when this ScopedEventId is destructed.
|
||||
*/
|
||||
void
|
||||
release();
|
||||
@@ -95,7 +95,6 @@ private:
|
||||
};
|
||||
|
||||
} // namespace scheduler
|
||||
|
||||
} // namespace nfd
|
||||
|
||||
#endif // NFD_CORE_SCHEDULER_HPP
|
||||
+10
-20
@@ -37,11 +37,11 @@ namespace face {
|
||||
/** \brief Prototype for the callback that is invoked when a face is created
|
||||
* (in response to an incoming connection or after a connection is established)
|
||||
*/
|
||||
using FaceCreatedCallback = function<void(const shared_ptr<Face>& face)>;
|
||||
using FaceCreatedCallback = std::function<void(const shared_ptr<Face>& face)>;
|
||||
|
||||
/** \brief Prototype for the callback that is invoked when a face fails to be created
|
||||
*/
|
||||
using FaceCreationFailedCallback = function<void(uint32_t status, const std::string& reason)>;
|
||||
using FaceCreationFailedCallback = std::function<void(uint32_t status, const std::string& reason)>;
|
||||
|
||||
/** \brief represent a channel that communicates on a local endpoint
|
||||
* \sa FaceSystem
|
||||
@@ -84,25 +84,15 @@ private:
|
||||
* Parameters are passed as a struct rather than individually, so that a future change in the list
|
||||
* of parameters does not require an update to the method signature in all subclasses.
|
||||
*/
|
||||
class FaceParams
|
||||
struct FaceParams
|
||||
{
|
||||
public:
|
||||
// get rid of this constructor and use aggregate init + NSDMIs when we switch to C++14
|
||||
FaceParams() noexcept
|
||||
: persistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
|
||||
, wantLocalFields(false)
|
||||
, wantLpReliability(false)
|
||||
, wantCongestionMarking(boost::logic::indeterminate)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
ndn::nfd::FacePersistency persistency;
|
||||
ndn::optional<time::nanoseconds> baseCongestionMarkingInterval;
|
||||
ndn::optional<uint64_t> defaultCongestionThreshold;
|
||||
bool wantLocalFields;
|
||||
bool wantLpReliability;
|
||||
boost::logic::tribool wantCongestionMarking;
|
||||
ndn::nfd::FacePersistency persistency = ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
|
||||
optional<time::nanoseconds> baseCongestionMarkingInterval;
|
||||
optional<uint64_t> defaultCongestionThreshold;
|
||||
optional<ssize_t> mtu;
|
||||
bool wantLocalFields = false;
|
||||
bool wantLpReliability = false;
|
||||
boost::logic::tribool wantCongestionMarking = boost::logic::indeterminate;
|
||||
};
|
||||
|
||||
/** \brief invokes a callback when the face is closed
|
||||
|
||||
@@ -72,12 +72,10 @@ protected:
|
||||
doSend(Transport::Packet&& packet) override;
|
||||
|
||||
void
|
||||
handleSend(const boost::system::error_code& error,
|
||||
size_t nBytesSent, const Block& payload);
|
||||
handleSend(const boost::system::error_code& error, size_t nBytesSent);
|
||||
|
||||
void
|
||||
handleReceive(const boost::system::error_code& error,
|
||||
size_t nBytesReceived);
|
||||
handleReceive(const boost::system::error_code& error, size_t nBytesReceived);
|
||||
|
||||
void
|
||||
processErrorCode(const boost::system::error_code& error);
|
||||
@@ -95,7 +93,7 @@ protected:
|
||||
typename protocol::socket m_socket;
|
||||
typename protocol::endpoint m_sender;
|
||||
|
||||
NFD_LOG_INCLASS_DECLARE();
|
||||
NFD_LOG_MEMBER_DECL();
|
||||
|
||||
private:
|
||||
std::array<uint8_t, ndn::MAX_NDN_PACKET_SIZE> m_receiveBuffer;
|
||||
@@ -120,9 +118,9 @@ DatagramTransport<T, U>::DatagramTransport(typename DatagramTransport::protocol:
|
||||
}
|
||||
|
||||
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
|
||||
bind(&DatagramTransport<T, U>::handleReceive, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
[this] (auto&&... args) {
|
||||
this->handleReceive(std::forward<decltype(args)>(args)...);
|
||||
});
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
@@ -164,10 +162,10 @@ DatagramTransport<T, U>::doSend(Transport::Packet&& packet)
|
||||
NFD_LOG_FACE_TRACE(__func__);
|
||||
|
||||
m_socket.async_send(boost::asio::buffer(packet.packet),
|
||||
bind(&DatagramTransport<T, U>::handleSend, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred,
|
||||
packet.packet));
|
||||
// packet.packet is copied into the lambda to retain the underlying Buffer
|
||||
[this, p = packet.packet] (auto&&... args) {
|
||||
this->handleSend(std::forward<decltype(args)>(args)...);
|
||||
});
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
@@ -202,23 +200,20 @@ DatagramTransport<T, U>::receiveDatagram(const uint8_t* buffer, size_t nBytesRec
|
||||
|
||||
template<class T, class U>
|
||||
void
|
||||
DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error,
|
||||
size_t nBytesReceived)
|
||||
DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error, size_t nBytesReceived)
|
||||
{
|
||||
receiveDatagram(m_receiveBuffer.data(), nBytesReceived, error);
|
||||
|
||||
if (m_socket.is_open())
|
||||
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
|
||||
bind(&DatagramTransport<T, U>::handleReceive, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
[this] (auto&&... args) {
|
||||
this->handleReceive(std::forward<decltype(args)>(args)...);
|
||||
});
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
void
|
||||
DatagramTransport<T, U>::handleSend(const boost::system::error_code& error,
|
||||
size_t nBytesSent, const Block& payload)
|
||||
// 'payload' is unused; it's needed to retain the underlying Buffer
|
||||
DatagramTransport<T, U>::handleSend(const boost::system::error_code& error, size_t nBytesSent)
|
||||
{
|
||||
if (error)
|
||||
return processErrorCode(error);
|
||||
@@ -266,7 +261,7 @@ DatagramTransport<T, U>::resetRecentlyReceived()
|
||||
|
||||
template<class T, class U>
|
||||
Transport::EndpointId
|
||||
DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint& ep)
|
||||
DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint&)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("EthernetChannel");
|
||||
NFD_LOG_INIT(EthernetChannel);
|
||||
|
||||
EthernetChannel::EthernetChannel(shared_ptr<const ndn::net::NetworkInterface> localEndpoint,
|
||||
time::nanoseconds idleTimeout)
|
||||
@@ -65,7 +65,7 @@ EthernetChannel::connect(const ethernet::Address& remoteEndpoint,
|
||||
catch (const boost::system::system_error& e) {
|
||||
NFD_LOG_CHAN_DEBUG("Face creation for " << remoteEndpoint << " failed: " << e.what());
|
||||
if (onConnectFailed)
|
||||
onConnectFailed(504, std::string("Face creation failed: ") + e.what());
|
||||
onConnectFailed(504, "Face creation failed: "s + e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,9 +102,7 @@ EthernetChannel::asyncRead(const FaceCreatedCallback& onFaceCreated,
|
||||
const FaceCreationFailedCallback& onReceiveFailed)
|
||||
{
|
||||
m_socket.async_read_some(boost::asio::null_buffers(),
|
||||
bind(&EthernetChannel::handleRead, this,
|
||||
boost::asio::placeholders::error,
|
||||
onFaceCreated, onReceiveFailed));
|
||||
[=] (const auto& e, auto) { this->handleRead(e, onFaceCreated, onReceiveFailed); });
|
||||
}
|
||||
|
||||
void
|
||||
@@ -172,7 +170,7 @@ EthernetChannel::processIncomingPacket(const uint8_t* packet, size_t length,
|
||||
catch (const EthernetTransport::Error& e) {
|
||||
NFD_LOG_CHAN_DEBUG("Face creation for " << sender << " failed: " << e.what());
|
||||
if (onReceiveFailed)
|
||||
onReceiveFailed(504, std::string("Face creation failed: ") + e.what());
|
||||
onReceiveFailed(504, "Face creation failed: "s + e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -205,7 +203,8 @@ EthernetChannel::createFace(const ethernet::Address& remoteEndpoint,
|
||||
|
||||
auto linkService = make_unique<GenericLinkService>(options);
|
||||
auto transport = make_unique<UnicastEthernetTransport>(*m_localEndpoint, remoteEndpoint,
|
||||
params.persistency, m_idleFaceTimeout);
|
||||
params.persistency, m_idleFaceTimeout,
|
||||
params.mtu);
|
||||
auto face = make_shared<Face>(std::move(linkService), std::move(transport));
|
||||
|
||||
m_channelFaces[remoteEndpoint] = face;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("EthernetFactory");
|
||||
NFD_LOG_INIT(EthernetFactory);
|
||||
NFD_REGISTER_PROTOCOL_FACTORY(EthernetFactory);
|
||||
|
||||
const std::string&
|
||||
@@ -46,11 +46,10 @@ EthernetFactory::getId()
|
||||
EthernetFactory::EthernetFactory(const CtorParams& params)
|
||||
: ProtocolFactory(params)
|
||||
{
|
||||
m_netifAddConn = netmon->onInterfaceAdded.connect(
|
||||
[this] (const shared_ptr<const ndn::net::NetworkInterface>& netif) {
|
||||
this->applyUnicastConfigToNetif(netif);
|
||||
this->applyMcastConfigToNetif(*netif);
|
||||
});
|
||||
m_netifAddConn = netmon->onInterfaceAdded.connect([this] (const auto& netif) {
|
||||
this->applyUnicastConfigToNetif(netif);
|
||||
this->applyMcastConfigToNetif(*netif);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -201,6 +200,13 @@ EthernetFactory::createFace(const CreateFaceRequest& req,
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.params.mtu && *req.params.mtu < Transport::MIN_MTU) {
|
||||
// The specified MTU must be greater than the minimum possible
|
||||
NFD_LOG_TRACE("createFace cannot create a face with an MTU less than " << Transport::MIN_MTU);
|
||||
onFailure(406, "MTU cannot be less than " + to_string(Transport::MIN_MTU));
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& i : m_channels) {
|
||||
if (i.first == localEndpoint) {
|
||||
i.second->connect(remoteEndpoint, req.params, onCreated, onFailure);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "ethernet-protocol.hpp"
|
||||
|
||||
#include <arpa/inet.h> // for ntohs()
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
namespace nfd {
|
||||
namespace ethernet {
|
||||
@@ -41,8 +41,9 @@ checkFrameHeader(const uint8_t* packet, size_t length,
|
||||
|
||||
// in some cases VLAN-tagged frames may survive the BPF filter,
|
||||
// make sure we do not process those frames (see #3348)
|
||||
if (ntohs(eh->ether_type) != ETHERTYPE_NDN)
|
||||
return {nullptr, "Received frame with wrong ethertype: " + to_string(ntohs(eh->ether_type))};
|
||||
uint16_t ethertype = boost::endian::big_to_native(eh->ether_type);
|
||||
if (ethertype != ETHERTYPE_NDN)
|
||||
return {nullptr, "Received frame with wrong ethertype: " + to_string(ethertype)};
|
||||
|
||||
#ifdef _DEBUG
|
||||
Address shost(eh->ether_shost);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -29,13 +29,14 @@
|
||||
|
||||
#include <pcap/pcap.h>
|
||||
|
||||
#include <arpa/inet.h> // for htons()
|
||||
#include <cstring> // for memcpy()
|
||||
#include <cstring> // for memcpy()
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("EthernetTransport");
|
||||
NFD_LOG_INIT(EthernetTransport);
|
||||
|
||||
EthernetTransport::EthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
|
||||
const ethernet::Address& remoteEndpoint)
|
||||
@@ -101,7 +102,7 @@ EthernetTransport::sendPacket(const ndn::Block& block)
|
||||
}
|
||||
|
||||
// construct and prepend the ethernet header
|
||||
static uint16_t ethertype = htons(ethernet::ETHERTYPE_NDN);
|
||||
uint16_t ethertype = boost::endian::native_to_big(ethernet::ETHERTYPE_NDN);
|
||||
buffer.prependByteArray(reinterpret_cast<const uint8_t*>(ðertype), ethernet::TYPE_LEN);
|
||||
buffer.prependByteArray(m_srcAddress.data(), m_srcAddress.size());
|
||||
buffer.prependByteArray(m_destAddress.data(), m_destAddress.size());
|
||||
@@ -122,8 +123,7 @@ void
|
||||
EthernetTransport::asyncRead()
|
||||
{
|
||||
m_socket.async_read_some(boost::asio::null_buffers(),
|
||||
bind(&EthernetTransport::handleRead, this,
|
||||
boost::asio::placeholders::error));
|
||||
[this] (const auto& e, auto) { this->handleRead(e); });
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("FaceSystem");
|
||||
NFD_LOG_INIT(FaceSystem);
|
||||
|
||||
FaceSystem::FaceSystem(FaceTable& faceTable, shared_ptr<ndn::net::NetworkMonitor> netmon)
|
||||
: m_faceTable(faceTable)
|
||||
@@ -47,7 +47,7 @@ FaceSystem::FaceSystem(FaceTable& faceTable, shared_ptr<ndn::net::NetworkMonitor
|
||||
ProtocolFactoryCtorParams
|
||||
FaceSystem::makePFCtorParams()
|
||||
{
|
||||
auto addFace = bind(&FaceTable::add, &m_faceTable, _1);
|
||||
auto addFace = [&ft = m_faceTable] (auto face) { ft.add(std::move(face)); };
|
||||
return {addFace, m_netmon};
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "core/config-file.hpp"
|
||||
#include "core/network-interface-predicate.hpp"
|
||||
#include "core/network-predicate.hpp"
|
||||
#include <ndn-cxx/net/network-address.hpp>
|
||||
#include <ndn-cxx/net/network-interface.hpp>
|
||||
#include <ndn-cxx/net/network-monitor.hpp>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -68,7 +68,7 @@ class Face
|
||||
#ifndef WITH_TESTS
|
||||
final
|
||||
#endif
|
||||
: public enable_shared_from_this<Face>, noncopyable
|
||||
: public std::enable_shared_from_this<Face>, noncopyable
|
||||
{
|
||||
public:
|
||||
Face(unique_ptr<LinkService> service, unique_ptr<Transport> transport);
|
||||
|
||||
@@ -32,21 +32,10 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("GenericLinkService");
|
||||
NFD_LOG_INIT(GenericLinkService);
|
||||
|
||||
constexpr uint32_t DEFAULT_CONGESTION_THRESHOLD_DIVISOR = 2;
|
||||
|
||||
GenericLinkService::Options::Options()
|
||||
: allowLocalFields(false)
|
||||
, allowFragmentation(false)
|
||||
, allowReassembly(false)
|
||||
, allowCongestionMarking(false)
|
||||
, baseCongestionMarkingInterval(time::milliseconds(100)) // Interval from RFC 8289 (CoDel)
|
||||
, defaultCongestionThreshold(65536) // This default value works well for a queue capacity of 200KiB
|
||||
, allowSelfLearning(false)
|
||||
{
|
||||
}
|
||||
|
||||
GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
|
||||
: m_options(options)
|
||||
, m_fragmenter(m_options.fragmenterOptions, this)
|
||||
@@ -57,8 +46,8 @@ GenericLinkService::GenericLinkService(const GenericLinkService::Options& option
|
||||
, m_lastMarkTime(time::steady_clock::TimePoint::min())
|
||||
, m_nMarkedSinceInMarkingState(0)
|
||||
{
|
||||
m_reassembler.beforeTimeout.connect(bind([this] { ++this->nReassemblyTimeouts; }));
|
||||
m_reliability.onDroppedInterest.connect([this] (const Interest& i) { this->notifyDroppedInterest(i); });
|
||||
m_reassembler.beforeTimeout.connect([this] (auto...) { ++this->nReassemblyTimeouts; });
|
||||
m_reliability.onDroppedInterest.connect([this] (const auto& i) { this->notifyDroppedInterest(i); });
|
||||
nReassembling.observe(&m_reassembler);
|
||||
}
|
||||
|
||||
@@ -226,7 +215,7 @@ GenericLinkService::assignSequence(lp::Packet& pkt)
|
||||
void
|
||||
GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
|
||||
{
|
||||
std::for_each(pkts.begin(), pkts.end(), bind(&GenericLinkService::assignSequence, this, _1));
|
||||
std::for_each(pkts.begin(), pkts.end(), [this] (auto& pkt) { this->assignSequence(pkt); });
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -98,16 +98,19 @@ public:
|
||||
class Options
|
||||
{
|
||||
public:
|
||||
Options();
|
||||
constexpr
|
||||
Options() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
/** \brief enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy
|
||||
*/
|
||||
bool allowLocalFields;
|
||||
bool allowLocalFields = false;
|
||||
|
||||
/** \brief enables fragmentation
|
||||
*/
|
||||
bool allowFragmentation;
|
||||
bool allowFragmentation = false;
|
||||
|
||||
/** \brief options for fragmentation
|
||||
*/
|
||||
@@ -115,7 +118,7 @@ public:
|
||||
|
||||
/** \brief enables reassembly
|
||||
*/
|
||||
bool allowReassembly;
|
||||
bool allowReassembly = false;
|
||||
|
||||
/** \brief options for reassembly
|
||||
*/
|
||||
@@ -127,19 +130,23 @@ public:
|
||||
|
||||
/** \brief enables send queue congestion detection and marking
|
||||
*/
|
||||
bool allowCongestionMarking;
|
||||
bool allowCongestionMarking = false;
|
||||
|
||||
/** \brief starting value for congestion marking interval
|
||||
*
|
||||
* The default value (100 ms) is taken from RFC 8289 (CoDel).
|
||||
*/
|
||||
time::nanoseconds baseCongestionMarkingInterval;
|
||||
time::nanoseconds baseCongestionMarkingInterval = 100_ms;
|
||||
|
||||
/** \brief default congestion threshold in bytes
|
||||
*
|
||||
* The default value (64 KiB) works well for a queue capacity of 200 KiB.
|
||||
*/
|
||||
size_t defaultCongestionThreshold;
|
||||
size_t defaultCongestionThreshold = 65536;
|
||||
|
||||
/** \brief enables self-learning forwarding support
|
||||
*/
|
||||
bool allowSelfLearning;
|
||||
bool allowSelfLearning = false;
|
||||
};
|
||||
|
||||
/** \brief counters provided by GenericLinkService
|
||||
@@ -147,7 +154,7 @@ public:
|
||||
using Counters = GenericLinkServiceCounters;
|
||||
|
||||
explicit
|
||||
GenericLinkService(const Options& options = Options());
|
||||
GenericLinkService(const Options& options = {});
|
||||
|
||||
/** \brief get Options used by GenericLinkService
|
||||
*/
|
||||
@@ -283,6 +290,7 @@ PROTECTED_WITH_TESTS_ELSE_PRIVATE:
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/// CongestionMark TLV-TYPE (3 octets) + CongestionMark TLV-LENGTH (1 octet) + sizeof(uint64_t)
|
||||
static constexpr size_t CONGESTION_MARK_SIZE = 3 + 1 + sizeof(uint64_t);
|
||||
|
||||
/// Time to mark next packet due to send queue congestion
|
||||
time::steady_clock::TimePoint m_nextMarkTime;
|
||||
/// Time last packet was marked
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -29,11 +29,11 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INCLASS_DEFINE(InternalForwarderTransport, "InternalForwarderTransport");
|
||||
NFD_LOG_MEMBER_INIT(InternalForwarderTransport, InternalForwarderTransport);
|
||||
NFD_LOG_MEMBER_INIT(InternalClientTransport, InternalClientTransport);
|
||||
|
||||
InternalForwarderTransport::InternalForwarderTransport(
|
||||
const FaceUri& localUri, const FaceUri& remoteUri,
|
||||
ndn::nfd::FaceScope scope, ndn::nfd::LinkType linkType)
|
||||
InternalForwarderTransport::InternalForwarderTransport(const FaceUri& localUri, const FaceUri& remoteUri,
|
||||
ndn::nfd::FaceScope scope, ndn::nfd::LinkType linkType)
|
||||
{
|
||||
this->setLocalUri(localUri);
|
||||
this->setRemoteUri(remoteUri);
|
||||
@@ -71,8 +71,6 @@ InternalForwarderTransport::doClose()
|
||||
this->setState(TransportState::CLOSED);
|
||||
}
|
||||
|
||||
NFD_LOG_INCLASS_DEFINE(InternalClientTransport, "InternalClientTransport");
|
||||
|
||||
static void
|
||||
asyncReceive(InternalTransportBase* recipient, const Block& packet)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -27,6 +27,7 @@
|
||||
#define NFD_DAEMON_FACE_INTERNAL_TRANSPORT_HPP
|
||||
|
||||
#include "transport.hpp"
|
||||
|
||||
#include <ndn-cxx/transport/transport.hpp>
|
||||
|
||||
namespace nfd {
|
||||
@@ -73,7 +74,7 @@ private:
|
||||
doSend(Packet&& packet) override;
|
||||
|
||||
private:
|
||||
NFD_LOG_INCLASS_DECLARE();
|
||||
NFD_LOG_MEMBER_DECL();
|
||||
};
|
||||
|
||||
/** \brief implements a client-side transport that can be paired with another
|
||||
@@ -117,7 +118,7 @@ public:
|
||||
send(const Block& header, const Block& payload) override;
|
||||
|
||||
private:
|
||||
NFD_LOG_INCLASS_DECLARE();
|
||||
NFD_LOG_MEMBER_DECL();
|
||||
|
||||
signal::ScopedConnection m_fwToClientTransmitConn;
|
||||
signal::ScopedConnection m_clientToFwTransmitConn;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -29,7 +29,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("LinkService");
|
||||
NFD_LOG_INIT(LinkService);
|
||||
|
||||
LinkService::LinkService()
|
||||
: m_face(nullptr)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -25,12 +25,13 @@
|
||||
|
||||
#include "lp-fragmenter.hpp"
|
||||
#include "link-service.hpp"
|
||||
|
||||
#include <ndn-cxx/encoding/tlv.hpp>
|
||||
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("LpFragmenter");
|
||||
NFD_LOG_INIT(LpFragmenter);
|
||||
|
||||
static_assert(lp::tlv::LpPacket < 253, "LpPacket TLV-TYPE must fit in 1 octet");
|
||||
static_assert(lp::tlv::Sequence < 253, "Sequence TLV-TYPE must fit in 1 octet");
|
||||
@@ -56,11 +57,6 @@ static const size_t MAX_FRAG_OVERHEAD =
|
||||
1 + 1 + 8 + // FragCount TLV
|
||||
1 + 9; // Fragment TLV-TYPE and TLV-LENGTH
|
||||
|
||||
LpFragmenter::Options::Options()
|
||||
: nMaxFragments(400)
|
||||
{
|
||||
}
|
||||
|
||||
LpFragmenter::LpFragmenter(const LpFragmenter::Options& options, const LinkService* linkService)
|
||||
: m_options(options)
|
||||
, m_linkService(linkService)
|
||||
@@ -121,7 +117,7 @@ LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
|
||||
// compute FragCount
|
||||
if (fragCount > m_options.nMaxFragments) {
|
||||
NFD_LOG_FACE_WARN("fragmentation error, FragCount over limit: DROP");
|
||||
return std::make_pair(false, std::vector<lp::Packet>{});
|
||||
return std::make_tuple(false, std::vector<lp::Packet>{});
|
||||
}
|
||||
|
||||
// populate fragments
|
||||
@@ -134,7 +130,7 @@ LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
|
||||
lp::Packet& frag = frags[fragIndex];
|
||||
frag.add<lp::FragIndexField>(fragIndex);
|
||||
frag.add<lp::FragCountField>(fragCount);
|
||||
frag.set<lp::FragmentField>(std::make_pair(fragBegin, fragEnd));
|
||||
frag.set<lp::FragmentField>({fragBegin, fragEnd});
|
||||
BOOST_ASSERT(frag.wireEncode().size() <= mtu);
|
||||
|
||||
++fragIndex;
|
||||
@@ -143,7 +139,7 @@ LpFragmenter::fragmentPacket(const lp::Packet& packet, size_t mtu)
|
||||
}
|
||||
BOOST_ASSERT(fragIndex == fragCount);
|
||||
|
||||
return std::make_pair(true, frags);
|
||||
return std::make_tuple(true, frags);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
|
||||
#define NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
|
||||
|
||||
#include "core/common.hpp"
|
||||
#include "face-log.hpp"
|
||||
|
||||
#include <ndn-cxx/lp/packet.hpp>
|
||||
@@ -36,26 +37,22 @@ namespace face {
|
||||
class LinkService;
|
||||
|
||||
/** \brief fragments network-layer packets into NDNLPv2 link-layer packets
|
||||
* \sa http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
|
||||
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
|
||||
*/
|
||||
class LpFragmenter
|
||||
{
|
||||
public:
|
||||
/** \brief Options that control the behavior of LpFragmenter
|
||||
*/
|
||||
class Options
|
||||
struct Options
|
||||
{
|
||||
public:
|
||||
Options();
|
||||
|
||||
public:
|
||||
/** \brief maximum number of fragments in a packet
|
||||
*/
|
||||
size_t nMaxFragments;
|
||||
size_t nMaxFragments = 400;
|
||||
};
|
||||
|
||||
explicit
|
||||
LpFragmenter(const Options& options = Options(), const LinkService* linkService = nullptr);
|
||||
LpFragmenter(const Options& options, const LinkService* linkService = nullptr);
|
||||
|
||||
/** \brief set options for fragmenter
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -25,18 +25,13 @@
|
||||
|
||||
#include "lp-reassembler.hpp"
|
||||
#include "link-service.hpp"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("LpReassembler");
|
||||
|
||||
LpReassembler::Options::Options()
|
||||
: nMaxFragments(400)
|
||||
, reassemblyTimeout(time::milliseconds(500))
|
||||
{
|
||||
}
|
||||
NFD_LOG_INIT(LpReassembler);
|
||||
|
||||
LpReassembler::LpReassembler(const LpReassembler::Options& options, const LinkService* linkService)
|
||||
: m_options(options)
|
||||
@@ -118,8 +113,7 @@ LpReassembler::receiveFragment(Transport::EndpointId remoteEndpoint, const lp::P
|
||||
}
|
||||
|
||||
// set drop timer
|
||||
pp.dropTimer = scheduler::schedule(m_options.reassemblyTimeout,
|
||||
bind(&LpReassembler::timeoutPartialPacket, this, key));
|
||||
pp.dropTimer = scheduler::schedule(m_options.reassemblyTimeout, [=] { timeoutPartialPacket(key); });
|
||||
|
||||
return FALSE_RETURN;
|
||||
}
|
||||
@@ -129,7 +123,7 @@ LpReassembler::doReassembly(const Key& key)
|
||||
{
|
||||
PartialPacket& pp = m_partialPackets[key];
|
||||
|
||||
size_t payloadSize = std::accumulate(pp.fragments.begin(), pp.fragments.end(), 0,
|
||||
size_t payloadSize = std::accumulate(pp.fragments.begin(), pp.fragments.end(), 0U,
|
||||
[&] (size_t sum, const lp::Packet& pkt) -> size_t {
|
||||
ndn::Buffer::const_iterator fragBegin, fragEnd;
|
||||
std::tie(fragBegin, fragEnd) = pkt.get<lp::FragmentField>();
|
||||
@@ -137,7 +131,7 @@ LpReassembler::doReassembly(const Key& key)
|
||||
});
|
||||
|
||||
ndn::Buffer fragBuffer(payloadSize);
|
||||
ndn::Buffer::iterator it = fragBuffer.begin();
|
||||
auto it = fragBuffer.begin();
|
||||
|
||||
for (const lp::Packet& frag : pp.fragments) {
|
||||
ndn::Buffer::const_iterator fragBegin, fragEnd;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -38,32 +38,28 @@ namespace face {
|
||||
class LinkService;
|
||||
|
||||
/** \brief reassembles fragmented network-layer packets
|
||||
* \sa http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
|
||||
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
|
||||
*/
|
||||
class LpReassembler : noncopyable
|
||||
{
|
||||
public:
|
||||
/** \brief Options that control the behavior of LpReassembler
|
||||
*/
|
||||
class Options
|
||||
struct Options
|
||||
{
|
||||
public:
|
||||
Options();
|
||||
|
||||
public:
|
||||
/** \brief maximum number of fragments in a packet
|
||||
*
|
||||
* LpPackets with FragCount over this limit are dropped.
|
||||
*/
|
||||
size_t nMaxFragments;
|
||||
size_t nMaxFragments = 400;
|
||||
|
||||
/** \brief timeout before a partially reassembled packet is dropped
|
||||
*/
|
||||
time::nanoseconds reassemblyTimeout;
|
||||
time::nanoseconds reassemblyTimeout = 500_ms;
|
||||
};
|
||||
|
||||
explicit
|
||||
LpReassembler(const Options& options = Options(), const LinkService* linkService = nullptr);
|
||||
LpReassembler(const Options& options, const LinkService* linkService = nullptr);
|
||||
|
||||
/** \brief set options for reassembler
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -39,13 +39,13 @@ LpReliability::LpReliability(const LpReliability::Options& options, GenericLinkS
|
||||
{
|
||||
BOOST_ASSERT(m_linkService != nullptr);
|
||||
|
||||
BOOST_ASSERT(m_options.idleAckTimerPeriod > time::nanoseconds::zero());
|
||||
BOOST_ASSERT(m_options.idleAckTimerPeriod > 0_ns);
|
||||
}
|
||||
|
||||
void
|
||||
LpReliability::setOptions(const Options& options)
|
||||
{
|
||||
BOOST_ASSERT(options.idleAckTimerPeriod > time::nanoseconds::zero());
|
||||
BOOST_ASSERT(options.idleAckTimerPeriod > 0_ns);
|
||||
|
||||
if (m_options.isEnabled && !options.isEnabled) {
|
||||
this->stopIdleAckTimer();
|
||||
@@ -81,8 +81,7 @@ LpReliability::handleOutgoing(std::vector<lp::Packet>& frags, lp::Packet&& pkt,
|
||||
std::forward_as_tuple(txSeq),
|
||||
std::forward_as_tuple(frag));
|
||||
unackedFragsIt->second.sendTime = sendTime;
|
||||
unackedFragsIt->second.rtoTimer =
|
||||
scheduler::schedule(m_rto.computeRto(), bind(&LpReliability::onLpPacketLost, this, unackedFragsIt));
|
||||
unackedFragsIt->second.rtoTimer = scheduler::schedule(m_rto.computeRto(), [=] { onLpPacketLost(txSeq); });
|
||||
unackedFragsIt->second.netPkt = netPkt;
|
||||
|
||||
if (m_unackedFrags.size() == 1) {
|
||||
@@ -127,9 +126,20 @@ LpReliability::processIncomingPacket(const lp::Packet& pkt)
|
||||
// packet. Potentially increment the start of the window.
|
||||
onLpPacketAcknowledged(fragIt);
|
||||
|
||||
// This set contains TxSequences that have been removed by onLpPacketLost below because they
|
||||
// were part of a network packet that was removed due to a fragment exceeding retx, as well as
|
||||
// any other TxSequences removed by onLpPacketLost. This prevents onLpPacketLost from being
|
||||
// called later for an invalid iterator.
|
||||
std::set<lp::Sequence> removedLpPackets;
|
||||
|
||||
// Resend or fail fragments considered lost. Potentially increment the start of the window.
|
||||
for (UnackedFrags::iterator txSeqIt : lostLpPackets) {
|
||||
this->onLpPacketLost(txSeqIt);
|
||||
for (lp::Sequence txSeq : lostLpPackets) {
|
||||
if (removedLpPackets.find(txSeq) == removedLpPackets.end()) {
|
||||
auto removedThisTxSeq = this->onLpPacketLost(txSeq);
|
||||
for (auto removedTxSeq : removedThisTxSeq) {
|
||||
removedLpPackets.insert(removedTxSeq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,11 +167,10 @@ LpReliability::piggyback(lp::Packet& pkt, ssize_t mtu)
|
||||
|
||||
while (!m_ackQueue.empty()) {
|
||||
lp::Sequence ackSeq = m_ackQueue.front();
|
||||
// Ack Size = Ack Type (3 octets) + Ack Length (1 octet) + Value (1, 2, 4, or 8 octets)
|
||||
ssize_t ackSize = tlv::sizeOfVarNumber(lp::tlv::Ack) +
|
||||
tlv::sizeOfVarNumber(
|
||||
tlv::sizeOfNonNegativeInteger(std::numeric_limits<lp::Sequence>::max())) +
|
||||
tlv::sizeOfNonNegativeInteger(ackSeq);
|
||||
// Ack size = Ack TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + uint64_t (8 octets)
|
||||
const ssize_t ackSize = tlv::sizeOfVarNumber(lp::tlv::Ack) +
|
||||
tlv::sizeOfVarNumber(sizeof(lp::Sequence)) +
|
||||
sizeof(lp::Sequence);
|
||||
|
||||
if (ackSize > remainingSpace) {
|
||||
break;
|
||||
@@ -206,10 +215,10 @@ LpReliability::stopIdleAckTimer()
|
||||
m_isIdleAckTimerRunning = false;
|
||||
}
|
||||
|
||||
std::vector<LpReliability::UnackedFrags::iterator>
|
||||
std::vector<lp::Sequence>
|
||||
LpReliability::findLostLpPackets(LpReliability::UnackedFrags::iterator ackIt)
|
||||
{
|
||||
std::vector<UnackedFrags::iterator> lostLpPackets;
|
||||
std::vector<lp::Sequence> lostLpPackets;
|
||||
|
||||
for (auto it = m_firstUnackedFrag; ; ++it) {
|
||||
if (it == m_unackedFrags.end()) {
|
||||
@@ -224,27 +233,30 @@ LpReliability::findLostLpPackets(LpReliability::UnackedFrags::iterator ackIt)
|
||||
unackedFrag.nGreaterSeqAcks++;
|
||||
|
||||
if (unackedFrag.nGreaterSeqAcks >= m_options.seqNumLossThreshold) {
|
||||
lostLpPackets.push_back(it);
|
||||
lostLpPackets.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
return lostLpPackets;
|
||||
}
|
||||
|
||||
void
|
||||
LpReliability::onLpPacketLost(UnackedFrags::iterator txSeqIt)
|
||||
std::vector<lp::Sequence>
|
||||
LpReliability::onLpPacketLost(lp::Sequence txSeq)
|
||||
{
|
||||
BOOST_ASSERT(m_unackedFrags.count(txSeqIt->first) > 0);
|
||||
BOOST_ASSERT(m_unackedFrags.count(txSeq) > 0);
|
||||
auto txSeqIt = m_unackedFrags.find(txSeq);
|
||||
|
||||
auto& txFrag = txSeqIt->second;
|
||||
txFrag.rtoTimer.cancel();
|
||||
auto netPkt = txFrag.netPkt;
|
||||
std::vector<lp::Sequence> removedThisTxSeq;
|
||||
|
||||
// Check if maximum number of retransmissions exceeded
|
||||
if (txFrag.retxCount >= m_options.maxRetx) {
|
||||
// Delete all LpPackets of NetPkt from m_unackedFrags (except this one)
|
||||
for (size_t i = 0; i < netPkt->unackedFrags.size(); i++) {
|
||||
if (netPkt->unackedFrags[i] != txSeqIt) {
|
||||
removedThisTxSeq.push_back(netPkt->unackedFrags[i]->first);
|
||||
deleteUnackedFrag(netPkt->unackedFrags[i]);
|
||||
}
|
||||
}
|
||||
@@ -260,6 +272,7 @@ LpReliability::onLpPacketLost(UnackedFrags::iterator txSeqIt)
|
||||
onDroppedInterest(Interest(frag));
|
||||
}
|
||||
|
||||
removedThisTxSeq.push_back(txSeqIt->first);
|
||||
deleteUnackedFrag(txSeqIt);
|
||||
}
|
||||
else {
|
||||
@@ -284,15 +297,17 @@ LpReliability::onLpPacketLost(UnackedFrags::iterator txSeqIt)
|
||||
BOOST_ASSERT(fragInNetPkt != netPkt->unackedFrags.end());
|
||||
*fragInNetPkt = newTxFragIt;
|
||||
|
||||
removedThisTxSeq.push_back(txSeqIt->first);
|
||||
deleteUnackedFrag(txSeqIt);
|
||||
|
||||
// Retransmit fragment
|
||||
m_linkService->sendLpPacket(lp::Packet(newTxFrag.pkt));
|
||||
|
||||
// Start RTO timer for this sequence
|
||||
newTxFrag.rtoTimer = scheduler::schedule(m_rto.computeRto(),
|
||||
bind(&LpReliability::onLpPacketLost, this, newTxFragIt));
|
||||
newTxFrag.rtoTimer = scheduler::schedule(m_rto.computeRto(), [=] { onLpPacketLost(newTxSeq); });
|
||||
}
|
||||
|
||||
return removedThisTxSeq;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
|
||||
/** \brief period between sending pending Acks in an IDLE packet
|
||||
*/
|
||||
time::nanoseconds idleAckTimerPeriod = time::milliseconds(5);
|
||||
time::nanoseconds idleAckTimerPeriod = 5_ms;
|
||||
|
||||
/** \brief a fragment is considered lost if this number of fragments with greater sequence
|
||||
* numbers are acknowledged
|
||||
@@ -135,15 +135,16 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
/** \brief find and mark as lost fragments where a configurable number of Acks
|
||||
* (\p m_options.seqNumLossThreshold) have been received for greater TxSequence numbers
|
||||
* \param ackIt iterator pointing to acknowledged fragment
|
||||
* \return vector containing iterators to fragments marked lost by this mechanism
|
||||
* \return vector containing TxSequences of fragments marked lost by this mechanism
|
||||
*/
|
||||
std::vector<UnackedFrags::iterator>
|
||||
std::vector<lp::Sequence>
|
||||
findLostLpPackets(UnackedFrags::iterator ackIt);
|
||||
|
||||
/** \brief resend (or give up on) a lost fragment
|
||||
* \return vector of the TxSequences of fragments removed due to a network packet being removed
|
||||
*/
|
||||
void
|
||||
onLpPacketLost(UnackedFrags::iterator txSeqIt);
|
||||
std::vector<lp::Sequence>
|
||||
onLpPacketLost(lp::Sequence txSeq);
|
||||
|
||||
/** \brief remove the fragment with the given sequence number from the map of unacknowledged
|
||||
* fragments, as well as its associated network packet (if any)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -46,7 +46,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("MulticastEthernetTransport");
|
||||
NFD_LOG_INIT(MulticastEthernetTransport);
|
||||
|
||||
MulticastEthernetTransport::MulticastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
|
||||
const ethernet::Address& mcastAddress,
|
||||
|
||||
@@ -40,8 +40,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(DatagramTransport, MulticastUdpTransport::protocol,
|
||||
Multicast, "MulticastUdpTransport");
|
||||
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>), MulticastUdpTransport);
|
||||
|
||||
MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& multicastGroup,
|
||||
protocol::socket&& recvSocket,
|
||||
@@ -88,10 +87,10 @@ MulticastUdpTransport::doSend(Transport::Packet&& packet)
|
||||
NFD_LOG_FACE_TRACE(__func__);
|
||||
|
||||
m_sendSocket.async_send_to(boost::asio::buffer(packet.packet), m_multicastGroup,
|
||||
bind(&MulticastUdpTransport::handleSend, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred,
|
||||
packet.packet));
|
||||
// packet.packet is copied into the lambda to retain the underlying Buffer
|
||||
[this, p = packet.packet] (auto&&... args) {
|
||||
this->handleSend(std::forward<decltype(args)>(args)...);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_MEMBER_DECL_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>));
|
||||
|
||||
// Explicit specialization of makeEndpointId for the UDP multicast case.
|
||||
// Note that this "shall be declared before the first use of the specialization
|
||||
// that would cause an implicit instantiation to take place, in every translation
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -43,14 +43,12 @@ PcapHelper::PcapHelper(const std::string& interfaceName)
|
||||
if (!m_pcap)
|
||||
BOOST_THROW_EXCEPTION(Error("pcap_create: " + std::string(errbuf)));
|
||||
|
||||
#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
|
||||
// Enable "immediate mode", effectively disabling any read buffering in the kernel.
|
||||
// This corresponds to the BIOCIMMEDIATE ioctl on BSD-like systems (including macOS)
|
||||
// where libpcap uses a BPF device. On Linux this forces libpcap not to use TPACKET_V3,
|
||||
// even if the kernel supports it, thus preventing bug #1511.
|
||||
if (pcap_set_immediate_mode(m_pcap, 1) < 0)
|
||||
BOOST_THROW_EXCEPTION(Error("pcap_set_immediate_mode failed"));
|
||||
#endif
|
||||
}
|
||||
|
||||
PcapHelper::~PcapHelper()
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
struct CreateFaceRequest
|
||||
{
|
||||
FaceUri remoteUri;
|
||||
ndn::optional<FaceUri> localUri;
|
||||
optional<FaceUri> localUri;
|
||||
FaceParams params;
|
||||
};
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ protected:
|
||||
protected:
|
||||
typename protocol::socket m_socket;
|
||||
|
||||
NFD_LOG_INCLASS_DECLARE();
|
||||
NFD_LOG_MEMBER_DECL();
|
||||
|
||||
private:
|
||||
uint8_t m_receiveBuffer[ndn::MAX_NDN_PACKET_SIZE];
|
||||
@@ -200,9 +200,7 @@ void
|
||||
StreamTransport<T>::sendFromQueue()
|
||||
{
|
||||
boost::asio::async_write(m_socket, boost::asio::buffer(m_sendQueue.front()),
|
||||
bind(&StreamTransport<T>::handleSend, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
[this] (auto&&... args) { this->handleSend(std::forward<decltype(args)>(args)...); });
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -232,9 +230,7 @@ StreamTransport<T>::startReceive()
|
||||
|
||||
m_socket.async_receive(boost::asio::buffer(m_receiveBuffer + m_receiveBufferSize,
|
||||
ndn::MAX_NDN_PACKET_SIZE - m_receiveBufferSize),
|
||||
bind(&StreamTransport<T>::handleReceive, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
[this] (auto&&... args) { this->handleReceive(std::forward<decltype(args)>(args)...); });
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
||||
+16
-22
@@ -24,22 +24,24 @@
|
||||
*/
|
||||
|
||||
#include "tcp-channel.hpp"
|
||||
#include "core/global-io.hpp"
|
||||
#include "generic-link-service.hpp"
|
||||
#include "tcp-transport.hpp"
|
||||
#include "core/global-io.hpp"
|
||||
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("TcpChannel");
|
||||
NFD_LOG_INIT(TcpChannel);
|
||||
|
||||
namespace ip = boost::asio::ip;
|
||||
|
||||
TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking)
|
||||
TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
|
||||
DetermineFaceScopeFromAddress determineFaceScope)
|
||||
: m_localEndpoint(localEndpoint)
|
||||
, m_acceptor(getGlobalIoService())
|
||||
, m_socket(getGlobalIoService())
|
||||
, m_wantCongestionMarking(wantCongestionMarking)
|
||||
, m_determineFaceScope(std::move(determineFaceScope))
|
||||
{
|
||||
setUri(FaceUri(m_localEndpoint));
|
||||
NFD_LOG_CHAN_INFO("Creating channel");
|
||||
@@ -81,15 +83,15 @@ TcpChannel::connect(const tcp::Endpoint& remoteEndpoint,
|
||||
return;
|
||||
}
|
||||
|
||||
auto clientSocket = make_shared<ip::tcp::socket>(ref(getGlobalIoService()));
|
||||
auto timeoutEvent = scheduler::schedule(timeout, bind(&TcpChannel::handleConnectTimeout, this,
|
||||
remoteEndpoint, clientSocket, onConnectFailed));
|
||||
auto clientSocket = make_shared<ip::tcp::socket>(std::ref(getGlobalIoService()));
|
||||
auto timeoutEvent = scheduler::schedule(timeout, [=] {
|
||||
handleConnectTimeout(remoteEndpoint, clientSocket, onConnectFailed);
|
||||
});
|
||||
|
||||
NFD_LOG_CHAN_TRACE("Connecting to " << remoteEndpoint);
|
||||
clientSocket->async_connect(remoteEndpoint,
|
||||
bind(&TcpChannel::handleConnect, this,
|
||||
boost::asio::placeholders::error, remoteEndpoint, clientSocket,
|
||||
params, timeoutEvent, onFaceCreated, onConnectFailed));
|
||||
clientSocket->async_connect(remoteEndpoint, [=] (const auto& e) {
|
||||
this->handleConnect(e, remoteEndpoint, clientSocket, params, timeoutEvent, onFaceCreated, onConnectFailed);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -122,7 +124,9 @@ TcpChannel::createFace(ip::tcp::socket&& socket,
|
||||
}
|
||||
|
||||
auto linkService = make_unique<GenericLinkService>(options);
|
||||
auto transport = make_unique<TcpTransport>(std::move(socket), params.persistency);
|
||||
auto faceScope = m_determineFaceScope(socket.local_endpoint().address(),
|
||||
socket.remote_endpoint().address());
|
||||
auto transport = make_unique<TcpTransport>(std::move(socket), params.persistency, faceScope);
|
||||
face = make_shared<Face>(std::move(linkService), std::move(transport));
|
||||
|
||||
m_channelFaces[remoteEndpoint] = face;
|
||||
@@ -147,9 +151,7 @@ void
|
||||
TcpChannel::accept(const FaceCreatedCallback& onFaceCreated,
|
||||
const FaceCreationFailedCallback& onAcceptFailed)
|
||||
{
|
||||
m_acceptor.async_accept(m_socket, bind(&TcpChannel::handleAccept, this,
|
||||
boost::asio::placeholders::error,
|
||||
onFaceCreated, onAcceptFailed));
|
||||
m_acceptor.async_accept(m_socket, [=] (const auto& e) { this->handleAccept(e, onFaceCreated, onAcceptFailed); });
|
||||
}
|
||||
|
||||
void
|
||||
@@ -187,15 +189,7 @@ TcpChannel::handleConnect(const boost::system::error_code& error,
|
||||
{
|
||||
scheduler::cancel(connectTimeoutEvent);
|
||||
|
||||
#if (BOOST_VERSION == 105400)
|
||||
// To handle regression in Boost 1.54
|
||||
// https://svn.boost.org/trac/boost/ticket/8795
|
||||
boost::system::error_code anotherErrorCode;
|
||||
socket->remote_endpoint(anotherErrorCode);
|
||||
if (error || anotherErrorCode) {
|
||||
#else
|
||||
if (error) {
|
||||
#endif
|
||||
if (error != boost::asio::error::operation_aborted) {
|
||||
NFD_LOG_CHAN_DEBUG("Connection to " << remoteEndpoint << " failed: " << error.message());
|
||||
if (onConnectFailed)
|
||||
|
||||
@@ -37,6 +37,9 @@ typedef boost::asio::ip::tcp::endpoint Endpoint;
|
||||
|
||||
namespace face {
|
||||
|
||||
using DetermineFaceScopeFromAddress = std::function<ndn::nfd::FaceScope(const boost::asio::ip::address& local,
|
||||
const boost::asio::ip::address& remote)>;
|
||||
|
||||
/**
|
||||
* \brief Class implementing TCP-based channel to create faces
|
||||
*
|
||||
@@ -53,7 +56,8 @@ public:
|
||||
* To enable creation faces upon incoming connections,
|
||||
* one needs to explicitly call TcpChannel::listen method.
|
||||
*/
|
||||
TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking);
|
||||
TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
|
||||
DetermineFaceScopeFromAddress determineFaceScope);
|
||||
|
||||
bool
|
||||
isListening() const override
|
||||
@@ -126,6 +130,7 @@ private:
|
||||
boost::asio::ip::tcp::socket m_socket;
|
||||
std::map<tcp::Endpoint, shared_ptr<Face>> m_channelFaces;
|
||||
bool m_wantCongestionMarking;
|
||||
DetermineFaceScopeFromAddress m_determineFaceScope;
|
||||
};
|
||||
|
||||
} // namespace face
|
||||
|
||||
@@ -25,14 +25,12 @@
|
||||
|
||||
#include "tcp-factory.hpp"
|
||||
|
||||
#include <ndn-cxx/net/address-converter.hpp>
|
||||
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
namespace ip = boost::asio::ip;
|
||||
|
||||
NFD_LOG_INIT("TcpFactory");
|
||||
NFD_LOG_INIT(TcpFactory);
|
||||
NFD_REGISTER_PROTOCOL_FACTORY(TcpFactory);
|
||||
|
||||
const std::string&
|
||||
@@ -72,6 +70,8 @@ TcpFactory::processConfig(OptionalConfigSection configSection,
|
||||
uint16_t port = 6363;
|
||||
bool enableV4 = true;
|
||||
bool enableV6 = true;
|
||||
IpAddressPredicate local;
|
||||
bool isLocalConfigured = false;
|
||||
|
||||
for (const auto& pair : *configSection) {
|
||||
const std::string& key = pair.first;
|
||||
@@ -88,10 +88,28 @@ TcpFactory::processConfig(OptionalConfigSection configSection,
|
||||
else if (key == "enable_v6") {
|
||||
enableV6 = ConfigFile::parseYesNo(pair, "face_system.tcp");
|
||||
}
|
||||
else if (key == "local") {
|
||||
isLocalConfigured = true;
|
||||
for (const auto& localPair : pair.second) {
|
||||
const std::string& localKey = localPair.first;
|
||||
if (localKey == "whitelist") {
|
||||
local.parseWhitelist(localPair.second);
|
||||
}
|
||||
else if (localKey == "blacklist") {
|
||||
local.parseBlacklist(localPair.second);
|
||||
}
|
||||
else {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option face_system.tcp.local." + localKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option face_system.tcp." + key));
|
||||
}
|
||||
}
|
||||
if (!isLocalConfigured) {
|
||||
local.assign({{"subnet", "127.0.0.0/8"}, {"subnet", "::1/128"}}, {});
|
||||
}
|
||||
|
||||
if (!enableV4 && !enableV6) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error(
|
||||
@@ -125,6 +143,8 @@ TcpFactory::processConfig(OptionalConfigSection configSection,
|
||||
else if (providedSchemes.count("tcp6") > 0) {
|
||||
NFD_LOG_WARN("Cannot close tcp6 channel after its creation");
|
||||
}
|
||||
|
||||
m_local = std::move(local);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +167,7 @@ TcpFactory::createFace(const CreateFaceRequest& req,
|
||||
return;
|
||||
}
|
||||
|
||||
tcp::Endpoint endpoint(ndn::ip::addressFromString(req.remoteUri.getHost()),
|
||||
tcp::Endpoint endpoint(ip::address::from_string(req.remoteUri.getHost()),
|
||||
boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
|
||||
|
||||
// a canonical tcp4/tcp6 FaceUri cannot have a multicast address
|
||||
@@ -159,6 +179,12 @@ TcpFactory::createFace(const CreateFaceRequest& req,
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.params.mtu) {
|
||||
NFD_LOG_TRACE("createFace cannot create a TCP face with an overridden MTU");
|
||||
onFailure(406, "TCP faces do not support MTU overrides");
|
||||
return;
|
||||
}
|
||||
|
||||
// very simple logic for now
|
||||
for (const auto& i : m_channels) {
|
||||
if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
|
||||
@@ -179,7 +205,8 @@ TcpFactory::createChannel(const tcp::Endpoint& endpoint)
|
||||
if (it != m_channels.end())
|
||||
return it->second;
|
||||
|
||||
auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking);
|
||||
auto channel = make_shared<TcpChannel>(endpoint, m_wantCongestionMarking,
|
||||
bind(&TcpFactory::determineFaceScopeFromAddresses, this, _1, _2));
|
||||
m_channels[endpoint] = channel;
|
||||
return channel;
|
||||
}
|
||||
@@ -190,5 +217,15 @@ TcpFactory::getChannels() const
|
||||
return getChannelsFromMap(m_channels);
|
||||
}
|
||||
|
||||
ndn::nfd::FaceScope
|
||||
TcpFactory::determineFaceScopeFromAddresses(const boost::asio::ip::address& localAddress,
|
||||
const boost::asio::ip::address& remoteAddress) const
|
||||
{
|
||||
if (m_local(localAddress) && m_local(remoteAddress)) {
|
||||
return ndn::nfd::FACE_SCOPE_LOCAL;
|
||||
}
|
||||
return ndn::nfd::FACE_SCOPE_NON_LOCAL;
|
||||
}
|
||||
|
||||
} // namespace face
|
||||
} // namespace nfd
|
||||
@@ -71,9 +71,17 @@ public:
|
||||
std::vector<shared_ptr<const Channel>>
|
||||
getChannels() const override;
|
||||
|
||||
private:
|
||||
ndn::nfd::FaceScope
|
||||
determineFaceScopeFromAddresses(const boost::asio::ip::address& local,
|
||||
const boost::asio::ip::address& remote) const;
|
||||
|
||||
private:
|
||||
bool m_wantCongestionMarking = false;
|
||||
std::map<tcp::Endpoint, shared_ptr<TcpChannel>> m_channels;
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
IpAddressPredicate m_local;
|
||||
};
|
||||
|
||||
} // namespace face
|
||||
|
||||
@@ -33,26 +33,20 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamTransport, TcpTransport::protocol, "TcpTransport");
|
||||
NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>, TcpTransport);
|
||||
|
||||
time::milliseconds TcpTransport::s_initialReconnectWait = time::seconds(1);
|
||||
time::milliseconds TcpTransport::s_maxReconnectWait = time::minutes(5);
|
||||
time::milliseconds TcpTransport::s_initialReconnectWait = 1_s;
|
||||
time::milliseconds TcpTransport::s_maxReconnectWait = 5_min;
|
||||
float TcpTransport::s_reconnectWaitMultiplier = 2.0f;
|
||||
|
||||
TcpTransport::TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency)
|
||||
TcpTransport::TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency, ndn::nfd::FaceScope faceScope)
|
||||
: StreamTransport(std::move(socket))
|
||||
, m_remoteEndpoint(m_socket.remote_endpoint())
|
||||
, m_nextReconnectWait(s_initialReconnectWait)
|
||||
{
|
||||
this->setLocalUri(FaceUri(m_socket.local_endpoint()));
|
||||
this->setRemoteUri(FaceUri(m_socket.remote_endpoint()));
|
||||
|
||||
if (m_socket.local_endpoint().address().is_loopback() &&
|
||||
m_socket.remote_endpoint().address().is_loopback())
|
||||
this->setScope(ndn::nfd::FACE_SCOPE_LOCAL);
|
||||
else
|
||||
this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
|
||||
|
||||
this->setScope(faceScope);
|
||||
this->setPersistency(persistency);
|
||||
this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
|
||||
this->setMtu(MTU_UNLIMITED);
|
||||
@@ -140,10 +134,8 @@ TcpTransport::reconnect()
|
||||
this->resetReceiveBuffer();
|
||||
this->resetSendQueue();
|
||||
|
||||
m_reconnectEvent = scheduler::schedule(m_nextReconnectWait,
|
||||
[this] { handleReconnectTimeout(); });
|
||||
m_socket.async_connect(m_remoteEndpoint,
|
||||
[this] (const boost::system::error_code& error) { handleReconnect(error); });
|
||||
m_reconnectEvent = scheduler::schedule(m_nextReconnectWait, [this] { this->handleReconnectTimeout(); });
|
||||
m_socket.async_connect(m_remoteEndpoint, [this] (const auto& e) { this->handleReconnect(e); });
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_MEMBER_DECL_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>);
|
||||
|
||||
/**
|
||||
* \brief A Transport that communicates on a connected TCP socket
|
||||
*
|
||||
@@ -42,7 +44,7 @@ namespace face {
|
||||
class TcpTransport FINAL_UNLESS_WITH_TESTS : public StreamTransport<boost::asio::ip::tcp>
|
||||
{
|
||||
public:
|
||||
TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency);
|
||||
TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency, ndn::nfd::FaceScope faceScope);
|
||||
|
||||
ssize_t
|
||||
getSendQueueLength() final;
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("Transport");
|
||||
NFD_LOG_INIT(Transport);
|
||||
|
||||
const ssize_t Transport::MIN_MTU;
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, TransportState state)
|
||||
@@ -126,12 +128,6 @@ Transport::receive(Packet&& packet)
|
||||
m_service->receivePacket(std::move(packet));
|
||||
}
|
||||
|
||||
ssize_t
|
||||
Transport::getSendQueueLength()
|
||||
{
|
||||
return QUEUE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
bool
|
||||
Transport::canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const
|
||||
{
|
||||
|
||||
@@ -202,13 +202,6 @@ public: // upper interface
|
||||
void
|
||||
send(Packet&& packet);
|
||||
|
||||
protected: // upper interface to be invoked by subclass
|
||||
/** \brief receive a link-layer packet
|
||||
* \warning undefined behavior if packet size exceeds MTU limit
|
||||
*/
|
||||
void
|
||||
receive(Packet&& packet);
|
||||
|
||||
public: // static properties
|
||||
/** \return a FaceUri representing local endpoint
|
||||
*/
|
||||
@@ -291,7 +284,17 @@ public: // dynamic properties
|
||||
* \retval QUEUE_ERROR transport was unable to retrieve the queue length
|
||||
*/
|
||||
virtual ssize_t
|
||||
getSendQueueLength();
|
||||
getSendQueueLength()
|
||||
{
|
||||
return QUEUE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
protected: // upper interface to be invoked by subclass
|
||||
/** \brief receive a link-layer packet
|
||||
* \warning undefined behavior if packet size exceeds MTU limit
|
||||
*/
|
||||
void
|
||||
receive(Packet&& packet);
|
||||
|
||||
protected: // properties to be set by subclass
|
||||
void
|
||||
@@ -363,6 +366,13 @@ private: // to be overridden by subclass
|
||||
virtual void
|
||||
doSend(Packet&& packet) = 0;
|
||||
|
||||
public:
|
||||
/** \brief minimum MTU that may be set on a transport
|
||||
*
|
||||
* This is done to ensure the NDNLPv2 fragmentation feature functions properly.
|
||||
*/
|
||||
static constexpr ssize_t MIN_MTU = 64;
|
||||
|
||||
private:
|
||||
Face* m_face;
|
||||
LinkService* m_service;
|
||||
@@ -372,7 +382,7 @@ private:
|
||||
ndn::nfd::FacePersistency m_persistency;
|
||||
ndn::nfd::LinkType m_linkType;
|
||||
ssize_t m_mtu;
|
||||
size_t m_sendQueueCapacity;
|
||||
ssize_t m_sendQueueCapacity;
|
||||
TransportState m_state;
|
||||
time::steady_clock::TimePoint m_expirationTime;
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("UdpChannel");
|
||||
NFD_LOG_INIT(UdpChannel);
|
||||
|
||||
namespace ip = boost::asio::ip;
|
||||
|
||||
@@ -60,7 +60,7 @@ UdpChannel::connect(const udp::Endpoint& remoteEndpoint,
|
||||
catch (const boost::system::system_error& e) {
|
||||
NFD_LOG_CHAN_DEBUG("Face creation for " << remoteEndpoint << " failed: " << e.what());
|
||||
if (onConnectFailed)
|
||||
onConnectFailed(504, std::string("Face creation failed: ") + e.what());
|
||||
onConnectFailed(504, "Face creation failed: "s + e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -94,10 +94,9 @@ UdpChannel::waitForNewPeer(const FaceCreatedCallback& onFaceCreated,
|
||||
const FaceCreationFailedCallback& onReceiveFailed)
|
||||
{
|
||||
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint,
|
||||
bind(&UdpChannel::handleNewPeer, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred,
|
||||
onFaceCreated, onReceiveFailed));
|
||||
[=] (auto&&... args) {
|
||||
this->handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -127,7 +126,7 @@ UdpChannel::handleNewPeer(const boost::system::error_code& error,
|
||||
catch (const boost::system::system_error& e) {
|
||||
NFD_LOG_CHAN_DEBUG("Face creation for " << m_remoteEndpoint << " failed: " << e.what());
|
||||
if (onReceiveFailed)
|
||||
onReceiveFailed(504, std::string("Face creation failed: ") + e.what());
|
||||
onReceiveFailed(504, "Face creation failed: "s + e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,6 +160,8 @@ UdpChannel::createFace(const udp::Endpoint& remoteEndpoint,
|
||||
socket.connect(remoteEndpoint);
|
||||
|
||||
GenericLinkService::Options options;
|
||||
options.allowFragmentation = true;
|
||||
options.allowReassembly = true;
|
||||
options.reliabilityOptions.isEnabled = params.wantLpReliability;
|
||||
|
||||
if (boost::logic::indeterminate(params.wantCongestionMarking)) {
|
||||
@@ -179,7 +180,8 @@ UdpChannel::createFace(const udp::Endpoint& remoteEndpoint,
|
||||
}
|
||||
|
||||
auto linkService = make_unique<GenericLinkService>(options);
|
||||
auto transport = make_unique<UnicastUdpTransport>(std::move(socket), params.persistency, m_idleFaceTimeout);
|
||||
auto transport = make_unique<UnicastUdpTransport>(std::move(socket), params.persistency,
|
||||
m_idleFaceTimeout, params.mtu);
|
||||
auto face = make_shared<Face>(std::move(linkService), std::move(transport));
|
||||
|
||||
m_channelFaces[remoteEndpoint] = face;
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "multicast-udp-transport.hpp"
|
||||
#include "core/global-io.hpp"
|
||||
|
||||
#include <ndn-cxx/net/address-converter.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
|
||||
@@ -38,7 +37,7 @@ namespace face {
|
||||
namespace ip = boost::asio::ip;
|
||||
namespace net = ndn::net;
|
||||
|
||||
NFD_LOG_INIT("UdpFactory");
|
||||
NFD_LOG_INIT(UdpFactory);
|
||||
NFD_REGISTER_PROTOCOL_FACTORY(UdpFactory);
|
||||
|
||||
const std::string&
|
||||
@@ -51,7 +50,9 @@ UdpFactory::getId()
|
||||
UdpFactory::UdpFactory(const CtorParams& params)
|
||||
: ProtocolFactory(params)
|
||||
{
|
||||
m_netifAddConn = netmon->onInterfaceAdded.connect(bind(&UdpFactory::applyMcastConfigToNetif, this, _1));
|
||||
m_netifAddConn = netmon->onInterfaceAdded.connect([this] (const auto& netif) {
|
||||
this->applyMcastConfigToNetif(netif);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -137,7 +138,7 @@ UdpFactory::processConfig(OptionalConfigSection configSection,
|
||||
else if (key == "mcast_group_v6") {
|
||||
const std::string& valueStr = value.get_value<std::string>();
|
||||
boost::system::error_code ec;
|
||||
mcastConfig.groupV6.address(ndn::ip::addressV6FromString(valueStr, ec));
|
||||
mcastConfig.groupV6.address(ip::address_v6::from_string(valueStr, ec));
|
||||
if (ec) {
|
||||
BOOST_THROW_EXCEPTION(ConfigFile::Error("face_system.udp.mcast_group_v6: '" +
|
||||
valueStr + "' cannot be parsed as an IPv6 address"));
|
||||
@@ -253,7 +254,7 @@ UdpFactory::createFace(const CreateFaceRequest& req,
|
||||
return;
|
||||
}
|
||||
|
||||
udp::Endpoint endpoint(ndn::ip::addressFromString(req.remoteUri.getHost()),
|
||||
udp::Endpoint endpoint(ip::address::from_string(req.remoteUri.getHost()),
|
||||
boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
|
||||
|
||||
if (endpoint.address().is_multicast()) {
|
||||
@@ -269,6 +270,13 @@ UdpFactory::createFace(const CreateFaceRequest& req,
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.params.mtu && *req.params.mtu < Transport::MIN_MTU) {
|
||||
// The specified MTU must be greater than the minimum possible
|
||||
NFD_LOG_TRACE("createFace cannot create a face with MTU less than " << Transport::MIN_MTU);
|
||||
onFailure(406, "MTU cannot be less than " + to_string(Transport::MIN_MTU));
|
||||
return;
|
||||
}
|
||||
|
||||
// very simple logic for now
|
||||
for (const auto& i : m_channels) {
|
||||
if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
|
||||
@@ -363,7 +371,7 @@ UdpFactory::createMulticastFace(const shared_ptr<const net::NetworkInterface>& n
|
||||
return face;
|
||||
}
|
||||
|
||||
static ndn::optional<ip::address>
|
||||
static optional<ip::address>
|
||||
pickAddress(const net::NetworkInterface& netif, net::AddressFamily af)
|
||||
{
|
||||
for (const auto& na : netif.getNetworkAddresses()) {
|
||||
@@ -372,7 +380,7 @@ pickAddress(const net::NetworkInterface& netif, net::AddressFamily af)
|
||||
return na.getIp();
|
||||
}
|
||||
}
|
||||
return ndn::nullopt;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
std::vector<shared_ptr<Face>>
|
||||
@@ -415,7 +423,7 @@ UdpFactory::applyMcastConfigToNetif(const shared_ptr<const net::NetworkInterface
|
||||
NFD_LOG_DEBUG("Not creating multicast faces on " << netif->getName() << ": no viable IP address");
|
||||
// keep an eye on new addresses
|
||||
m_netifConns[netif->getIndex()].addrAddConn =
|
||||
netif->onAddressAdded.connect(bind(&UdpFactory::applyMcastConfigToNetif, this, netif));
|
||||
netif->onAddressAdded.connect([=] (auto...) { this->applyMcastConfigToNetif(netif); });
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -30,12 +30,13 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("UnicastEthernetTransport");
|
||||
NFD_LOG_INIT(UnicastEthernetTransport);
|
||||
|
||||
UnicastEthernetTransport::UnicastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
|
||||
const ethernet::Address& remoteEndpoint,
|
||||
ndn::nfd::FacePersistency persistency,
|
||||
time::nanoseconds idleTimeout)
|
||||
time::nanoseconds idleTimeout,
|
||||
optional<ssize_t> overrideMtu)
|
||||
: EthernetTransport(localEndpoint, remoteEndpoint)
|
||||
, m_idleTimeout(idleTimeout)
|
||||
{
|
||||
@@ -44,7 +45,13 @@ UnicastEthernetTransport::UnicastEthernetTransport(const ndn::net::NetworkInterf
|
||||
this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
|
||||
this->setPersistency(persistency);
|
||||
this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
|
||||
this->setMtu(localEndpoint.getMtu());
|
||||
|
||||
if (overrideMtu) {
|
||||
this->setMtu(std::min<ssize_t>(localEndpoint.getMtu(), *overrideMtu));
|
||||
}
|
||||
else {
|
||||
this->setMtu(localEndpoint.getMtu());
|
||||
}
|
||||
|
||||
NFD_LOG_FACE_INFO("Creating transport");
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -44,7 +44,8 @@ public:
|
||||
UnicastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
|
||||
const ethernet::Address& remoteEndpoint,
|
||||
ndn::nfd::FacePersistency persistency,
|
||||
time::nanoseconds idleTimeout);
|
||||
time::nanoseconds idleTimeout,
|
||||
optional<ssize_t> overrideMtu = {});
|
||||
|
||||
protected:
|
||||
bool
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -36,12 +36,12 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramTransport, UnicastUdpTransport::protocol,
|
||||
"UnicastUdpTransport");
|
||||
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Unicast>), UnicastUdpTransport);
|
||||
|
||||
UnicastUdpTransport::UnicastUdpTransport(protocol::socket&& socket,
|
||||
ndn::nfd::FacePersistency persistency,
|
||||
time::nanoseconds idleTimeout)
|
||||
time::nanoseconds idleTimeout,
|
||||
optional<ssize_t> overrideMtu)
|
||||
: DatagramTransport(std::move(socket))
|
||||
, m_idleTimeout(idleTimeout)
|
||||
{
|
||||
@@ -50,7 +50,14 @@ UnicastUdpTransport::UnicastUdpTransport(protocol::socket&& socket,
|
||||
this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
|
||||
this->setPersistency(persistency);
|
||||
this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT);
|
||||
this->setMtu(udp::computeMtu(m_socket.local_endpoint()));
|
||||
|
||||
if (overrideMtu) {
|
||||
this->setMtu(std::min(udp::computeMtu(m_socket.local_endpoint()), *overrideMtu));
|
||||
}
|
||||
else {
|
||||
this->setMtu(udp::computeMtu(m_socket.local_endpoint()));
|
||||
}
|
||||
BOOST_ASSERT(this->getMtu() >= MIN_MTU);
|
||||
|
||||
NFD_LOG_FACE_INFO("Creating transport");
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -32,6 +32,8 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_MEMBER_DECL_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Unicast>));
|
||||
|
||||
/**
|
||||
* \brief A Transport that communicates on a unicast UDP socket
|
||||
*/
|
||||
@@ -40,7 +42,8 @@ class UnicastUdpTransport final : public DatagramTransport<boost::asio::ip::udp,
|
||||
public:
|
||||
UnicastUdpTransport(protocol::socket&& socket,
|
||||
ndn::nfd::FacePersistency persistency,
|
||||
time::nanoseconds idleTimeout);
|
||||
time::nanoseconds idleTimeout,
|
||||
optional<ssize_t> overrideMtu = {});
|
||||
|
||||
protected:
|
||||
bool
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("UnixStreamChannel");
|
||||
NFD_LOG_INIT(UnixStreamChannel);
|
||||
|
||||
UnixStreamChannel::UnixStreamChannel(const unix_stream::Endpoint& endpoint,
|
||||
bool wantCongestionMarking)
|
||||
@@ -101,7 +101,7 @@ UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
|
||||
m_acceptor.bind(m_endpoint);
|
||||
m_acceptor.listen(backlog);
|
||||
|
||||
if (::chmod(m_endpoint.path().c_str(), 0666) < 0) {
|
||||
if (::chmod(m_endpoint.path().data(), 0666) < 0) {
|
||||
BOOST_THROW_EXCEPTION(Error("chmod(" + m_endpoint.path() + ") failed: " + std::strerror(errno)));
|
||||
}
|
||||
|
||||
@@ -113,9 +113,7 @@ void
|
||||
UnixStreamChannel::accept(const FaceCreatedCallback& onFaceCreated,
|
||||
const FaceCreationFailedCallback& onAcceptFailed)
|
||||
{
|
||||
m_acceptor.async_accept(m_socket, bind(&UnixStreamChannel::handleAccept, this,
|
||||
boost::asio::placeholders::error,
|
||||
onFaceCreated, onAcceptFailed));
|
||||
m_acceptor.async_accept(m_socket, [=] (const auto& e) { this->handleAccept(e, onFaceCreated, onAcceptFailed); });
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("UnixStreamFactory");
|
||||
NFD_LOG_INIT(UnixStreamFactory);
|
||||
NFD_REGISTER_PROTOCOL_FACTORY(UnixStreamFactory);
|
||||
|
||||
const std::string&
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -28,8 +28,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamTransport, UnixStreamTransport::protocol,
|
||||
"UnixStreamTransport");
|
||||
NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<boost::asio::local::stream_protocol>, UnixStreamTransport);
|
||||
|
||||
UnixStreamTransport::UnixStreamTransport(protocol::socket&& socket)
|
||||
: StreamTransport(std::move(socket))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -35,6 +35,8 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_MEMBER_DECL_SPECIALIZED(StreamTransport<boost::asio::local::stream_protocol>);
|
||||
|
||||
/**
|
||||
* \brief A Transport that communicates on a stream-oriented Unix domain socket
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("WebSocketChannel");
|
||||
NFD_LOG_INIT(WebSocketChannel);
|
||||
|
||||
WebSocketChannel::WebSocketChannel(const websocket::Endpoint& localEndpoint)
|
||||
: m_localEndpoint(localEndpoint)
|
||||
@@ -117,7 +117,7 @@ WebSocketChannel::handleOpen(websocketpp::connection_hdl hdl)
|
||||
NFD_LOG_CHAN_TRACE("Incoming connection from " << m_server.get_con_from_hdl(hdl)->get_remote_endpoint());
|
||||
|
||||
auto linkService = make_unique<GenericLinkService>();
|
||||
auto transport = make_unique<WebSocketTransport>(hdl, ref(m_server), m_pingInterval);
|
||||
auto transport = make_unique<WebSocketTransport>(hdl, std::ref(m_server), m_pingInterval);
|
||||
auto face = make_shared<Face>(std::move(linkService), std::move(transport));
|
||||
|
||||
BOOST_ASSERT(m_channelFaces.count(hdl) == 0);
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace face {
|
||||
|
||||
namespace ip = boost::asio::ip;
|
||||
|
||||
NFD_LOG_INIT("WebSocketFactory");
|
||||
NFD_LOG_INIT(WebSocketFactory);
|
||||
NFD_REGISTER_PROTOCOL_FACTORY(WebSocketFactory);
|
||||
|
||||
const std::string&
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -28,7 +28,7 @@
|
||||
namespace nfd {
|
||||
namespace face {
|
||||
|
||||
NFD_LOG_INIT("WebSocketTransport");
|
||||
NFD_LOG_INIT(WebSocketTransport);
|
||||
|
||||
static bool
|
||||
isLoopback(const boost::asio::ip::address& addr)
|
||||
@@ -97,7 +97,7 @@ WebSocketTransport::receiveMessage(const std::string& msg)
|
||||
|
||||
bool isOk = false;
|
||||
Block element;
|
||||
std::tie(isOk, element) = Block::fromBuffer(reinterpret_cast<const uint8_t*>(msg.c_str()), msg.size());
|
||||
std::tie(isOk, element) = Block::fromBuffer(reinterpret_cast<const uint8_t*>(msg.data()), msg.size());
|
||||
if (!isOk) {
|
||||
NFD_LOG_FACE_WARN("Failed to parse message payload");
|
||||
return;
|
||||
@@ -109,7 +109,7 @@ WebSocketTransport::receiveMessage(const std::string& msg)
|
||||
void
|
||||
WebSocketTransport::schedulePing()
|
||||
{
|
||||
m_pingEventId = scheduler::schedule(m_pingInterval, bind(&WebSocketTransport::sendPing, this));
|
||||
m_pingEventId = scheduler::schedule(m_pingInterval, [this] { sendPing(); });
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -30,13 +30,12 @@
|
||||
namespace nfd {
|
||||
namespace fw {
|
||||
|
||||
NFD_LOG_INIT("AccessStrategy");
|
||||
NFD_LOG_INIT(AccessStrategy);
|
||||
NFD_REGISTER_STRATEGY(AccessStrategy);
|
||||
|
||||
AccessStrategy::AccessStrategy(Forwarder& forwarder, const Name& name)
|
||||
: Strategy(forwarder)
|
||||
, m_removeFaceInfoConn(this->beforeRemoveFace.connect(
|
||||
bind(&AccessStrategy::removeFaceInfo, this, _1)))
|
||||
, m_removeFaceInfoConn(beforeRemoveFace.connect([this] (const Face& face) { removeFaceInfo(face); }))
|
||||
{
|
||||
ParsedInstanceName parsed = parseInstanceName(name);
|
||||
if (!parsed.parameters.empty()) {
|
||||
@@ -177,14 +176,13 @@ AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, FaceId inFaceId, F
|
||||
return;
|
||||
}
|
||||
|
||||
pit::InRecordCollection::iterator inRecord = pitEntry->getInRecord(*inFace);
|
||||
auto inRecord = pitEntry->getInRecord(*inFace);
|
||||
BOOST_ASSERT(inRecord != pitEntry->in_end());
|
||||
// in-record is erased only if Interest is satisfied, and RTO timer should have been cancelled
|
||||
// note: if this strategy is extended to send Nacks, that would also erase in-record,
|
||||
// and RTO timer should be cancelled in that case as well
|
||||
|
||||
const Interest& interest = inRecord->getInterest();
|
||||
|
||||
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
|
||||
|
||||
NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId <<
|
||||
@@ -227,14 +225,14 @@ AccessStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
|
||||
return;
|
||||
}
|
||||
|
||||
pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(inFace);
|
||||
auto outRecord = pitEntry->getOutRecord(inFace);
|
||||
if (outRecord == pitEntry->out_end()) { // no out-record
|
||||
NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << inFace.getId() <<
|
||||
" no-out-record");
|
||||
return;
|
||||
}
|
||||
|
||||
time::steady_clock::Duration rtt = time::steady_clock::now() - outRecord->getLastRenewed();
|
||||
auto rtt = time::steady_clock::now() - outRecord->getLastRenewed();
|
||||
NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << inFace.getId() <<
|
||||
" rtt=" << time::duration_cast<time::microseconds>(rtt).count());
|
||||
this->updateMeasurements(inFace, data, time::duration_cast<RttEstimator::Duration>(rtt));
|
||||
@@ -260,7 +258,7 @@ AccessStrategy::updateMeasurements(const Face& inFace, const Data& data,
|
||||
|
||||
AccessStrategy::MtInfo::MtInfo()
|
||||
: lastNexthop(face::INVALID_FACEID)
|
||||
, rtt(1, time::milliseconds(1), 0.1)
|
||||
, rtt(1, 1_ms, 0.1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -292,14 +290,13 @@ AccessStrategy::addPrefixMeasurements(const Data& data)
|
||||
BOOST_ASSERT(me != nullptr);
|
||||
}
|
||||
|
||||
static const time::nanoseconds ME_LIFETIME = time::seconds(8);
|
||||
this->getMeasurements().extendLifetime(*me, ME_LIFETIME);
|
||||
this->getMeasurements().extendLifetime(*me, 8_s);
|
||||
|
||||
return me->insertStrategyInfo<MtInfo>().first;
|
||||
}
|
||||
|
||||
AccessStrategy::FaceInfo::FaceInfo()
|
||||
: rtt(1, time::milliseconds(1), 0.1)
|
||||
: rtt(1, 1_ms, 0.1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -27,10 +27,8 @@
|
||||
#define NFD_DAEMON_FW_ACCESS_STRATEGY_HPP
|
||||
|
||||
#include "strategy.hpp"
|
||||
#include "core/rtt-estimator.hpp"
|
||||
#include "retx-suppression-fixed.hpp"
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include "core/rtt-estimator.hpp"
|
||||
|
||||
namespace nfd {
|
||||
namespace fw {
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace nfd {
|
||||
namespace fw {
|
||||
namespace asf {
|
||||
|
||||
NFD_LOG_INIT("AsfMeasurements");
|
||||
NFD_LOG_INIT(AsfMeasurements);
|
||||
|
||||
const RttStats::Rtt RttStats::RTT_TIMEOUT(-1.0);
|
||||
const RttStats::Rtt RttStats::RTT_NO_MEASUREMENT(0.0);
|
||||
@@ -168,7 +168,7 @@ NamespaceInfo::getOrCreateFaceInfo(const fib::Entry& fibEntry, FaceId faceId)
|
||||
FaceInfo* info = nullptr;
|
||||
|
||||
if (it == m_fit.end()) {
|
||||
const auto& pair = m_fit.insert(std::make_pair(faceId, FaceInfo()));
|
||||
const auto& pair = m_fit.emplace(faceId, FaceInfo());
|
||||
info = &pair.first->second;
|
||||
|
||||
extendFaceInfoLifetime(*info, faceId);
|
||||
@@ -193,9 +193,7 @@ NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, FaceId faceId)
|
||||
scheduler::cancel(info.getMeasurementExpirationEventId());
|
||||
|
||||
// Refresh measurement
|
||||
scheduler::EventId id = scheduler::schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
|
||||
bind(&NamespaceInfo::expireFaceInfo, this, faceId));
|
||||
|
||||
auto id = scheduler::schedule(AsfMeasurements::MEASUREMENTS_LIFETIME, [=] { expireFaceInfo(faceId); });
|
||||
info.setMeasurementExpirationEventId(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -254,8 +254,7 @@ public:
|
||||
const FaceInfoTable::iterator
|
||||
insert(FaceId faceId)
|
||||
{
|
||||
const auto& pair = m_fit.insert(std::make_pair(faceId, FaceInfo()));
|
||||
return pair.first;
|
||||
return m_fit.emplace(faceId, FaceInfo()).first;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -317,7 +316,7 @@ private:
|
||||
extendLifetime(measurements::Entry& me);
|
||||
|
||||
public:
|
||||
static constexpr time::microseconds MEASUREMENTS_LIFETIME = time::seconds(300);
|
||||
static constexpr time::microseconds MEASUREMENTS_LIFETIME = 300_s;
|
||||
|
||||
private:
|
||||
MeasurementsAccessor& m_measurements;
|
||||
|
||||
@@ -70,7 +70,7 @@ ProbingModule::getFaceToProbe(const Face& inFace,
|
||||
const Face& faceUsed)
|
||||
{
|
||||
FaceInfoFacePairSet rankedFaces(
|
||||
[] (FaceInfoFacePair pairLhs, FaceInfoFacePair pairRhs) -> bool {
|
||||
[] (const auto& pairLhs, const auto& pairRhs) -> bool {
|
||||
// Sort by RTT
|
||||
// If a face has timed-out, rank it behind non-timed-out faces
|
||||
FaceInfo& lhs = *pairLhs.first;
|
||||
@@ -93,14 +93,13 @@ ProbingModule::getFaceToProbe(const Face& inFace,
|
||||
}
|
||||
|
||||
FaceInfo* info = m_measurements.getFaceInfo(fibEntry, interest, hopFace.getId());
|
||||
|
||||
// If no RTT has been recorded, probe this face
|
||||
if (info == nullptr || !info->hasSrttMeasurement()) {
|
||||
return &hopFace;
|
||||
}
|
||||
|
||||
// Add FaceInfo to container sorted by RTT
|
||||
rankedFaces.insert(std::make_pair(info, &hopFace));
|
||||
rankedFaces.insert({info, &hopFace});
|
||||
}
|
||||
|
||||
if (rankedFaces.empty()) {
|
||||
@@ -149,7 +148,7 @@ ProbingModule::getFaceBasedOnProbability(const FaceInfoFacePairSet& rankedFaces)
|
||||
uint64_t rank = 1;
|
||||
double offset = 0.0;
|
||||
|
||||
for (const FaceInfoFacePair pair : rankedFaces) {
|
||||
for (const auto& pair : rankedFaces) {
|
||||
double probability = getProbingProbability(rank++, rankSum, rankedFaces.size());
|
||||
|
||||
// Is the random number within the bounds of this face's probability + the previous faces'
|
||||
|
||||
@@ -80,8 +80,8 @@ private:
|
||||
getRandomNumber(double start, double end);
|
||||
|
||||
public:
|
||||
static constexpr time::milliseconds DEFAULT_PROBING_INTERVAL = time::milliseconds(60000);
|
||||
static constexpr time::milliseconds MIN_PROBING_INTERVAL = time::milliseconds(1000);
|
||||
static constexpr time::milliseconds DEFAULT_PROBING_INTERVAL = 1_min;
|
||||
static constexpr time::milliseconds MIN_PROBING_INTERVAL = 1_s;
|
||||
|
||||
private:
|
||||
time::milliseconds m_probingInterval;
|
||||
|
||||
@@ -25,14 +25,13 @@
|
||||
|
||||
#include "asf-strategy.hpp"
|
||||
#include "algorithm.hpp"
|
||||
|
||||
#include "core/logger.hpp"
|
||||
|
||||
namespace nfd {
|
||||
namespace fw {
|
||||
namespace asf {
|
||||
|
||||
NFD_LOG_INIT("AsfStrategy");
|
||||
NFD_LOG_INIT(AsfStrategy);
|
||||
NFD_REGISTER_STRATEGY(AsfStrategy);
|
||||
|
||||
const time::milliseconds AsfStrategy::RETX_SUPPRESSION_INITIAL(10);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -44,10 +44,8 @@ BestRouteStrategyBase::afterReceiveInterest(const Face& inFace, const Interest&
|
||||
}
|
||||
|
||||
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
|
||||
const fib::NextHopList& nexthops = fibEntry.getNextHops();
|
||||
|
||||
for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
|
||||
Face& outFace = it->getFace();
|
||||
for (const auto& nexthop : fibEntry.getNextHops()) {
|
||||
Face& outFace = nexthop.getFace();
|
||||
if (!wouldViolateScope(inFace, interest, outFace) &&
|
||||
canForwardToLegacy(*pitEntry, outFace)) {
|
||||
this->sendInterest(pitEntry, outFace, interest);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace nfd {
|
||||
namespace fw {
|
||||
|
||||
NFD_LOG_INIT("BestRouteStrategy2");
|
||||
NFD_LOG_INIT(BestRouteStrategy2);
|
||||
NFD_REGISTER_STRATEGY(BestRouteStrategy2);
|
||||
|
||||
const time::milliseconds BestRouteStrategy2::RETX_SUPPRESSION_INITIAL(10);
|
||||
@@ -69,7 +69,7 @@ BestRouteStrategy2::getStrategyName()
|
||||
* \param wantUnused if true, NextHop must not have unexpired out-record
|
||||
* \param now time::steady_clock::now(), ignored if !wantUnused
|
||||
*/
|
||||
static inline bool
|
||||
static bool
|
||||
isNextHopEligible(const Face& inFace, const Interest& interest,
|
||||
const fib::NextHop& nexthop,
|
||||
const shared_ptr<pit::Entry>& pitEntry,
|
||||
@@ -88,7 +88,7 @@ isNextHopEligible(const Face& inFace, const Interest& interest,
|
||||
|
||||
if (wantUnused) {
|
||||
// nexthop must not have unexpired out-record
|
||||
pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(outFace);
|
||||
auto outRecord = pitEntry->getOutRecord(outFace);
|
||||
if (outRecord != pitEntry->out_end() && outRecord->getExpiry() > now) {
|
||||
return false;
|
||||
}
|
||||
@@ -100,23 +100,26 @@ isNextHopEligible(const Face& inFace, const Interest& interest,
|
||||
/** \brief pick an eligible NextHop with earliest out-record
|
||||
* \note It is assumed that every nexthop has an out-record.
|
||||
*/
|
||||
static inline fib::NextHopList::const_iterator
|
||||
static fib::NextHopList::const_iterator
|
||||
findEligibleNextHopWithEarliestOutRecord(const Face& inFace, const Interest& interest,
|
||||
const fib::NextHopList& nexthops,
|
||||
const shared_ptr<pit::Entry>& pitEntry)
|
||||
{
|
||||
fib::NextHopList::const_iterator found = nexthops.end();
|
||||
time::steady_clock::TimePoint earliestRenewed = time::steady_clock::TimePoint::max();
|
||||
for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
|
||||
auto found = nexthops.end();
|
||||
auto earliestRenewed = time::steady_clock::TimePoint::max();
|
||||
|
||||
for (auto it = nexthops.begin(); it != nexthops.end(); ++it) {
|
||||
if (!isNextHopEligible(inFace, interest, *it, pitEntry))
|
||||
continue;
|
||||
pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(it->getFace());
|
||||
|
||||
auto outRecord = pitEntry->getOutRecord(it->getFace());
|
||||
BOOST_ASSERT(outRecord != pitEntry->out_end());
|
||||
if (outRecord->getLastRenewed() < earliestRenewed) {
|
||||
found = it;
|
||||
earliestRenewed = outRecord->getLastRenewed();
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
@@ -133,13 +136,13 @@ BestRouteStrategy2::afterReceiveInterest(const Face& inFace, const Interest& int
|
||||
|
||||
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
|
||||
const fib::NextHopList& nexthops = fibEntry.getNextHops();
|
||||
fib::NextHopList::const_iterator it = nexthops.end();
|
||||
auto it = nexthops.end();
|
||||
|
||||
if (suppression == RetxSuppressionResult::NEW) {
|
||||
// forward to nexthop with lowest cost except downstream
|
||||
it = std::find_if(nexthops.begin(), nexthops.end(),
|
||||
bind(&isNextHopEligible, cref(inFace), interest, _1, pitEntry,
|
||||
false, time::steady_clock::TimePoint::min()));
|
||||
it = std::find_if(nexthops.begin(), nexthops.end(), [&] (const auto& nexthop) {
|
||||
return isNextHopEligible(inFace, interest, nexthop, pitEntry);
|
||||
});
|
||||
|
||||
if (it == nexthops.end()) {
|
||||
NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " noNextHop");
|
||||
@@ -160,9 +163,10 @@ BestRouteStrategy2::afterReceiveInterest(const Face& inFace, const Interest& int
|
||||
}
|
||||
|
||||
// find an unused upstream with lowest cost except downstream
|
||||
it = std::find_if(nexthops.begin(), nexthops.end(),
|
||||
bind(&isNextHopEligible, cref(inFace), interest, _1, pitEntry,
|
||||
true, time::steady_clock::now()));
|
||||
it = std::find_if(nexthops.begin(), nexthops.end(), [&] (const auto& nexthop) {
|
||||
return isNextHopEligible(inFace, interest, nexthop, pitEntry, true, time::steady_clock::now());
|
||||
});
|
||||
|
||||
if (it != nexthops.end()) {
|
||||
Face& outFace = it->getFace();
|
||||
this->sendInterest(pitEntry, outFace, interest);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -29,7 +29,7 @@
|
||||
namespace nfd {
|
||||
namespace fw {
|
||||
|
||||
NFD_LOG_INIT("ClientControlStrategy");
|
||||
NFD_LOG_INIT(ClientControlStrategy);
|
||||
NFD_REGISTER_STRATEGY(ClientControlStrategy);
|
||||
|
||||
ClientControlStrategy::ClientControlStrategy(Forwarder& forwarder, const Name& name)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -24,16 +24,17 @@
|
||||
*/
|
||||
|
||||
#include "face-table.hpp"
|
||||
#include "core/asserts.hpp"
|
||||
#include "core/global-io.hpp"
|
||||
#include "core/logger.hpp"
|
||||
#include "face/channel.hpp"
|
||||
|
||||
#include <ndn-cxx/util/concepts.hpp>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
NFD_ASSERT_FORWARD_ITERATOR(FaceTable::const_iterator);
|
||||
NDN_CXX_ASSERT_FORWARD_ITERATOR(FaceTable::const_iterator);
|
||||
|
||||
NFD_LOG_INIT("FaceTable");
|
||||
NFD_LOG_INIT(FaceTable);
|
||||
|
||||
FaceTable::FaceTable()
|
||||
: m_lastFaceId(face::FACEID_RESERVED_MAX)
|
||||
@@ -85,7 +86,7 @@ FaceTable::addImpl(shared_ptr<Face> face, FaceId faceId)
|
||||
" remote=" << face->getRemoteUri() <<
|
||||
" local=" << face->getLocalUri());
|
||||
|
||||
connectFaceClosedSignal(*face, bind(&FaceTable::remove, this, faceId));
|
||||
connectFaceClosedSignal(*face, [=] { remove(faceId); });
|
||||
|
||||
this->afterAdd(*face);
|
||||
}
|
||||
|
||||
+107
-133
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -24,16 +24,18 @@
|
||||
*/
|
||||
|
||||
#include "forwarder.hpp"
|
||||
|
||||
#include "algorithm.hpp"
|
||||
#include "best-route-strategy2.hpp"
|
||||
#include "strategy.hpp"
|
||||
#include "core/logger.hpp"
|
||||
#include "table/cleanup.hpp"
|
||||
|
||||
#include <ndn-cxx/lp/tags.hpp>
|
||||
|
||||
namespace nfd {
|
||||
|
||||
NFD_LOG_INIT("Forwarder");
|
||||
NFD_LOG_INIT(Forwarder);
|
||||
|
||||
static Name
|
||||
getDefaultStrategyName()
|
||||
@@ -127,14 +129,11 @@ Forwarder::onIncomingInterest(Face& inFace, const Interest& interest)
|
||||
return;
|
||||
}
|
||||
|
||||
// cancel unsatisfy & straggler timer
|
||||
this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
|
||||
|
||||
// is pending?
|
||||
if (!pitEntry->hasInRecords()) {
|
||||
m_cs.find(interest,
|
||||
bind(&Forwarder::onContentStoreHit, this, ref(inFace), pitEntry, _1, _2),
|
||||
bind(&Forwarder::onContentStoreMiss, this, ref(inFace), pitEntry, _1));
|
||||
bind(&Forwarder::onContentStoreHit, this, std::ref(inFace), pitEntry, _1, _2),
|
||||
bind(&Forwarder::onContentStoreMiss, this, std::ref(inFace), pitEntry, _1));
|
||||
}
|
||||
else {
|
||||
this->onContentStoreMiss(inFace, pitEntry, interest);
|
||||
@@ -163,6 +162,12 @@ Forwarder::onInterestLoop(Face& inFace, const Interest& interest)
|
||||
inFace.sendNack(nack);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
compare_InRecord_expiry(const pit::InRecord& a, const pit::InRecord& b)
|
||||
{
|
||||
return a.getExpiry() < b.getExpiry();
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::onContentStoreMiss(const Face& inFace, const shared_ptr<pit::Entry>& pitEntry,
|
||||
const Interest& interest)
|
||||
@@ -173,8 +178,10 @@ Forwarder::onContentStoreMiss(const Face& inFace, const shared_ptr<pit::Entry>&
|
||||
// insert in-record
|
||||
pitEntry->insertOrUpdateInRecord(const_cast<Face&>(inFace), interest);
|
||||
|
||||
// set PIT unsatisfy timer
|
||||
this->setUnsatisfyTimer(pitEntry);
|
||||
// set PIT expiry timer to the time that the last PIT in-record expires
|
||||
auto lastExpiring = std::max_element(pitEntry->in_begin(), pitEntry->in_end(), &compare_InRecord_expiry);
|
||||
auto lastExpiryFromNow = lastExpiring->getExpiry() - time::steady_clock::now();
|
||||
this->setExpiryTimer(pitEntry, time::duration_cast<time::milliseconds>(lastExpiryFromNow));
|
||||
|
||||
// has NextHopFaceId?
|
||||
shared_ptr<lp::NextHopFaceIdTag> nextHopTag = interest.getTag<lp::NextHopFaceIdTag>();
|
||||
@@ -205,11 +212,15 @@ Forwarder::onContentStoreHit(const Face& inFace, const shared_ptr<pit::Entry>& p
|
||||
data.setTag(make_shared<lp::IncomingFaceIdTag>(face::FACEID_CONTENT_STORE));
|
||||
// XXX should we lookup PIT for other Interests that also match csMatch?
|
||||
|
||||
// set PIT straggler timer
|
||||
this->setStragglerTimer(pitEntry, true, data.getFreshnessPeriod());
|
||||
pitEntry->isSatisfied = true;
|
||||
pitEntry->dataFreshnessPeriod = data.getFreshnessPeriod();
|
||||
|
||||
// goto outgoing Data pipeline
|
||||
this->onOutgoingData(data, *const_pointer_cast<Face>(inFace.shared_from_this()));
|
||||
// set PIT expiry timer to now
|
||||
this->setExpiryTimer(pitEntry, 0_ms);
|
||||
|
||||
// dispatch to strategy: after Content Store hit
|
||||
this->dispatchToStrategy(*pitEntry,
|
||||
[&] (fw::Strategy& strategy) { strategy.afterContentStoreHit(pitEntry, inFace, data); });
|
||||
}
|
||||
|
||||
void
|
||||
@@ -227,47 +238,16 @@ Forwarder::onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outF
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::onInterestReject(const shared_ptr<pit::Entry>& pitEntry)
|
||||
{
|
||||
if (fw::hasPendingOutRecords(*pitEntry)) {
|
||||
NFD_LOG_ERROR("onInterestReject interest=" << pitEntry->getName() <<
|
||||
" cannot reject forwarded Interest");
|
||||
return;
|
||||
}
|
||||
NFD_LOG_DEBUG("onInterestReject interest=" << pitEntry->getName());
|
||||
|
||||
// cancel unsatisfy & straggler timer
|
||||
this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
|
||||
|
||||
// set PIT straggler timer
|
||||
this->setStragglerTimer(pitEntry, false);
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::onInterestUnsatisfied(const shared_ptr<pit::Entry>& pitEntry)
|
||||
{
|
||||
NFD_LOG_DEBUG("onInterestUnsatisfied interest=" << pitEntry->getName());
|
||||
|
||||
// invoke PIT unsatisfied callback
|
||||
this->dispatchToStrategy(*pitEntry,
|
||||
[&] (fw::Strategy& strategy) { strategy.beforeExpirePendingInterest(pitEntry); });
|
||||
|
||||
// goto Interest Finalize pipeline
|
||||
this->onInterestFinalize(pitEntry, false);
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::onInterestFinalize(const shared_ptr<pit::Entry>& pitEntry, bool isSatisfied,
|
||||
ndn::optional<time::milliseconds> dataFreshnessPeriod)
|
||||
Forwarder::onInterestFinalize(const shared_ptr<pit::Entry>& pitEntry)
|
||||
{
|
||||
NFD_LOG_DEBUG("onInterestFinalize interest=" << pitEntry->getName() <<
|
||||
(isSatisfied ? " satisfied" : " unsatisfied"));
|
||||
(pitEntry->isSatisfied ? " satisfied" : " unsatisfied"));
|
||||
|
||||
// Dead Nonce List insert if necessary
|
||||
this->insertDeadNonceList(*pitEntry, isSatisfied, dataFreshnessPeriod, 0);
|
||||
this->insertDeadNonceList(*pitEntry, 0);
|
||||
|
||||
// PIT delete
|
||||
this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
|
||||
scheduler::cancel(pitEntry->expiryTimer);
|
||||
m_pit.erase(pitEntry.get());
|
||||
}
|
||||
|
||||
@@ -291,7 +271,7 @@ Forwarder::onIncomingData(Face& inFace, const Data& data)
|
||||
|
||||
// PIT match
|
||||
pit::DataMatchResult pitMatches = m_pit.findAllDataMatches(data);
|
||||
if (pitMatches.begin() == pitMatches.end()) {
|
||||
if (pitMatches.size() == 0) {
|
||||
// goto Data unsolicited pipeline
|
||||
this->onDataUnsolicited(inFace, data);
|
||||
return;
|
||||
@@ -300,45 +280,73 @@ Forwarder::onIncomingData(Face& inFace, const Data& data)
|
||||
// CS insert
|
||||
m_cs.insert(data);
|
||||
|
||||
std::set<Face*> pendingDownstreams;
|
||||
// foreach PitEntry
|
||||
auto now = time::steady_clock::now();
|
||||
for (const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
|
||||
// when only one PIT entry is matched, trigger strategy: after receive Data
|
||||
if (pitMatches.size() == 1) {
|
||||
auto& pitEntry = pitMatches.front();
|
||||
|
||||
NFD_LOG_DEBUG("onIncomingData matching=" << pitEntry->getName());
|
||||
|
||||
// cancel unsatisfy & straggler timer
|
||||
this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
|
||||
// set PIT expiry timer to now
|
||||
this->setExpiryTimer(pitEntry, 0_ms);
|
||||
|
||||
// remember pending downstreams
|
||||
for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
|
||||
if (inRecord.getExpiry() > now) {
|
||||
pendingDownstreams.insert(&inRecord.getFace());
|
||||
}
|
||||
}
|
||||
|
||||
// invoke PIT satisfy callback
|
||||
// trigger strategy: after receive Data
|
||||
this->dispatchToStrategy(*pitEntry,
|
||||
[&] (fw::Strategy& strategy) { strategy.beforeSatisfyInterest(pitEntry, inFace, data); });
|
||||
|
||||
// Dead Nonce List insert if necessary (for out-record of inFace)
|
||||
this->insertDeadNonceList(*pitEntry, true, data.getFreshnessPeriod(), &inFace);
|
||||
[&] (fw::Strategy& strategy) { strategy.afterReceiveData(pitEntry, inFace, data); });
|
||||
|
||||
// mark PIT satisfied
|
||||
pitEntry->clearInRecords();
|
||||
pitEntry->isSatisfied = true;
|
||||
pitEntry->dataFreshnessPeriod = data.getFreshnessPeriod();
|
||||
|
||||
// Dead Nonce List insert if necessary (for out-record of inFace)
|
||||
this->insertDeadNonceList(*pitEntry, &inFace);
|
||||
|
||||
// delete PIT entry's out-record
|
||||
pitEntry->deleteOutRecord(inFace);
|
||||
|
||||
// set PIT straggler timer
|
||||
this->setStragglerTimer(pitEntry, true, data.getFreshnessPeriod());
|
||||
}
|
||||
// when more than one PIT entry is matched, trigger strategy: before satisfy Interest,
|
||||
// and send Data to all matched out faces
|
||||
else {
|
||||
std::set<Face*> pendingDownstreams;
|
||||
auto now = time::steady_clock::now();
|
||||
|
||||
// foreach pending downstream
|
||||
for (Face* pendingDownstream : pendingDownstreams) {
|
||||
if (pendingDownstream->getId() == inFace.getId() &&
|
||||
pendingDownstream->getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
|
||||
continue;
|
||||
for (const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
|
||||
NFD_LOG_DEBUG("onIncomingData matching=" << pitEntry->getName());
|
||||
|
||||
// remember pending downstreams
|
||||
for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
|
||||
if (inRecord.getExpiry() > now) {
|
||||
pendingDownstreams.insert(&inRecord.getFace());
|
||||
}
|
||||
}
|
||||
|
||||
// set PIT expiry timer to now
|
||||
this->setExpiryTimer(pitEntry, 0_ms);
|
||||
|
||||
// invoke PIT satisfy callback
|
||||
this->dispatchToStrategy(*pitEntry,
|
||||
[&] (fw::Strategy& strategy) { strategy.beforeSatisfyInterest(pitEntry, inFace, data); });
|
||||
|
||||
// mark PIT satisfied
|
||||
pitEntry->isSatisfied = true;
|
||||
pitEntry->dataFreshnessPeriod = data.getFreshnessPeriod();
|
||||
|
||||
// Dead Nonce List insert if necessary (for out-record of inFace)
|
||||
this->insertDeadNonceList(*pitEntry, &inFace);
|
||||
|
||||
// clear PIT entry's in and out records
|
||||
pitEntry->clearInRecords();
|
||||
pitEntry->deleteOutRecord(inFace);
|
||||
}
|
||||
|
||||
// foreach pending downstream
|
||||
for (Face* pendingDownstream : pendingDownstreams) {
|
||||
if (pendingDownstream->getId() == inFace.getId() &&
|
||||
pendingDownstream->getLinkType() != ndn::nfd::LINK_TYPE_AD_HOC) {
|
||||
continue;
|
||||
}
|
||||
// goto outgoing Data pipeline
|
||||
this->onOutgoingData(data, *pendingDownstream);
|
||||
}
|
||||
// goto outgoing Data pipeline
|
||||
this->onOutgoingData(data, *pendingDownstream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,6 +442,11 @@ Forwarder::onIncomingNack(Face& inFace, const lp::Nack& nack)
|
||||
// record Nack on out-record
|
||||
outRecord->setIncomingNack(nack);
|
||||
|
||||
// set PIT expiry timer to now when all out-record receive Nack
|
||||
if (!fw::hasPendingOutRecords(*pitEntry)) {
|
||||
this->setExpiryTimer(pitEntry, 0_ms);
|
||||
}
|
||||
|
||||
// trigger strategy: after receive NACK
|
||||
this->dispatchToStrategy(*pitEntry,
|
||||
[&] (fw::Strategy& strategy) { strategy.afterReceiveNack(inFace, nack, pitEntry); });
|
||||
@@ -491,65 +504,25 @@ Forwarder::onDroppedInterest(Face& outFace, const Interest& interest)
|
||||
m_strategyChoice.findEffectiveStrategy(interest.getName()).onDroppedInterest(outFace, interest);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
compare_InRecord_expiry(const pit::InRecord& a, const pit::InRecord& b)
|
||||
void
|
||||
Forwarder::setExpiryTimer(const shared_ptr<pit::Entry>& pitEntry, time::milliseconds duration)
|
||||
{
|
||||
return a.getExpiry() < b.getExpiry();
|
||||
BOOST_ASSERT(duration >= 0_ms);
|
||||
|
||||
scheduler::cancel(pitEntry->expiryTimer);
|
||||
|
||||
pitEntry->expiryTimer = scheduler::schedule(duration, [=] { onInterestFinalize(pitEntry); });
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::setUnsatisfyTimer(const shared_ptr<pit::Entry>& pitEntry)
|
||||
{
|
||||
pit::InRecordCollection::iterator lastExpiring =
|
||||
std::max_element(pitEntry->in_begin(), pitEntry->in_end(), &compare_InRecord_expiry);
|
||||
|
||||
time::steady_clock::TimePoint lastExpiry = lastExpiring->getExpiry();
|
||||
time::nanoseconds lastExpiryFromNow = lastExpiry - time::steady_clock::now();
|
||||
if (lastExpiryFromNow <= time::seconds::zero()) {
|
||||
// TODO all in-records are already expired; will this happen?
|
||||
}
|
||||
|
||||
scheduler::cancel(pitEntry->m_unsatisfyTimer);
|
||||
pitEntry->m_unsatisfyTimer = scheduler::schedule(lastExpiryFromNow,
|
||||
bind(&Forwarder::onInterestUnsatisfied, this, pitEntry));
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::setStragglerTimer(const shared_ptr<pit::Entry>& pitEntry, bool isSatisfied,
|
||||
ndn::optional<time::milliseconds> dataFreshnessPeriod)
|
||||
{
|
||||
time::nanoseconds stragglerTime = time::milliseconds(100);
|
||||
|
||||
scheduler::cancel(pitEntry->m_stragglerTimer);
|
||||
pitEntry->m_stragglerTimer = scheduler::schedule(stragglerTime,
|
||||
bind(&Forwarder::onInterestFinalize, this, pitEntry, isSatisfied, dataFreshnessPeriod));
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::cancelUnsatisfyAndStragglerTimer(pit::Entry& pitEntry)
|
||||
{
|
||||
scheduler::cancel(pitEntry.m_unsatisfyTimer);
|
||||
scheduler::cancel(pitEntry.m_stragglerTimer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
insertNonceToDnl(DeadNonceList& dnl, const pit::Entry& pitEntry,
|
||||
const pit::OutRecord& outRecord)
|
||||
{
|
||||
dnl.add(pitEntry.getName(), outRecord.getLastNonce());
|
||||
}
|
||||
|
||||
void
|
||||
Forwarder::insertDeadNonceList(pit::Entry& pitEntry, bool isSatisfied,
|
||||
ndn::optional<time::milliseconds> dataFreshnessPeriod, Face* upstream)
|
||||
Forwarder::insertDeadNonceList(pit::Entry& pitEntry, Face* upstream)
|
||||
{
|
||||
// need Dead Nonce List insert?
|
||||
bool needDnl = true;
|
||||
if (isSatisfied) {
|
||||
BOOST_ASSERT(dataFreshnessPeriod);
|
||||
BOOST_ASSERT(*dataFreshnessPeriod >= time::milliseconds::zero());
|
||||
if (pitEntry.isSatisfied) {
|
||||
BOOST_ASSERT(pitEntry.dataFreshnessPeriod >= 0_ms);
|
||||
needDnl = static_cast<bool>(pitEntry.getInterest().getMustBeFresh()) &&
|
||||
*dataFreshnessPeriod < m_deadNonceList.getLifetime();
|
||||
pitEntry.dataFreshnessPeriod < m_deadNonceList.getLifetime();
|
||||
}
|
||||
|
||||
if (!needDnl) {
|
||||
@@ -559,13 +532,14 @@ Forwarder::insertDeadNonceList(pit::Entry& pitEntry, bool isSatisfied,
|
||||
// Dead Nonce List insert
|
||||
if (upstream == nullptr) {
|
||||
// insert all outgoing Nonces
|
||||
const pit::OutRecordCollection& outRecords = pitEntry.getOutRecords();
|
||||
std::for_each(outRecords.begin(), outRecords.end(),
|
||||
bind(&insertNonceToDnl, ref(m_deadNonceList), cref(pitEntry), _1));
|
||||
const auto& outRecords = pitEntry.getOutRecords();
|
||||
std::for_each(outRecords.begin(), outRecords.end(), [&] (const auto& outRecord) {
|
||||
m_deadNonceList.add(pitEntry.getName(), outRecord.getLastNonce());
|
||||
});
|
||||
}
|
||||
else {
|
||||
// insert outgoing Nonce of a specific face
|
||||
pit::OutRecordCollection::iterator outRecord = pitEntry.getOutRecord(*upstream);
|
||||
auto outRecord = pitEntry.getOutRecord(*upstream);
|
||||
if (outRecord != pitEntry.getOutRecords().end()) {
|
||||
m_deadNonceList.add(pitEntry.getName(), outRecord->getLastNonce());
|
||||
}
|
||||
|
||||
+8
-27
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -209,23 +209,10 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE: // pipelines
|
||||
VIRTUAL_WITH_TESTS void
|
||||
onOutgoingInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outFace, const Interest& interest);
|
||||
|
||||
/** \brief Interest reject pipeline
|
||||
*/
|
||||
VIRTUAL_WITH_TESTS void
|
||||
onInterestReject(const shared_ptr<pit::Entry>& pitEntry);
|
||||
|
||||
/** \brief Interest unsatisfied pipeline
|
||||
*/
|
||||
VIRTUAL_WITH_TESTS void
|
||||
onInterestUnsatisfied(const shared_ptr<pit::Entry>& pitEntry);
|
||||
|
||||
/** \brief Interest finalize pipeline
|
||||
* \param isSatisfied whether the Interest has been satisfied
|
||||
* \param dataFreshnessPeriod FreshnessPeriod of satisfying Data
|
||||
*/
|
||||
VIRTUAL_WITH_TESTS void
|
||||
onInterestFinalize(const shared_ptr<pit::Entry>& pitEntry, bool isSatisfied,
|
||||
ndn::optional<time::milliseconds> dataFreshnessPeriod = ndn::nullopt);
|
||||
onInterestFinalize(const shared_ptr<pit::Entry>& pitEntry);
|
||||
|
||||
/** \brief incoming Data pipeline
|
||||
*/
|
||||
@@ -256,29 +243,23 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE: // pipelines
|
||||
onDroppedInterest(Face& outFace, const Interest& interest);
|
||||
|
||||
PROTECTED_WITH_TESTS_ELSE_PRIVATE:
|
||||
VIRTUAL_WITH_TESTS void
|
||||
setUnsatisfyTimer(const shared_ptr<pit::Entry>& pitEntry);
|
||||
|
||||
VIRTUAL_WITH_TESTS void
|
||||
setStragglerTimer(const shared_ptr<pit::Entry>& pitEntry, bool isSatisfied,
|
||||
ndn::optional<time::milliseconds> dataFreshnessPeriod = ndn::nullopt);
|
||||
|
||||
VIRTUAL_WITH_TESTS void
|
||||
cancelUnsatisfyAndStragglerTimer(pit::Entry& pitEntry);
|
||||
/** \brief set a new expiry timer (now + \p duration) on a PIT entry
|
||||
*/
|
||||
void
|
||||
setExpiryTimer(const shared_ptr<pit::Entry>& pitEntry, time::milliseconds duration);
|
||||
|
||||
/** \brief insert Nonce to Dead Nonce List if necessary
|
||||
* \param upstream if null, insert Nonces from all out-records;
|
||||
* if not null, insert Nonce only on the out-records of this face
|
||||
*/
|
||||
VIRTUAL_WITH_TESTS void
|
||||
insertDeadNonceList(pit::Entry& pitEntry, bool isSatisfied,
|
||||
ndn::optional<time::milliseconds> dataFreshnessPeriod, Face* upstream);
|
||||
insertDeadNonceList(pit::Entry& pitEntry, Face* upstream);
|
||||
|
||||
/** \brief call trigger (method) on the effective strategy of pitEntry
|
||||
*/
|
||||
#ifdef WITH_TESTS
|
||||
virtual void
|
||||
dispatchToStrategy(pit::Entry& pitEntry, function<void(fw::Strategy&)> trigger)
|
||||
dispatchToStrategy(pit::Entry& pitEntry, std::function<void(fw::Strategy&)> trigger)
|
||||
#else
|
||||
template<class Function>
|
||||
void
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, Regents of the University of California,
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -32,7 +32,7 @@ namespace fw {
|
||||
|
||||
NFD_REGISTER_STRATEGY(MulticastStrategy);
|
||||
|
||||
NFD_LOG_INIT("MulticastStrategy");
|
||||
NFD_LOG_INIT(MulticastStrategy);
|
||||
|
||||
const time::milliseconds MulticastStrategy::RETX_SUPPRESSION_INITIAL(10);
|
||||
const time::milliseconds MulticastStrategy::RETX_SUPPRESSION_MAX(250);
|
||||
|
||||
Loaded 100 of 293 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user