Compare commits

..
37 Commits
Author SHA1 Message Date
SunnyQjm 9bc57b880b feat: Add qsccp sched 2023-12-03 17:57:24 +08:00
Varun Patil 9b877c3a23 docker: add HOME environment variable and default config
Change-Id: I82b8d46ba74dc648786c23e68a1d1498c893108a
2023-11-18 18:20:28 -08:00
Varun Patil 23135a4cdd Add Dockerfile for nfd-status-http-server
Change-Id: I87349b2cf351c7323d8511677ce7f4a31d944387
2023-11-18 20:21:24 -05:00
Varun PatilandJunxiao Shi 6ba08cd5cb Add initial Dockerfile and CI workflow
Co-authored-by: Junxiao Shi <git@mail1.yoursunny.com>
Change-Id: Ib8341b61edef9be4e4c5f43836ff936c3c063010
2023-11-18 17:18:25 -05:00
Davide Pesavento e277f8b9e8 tools: switch to Face::getIoContext()
Change-Id: I6be4c682d62e1061af45052d2141b9e5b9e897c5
2023-11-11 17:14:02 -05:00
Davide Pesavento 9a63bf22d0 face: add missing includes
Change-Id: I2d855f71310e824205d37d892749c3eab9f5b3c3
2023-11-11 17:12:51 -05:00
Davide Pesavento ef6a528ae0 tests: randomize port used in multicast transport tests
Change-Id: I6030317ad10cf6f3c81f29c2a3898b41a1982c0e
2023-11-03 16:50:10 -04:00
Davide Pesavento 05bd6c2d69 docs: update list of supported platforms
Change-Id: I6aad1f19b593e707e0468e24b160bf3e769376d7
2023-10-31 21:45:25 -04:00
Davide Pesavento a9ec67c52b tests: expand test coverage of EthernetFactory and UdpFactory
Change-Id: I469ac8682502ca7a0e360703b462bfb119eaedf1
2023-10-23 21:00:03 -04:00
Davide Pesavento d7083a507f tests: refactor EthernetFixture
Also, use BOOST_TEST_INFO_SCOPE in a few places.

Change-Id: I113f326207825949ed9d3d22ade0654976d49b76
2023-10-19 17:51:16 -04:00
Davide Pesavento c5a9f81fce face: more robust handling of multicast face creation errors
Refs: #5030, #5297
Change-Id: I3ca985498d9d3756cbff94873063f3734bcea288
2023-10-19 02:12:05 -04:00
Davide Pesavento 0a05f7aea6 build: disable -Wnon-virtual-dtor compiler warning
It's overkill and suffers from annoying false positives that
prevent us from applying the "protected non-virtual destructor"
idiom in several perfectly valid cases. See for instance the
GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102168

The -Wdelete-non-virtual-dtor warning (included in -Wall) is
the preferred alternative and is enough to catch the unsafe
cases without false positives.

Partially reverts 847de408cb

Change-Id: I46ee1f01e7d4e2b125c2c534c6550824ba1de4c0
2023-10-16 20:50:03 -04:00
Davide Pesavento c0df94ed10 face: minor code cleanups
Change-Id: I154d2ad4dfd9e12e1fa9756f74884286b31298e4
2023-10-08 19:26:55 -04:00
awlane 9c36a65b11 face: handle PcapHelper::Error when applying multicast configuration
When the network interface state is changed, NFD reconfigures its
multicast ethernet faces. The code responsible for this is prone to
a TOCTOU race condition, e.g., if an interface is quickly brought up
and then down again. This currently raises an uncaught exception when
we try to set a packet filter for that interface.

Prevent this issue by catching PcapHelper errors in the same manner
as we catch EthernetTransport errors, and skip creating the face.

Refs: #5297
Change-Id: I9f91ac7c42dec06de34128cb34d6de8bb57e8cf5
2023-10-08 16:52:06 -04:00
Davide Pesavento 1e0c88e184 face: use async_wait operation instead of async_read with null_buffers
Change-Id: I2914e7f8fbd1b9a9e1fa8113d53700e7d6184464
2023-10-05 03:52:52 -04:00
Davide Pesavento 9bf64cc60d face: use new-style async_accept API
Change-Id: Id9de72c0922ec9ea13e5b1d9ded27dd7edf67e38
2023-10-05 02:12:02 -04:00
Davide Pesavento d91fe6d921 core+face: avoid deprecated Boost.Asio interfaces
Change-Id: I07ec286531edf63f258babe1561b4da2a88edd10
2023-10-04 21:40:02 -04:00
Davide Pesavento 5d64263dcb daemon: use asio::defer() instead of asio::post() where appropriate
Change-Id: I24d0fab6499d6430dd500ca157daa87f48960d15
2023-10-03 00:36:08 -04:00
Davide Pesavento a9e1ab2664 build: require boost >= 1.71.0
Refs: #5276
Change-Id: Ie428541639dcf1113acfb9e9d0a80f9be87d6cd3
2023-10-02 22:42:02 -04:00
Davide Pesavento 910232fce0 build: use python f-strings
Change-Id: I955739ac40508642509521760c1bc75286c94f30
2023-09-08 14:20:02 -04:00
Davide Pesavento decaf509b4 tools: modernize nfd-status-http-server and improve error handling
Change-Id: I5715c35f79d7dcd8dbefed328ebb625e9150a846
2023-08-30 22:50:03 -04:00
Davide Pesavento 8f0b8b6063 Simplify some code with Boost.Operators
Change-Id: Ic873bcbaf6be00d5c35601cfc8090df534d815ee
2023-08-29 21:04:08 -04:00
Davide Pesavento 11f1fd8340 build: update waf to version 2.0.26
Change-Id: I896871a312983ff36f1784aa53484c5edf95ebda
2023-08-19 01:50:04 -04:00
Davide Pesavento bf2e67fb14 build: enable a few more compiler warnings
Refactor default-compiler-flags.py to reduce duplication

Change-Id: I627b05257c2eec5c3ada9994bcd2b9a9be362157
2023-08-07 17:06:02 -04:00
Davide Pesavento 5b15e2fe97 build: decrease level of debug information produced by default
Refs: #5279
Change-Id: I537ff2a0a2e411279922823ae46cb7fee6586670
2023-08-07 16:35:35 -04:00
Davide Pesavento 95afc6d8a4 fw: increment nOutNacks when sending a Nack from onInterestLoop
Also expand test coverage of all forwarder counters

Change-Id: I6948af05aca1b5589e2f1c8a1f23c002d39d0ec0
2023-08-02 21:20:05 -04:00
Alex LaneandDavide Pesavento 653eb07e29 fw: refactor strategy logging and improve ASF probe logging
Bring strategy logging in line with format from 6bf94c0.
This should also marginally improve performance when log level is raised.

Refs: #5262, #5267
Co-authored-by: Davide Pesavento <davidepesa@gmail.com>
Change-Id: I6493b6476f3d0c6ae5562b66abfa46f6c6f4903d
2023-07-28 14:14:11 -04:00
Alex Lane 6bf94c02f5 fw: add Interest nonce to Forwarder logging where appropriate
Refs: #5262
Change-Id: Id3675fe1adb973d403f1e2ba386e9a4ec686c7b6
2023-06-08 02:42:02 -04:00
Davide Pesavento 191a7a24e6 core+daemon: declare all equality operators as hidden friends
Change-Id: Id832ee1fb16fb6742879c8b87f56002f94745103
2023-05-17 22:50:32 -04:00
Davide Pesavento ae43030f6f Further reduce the use of std::bind()
And also avoid deprecated ndn-cxx type aliases

Change-Id: I87e903b9671a3cf1c1b9ab30d4594d595c3c6da9
2023-05-11 01:50:11 -04:00
Davide Pesavento 63b3ae818f tools: fix compilation with latest ndn-cxx
Change-Id: Ifded624f3256452be98f288f9193dd26e464cd36
2023-03-27 14:05:04 -04:00
Davide Pesavento 4064127b97 mgmt+tools: add missing includes
Change-Id: I53aeaa6b223b616c170697662d02a028cea67400
2023-03-16 13:31:12 -04:00
Davide Pesavento d6ea0b1e0e tests: use std::nullopt
Change-Id: I7efdc8076c1bc4ced11dd3bdab7f199609009545
2023-03-13 22:54:15 -04:00
Davide Pesavento c5e3e7a55d build: drop official support for Ubuntu 18.04 and macOS 10.15
Increase the minimum required version of clang to 7.0 on linux, because
older versions fail to compile libstdc++'s implementation of std::variant

Change-Id: I6320973cbe3ff00faa8a36cd0e7ddf564c20d965
2023-03-07 21:25:27 -05:00
Davide Pesavento bf4c131f82 docs: update several URLs to point to docs.named-data.net
Change-Id: I4bab897f17e2b929675119198c9eab0309b6cc3e
2023-02-23 20:32:01 -05:00
Davide Pesavento 39c67f6291 build: switch source archive to xz compression
And a few minor README improvements

Change-Id: Iae8dc8fb3f5ac53296ffdadc8d2b893d13b8e684
2023-02-15 00:26:26 -05:00
Davide Pesavento 269b702f3d ci: adopt reusable workflows from named-data/actions
Change-Id: Iefd142d82f56a6fb83c5039565b6eba83c6e6445
2023-02-12 16:14:56 -05:00
241 changed files with 3759 additions and 2243 deletions

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
Dockerfile
/build/
.waf-*-*/
.waf3-*-*/
.lock-waf*
/VERSION.info
+10 -58
View File
@@ -3,67 +3,19 @@ on:
push:
paths-ignore:
- 'docs/**'
- '*.conf.sample*'
- '*.md'
- '.mailmap'
workflow_dispatch:
permissions:
contents: read
permissions: {}
jobs:
linux:
name: ${{ matrix.compiler }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04]
compiler: [g++-7, g++-8, g++-9, g++-10,
clang++-7, clang++-8, clang++-9, clang++-10, clang++-11, clang++-12]
include:
- os: ubuntu-22.04
compiler: g++-11
- os: ubuntu-22.04
compiler: g++-12
- os: ubuntu-22.04
compiler: clang++-13
- os: ubuntu-22.04
compiler: clang++-14
env:
CXX: ${{ matrix.compiler }}
steps:
- name: Install C++ compiler
run: |
sudo apt-get -qy install ${CXX/clang++/clang}
${CXX} --version
- name: Checkout
uses: actions/checkout@v3
with:
submodules: true
- name: Build and test
run: ./.jenkins
macos:
name: Xcode ${{ matrix.xcode }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-11]
xcode: ['12.4', '12.5', '13.2']
include:
- os: macos-12
xcode: '13.4'
- os: macos-12
xcode: '14.2'
steps:
- name: Set up Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode }}
- name: Checkout
uses: actions/checkout@v3
with:
submodules: true
- name: Build and test
run: ./.jenkins
Ubuntu:
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
with:
submodules: true
macOS:
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
with:
submodules: true
+81
View File
@@ -0,0 +1,81 @@
name: Publish Docker image
on:
push:
branches:
- master
paths-ignore:
- '*.md'
- '.mailmap'
workflow_dispatch:
permissions:
contents: read
packages: write
env:
REGISTRY: ghcr.io
jobs:
nfd:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Login to ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/nfd
flavor: latest=true
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
pull: true
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
nfd-status-http-server:
needs: nfd
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/nfd-status-http-server
flavor: latest=true
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./tools
file: ./tools/Dockerfile.nfd-status-http-server
pull: true
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+17 -30
View File
@@ -1,37 +1,24 @@
name: Docs
on:
push:
paths-ignore:
- '*.md'
- '.mailmap'
workflow_dispatch:
inputs:
skip-deploy:
description: 'Skip deployment?'
required: true
type: boolean
permissions:
contents: read
permissions: {}
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
env:
JOB_NAME: Docs
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: true
- name: Install dependencies
run: |
find .jenkins.d/ -type f -name '[1-9]*.sh' -exec chmod -x '{}' +
./.jenkins
- name: Build documentation
run: |
pybindir=$(python3 -c 'import sysconfig; print(sysconfig.get_path("scripts", "posix_user"))')
export PATH="${pybindir}${PATH:+:}${PATH}"
./waf --color=yes configure
./waf --color=yes build --targets=version.hpp
./waf --color=yes build --targets=manpages
./waf --color=yes docs
html:
uses: named-data/actions/.github/workflows/docs-html.yml@v1
with:
submodules: true
# Deploy only the master branch and release tags
deploy: ${{ !inputs.skip-deploy && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/NFD-')) }}
secrets: inherit
man:
uses: named-data/actions/.github/workflows/docs-man.yml@v1
with:
submodules: true
+3
View File
@@ -32,6 +32,9 @@ if [[ $JOB_NAME == *"code-coverage" ]]; then
export DISABLE_HEADERS_CHECK=yes
fi
# https://reproducible-builds.org/docs/source-date-epoch/
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
for file in .jenkins.d/*; do
[[ -f $file && -x $file ]] || continue
+9 -7
View File
@@ -1,14 +1,16 @@
<aa@cs.fiu.edu> <alexander.afanasyev@ucla.edu>
Alexander Lane <awlane@memphis.edu>
<chghasemi@cs.arizona.edu> <chavoosh.ghasemi@gmail.com>
<davidepesa@gmail.com> <davide.pesavento@lip6.fr>
<enewberry@email.arizona.edu> <enewberry@cs.arizona.edu>
Vince Lehman <vslehman@memphis.edu> <vlehman1@gmail.com>
<lybmath2009@gmail.com> <lybmath@ucla.edu>
Hila Ben Abraham <hilata@gmail.com>
<tuyukai1994@gmail.com> <tyk@bupt.edu.cn>
Haowei Yuan <hyuan@wustl.edu>
Hila Ben Abraham <hilata@gmail.com>
<lybmath2009@gmail.com> <lybmath@ucla.edu>
Md Ashiqur Rahman <marahman@email.arizona.edu>
Minsheng Zhang <jimmyzms5@gmail.com>
Spyridon Mastorakis <spiros.mastorakis@gmail.com>
Md Ashiqur Rahman <marahman@email.arizona.edu>
Yumin Xia <me@yumin-xia.com>
<chghasemi@cs.arizona.edu> <chavoosh.ghasemi@gmail.com>
Susmit Shannigrahi <susmit@cs.colostate.edu>
Tai-Lin Chu <tailinchu@gmail.com>
<tuyukai1994@gmail.com> <tyk@bupt.edu.cn>
Vince Lehman <vslehman@memphis.edu> <vlehman1@gmail.com>
Yumin Xia <me@yumin-xia.com>
+81 -64
View File
@@ -3,10 +3,12 @@
import platform
from waflib import Configure, Logs, Utils
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
help='Compile in debugging mode with minimal optimizations (-Og)')
def configure(conf):
conf.start_msg('Checking C++ compiler version')
@@ -18,19 +20,22 @@ def configure(conf):
if cxx == 'gcc':
if ccver < (7, 4, 0):
errmsg = ('The version of gcc you are using is too old.\n'
'The minimum supported gcc version is 7.4.')
'The minimum supported gcc version is 9.3.')
elif ccver < (9, 3, 0):
warnmsg = ('Using a version of gcc older than 9.3 is not '
'officially supported and may result in build failures.')
conf.flags = GccFlags()
elif cxx == 'clang':
if Utils.unversioned_sys_platform() == 'darwin':
if ccver < (10, 0, 0):
errmsg = ('The version of Xcode you are using is too old.\n'
'The minimum supported Xcode version is 11.3.')
elif ccver < (11, 0, 0):
warnmsg = ('Using a version of Xcode older than 11.3 is not '
'The minimum supported Xcode version is 12.4.')
elif ccver < (12, 0, 0):
warnmsg = ('Using a version of Xcode older than 12.4 is not '
'officially supported and may result in build failures.')
elif ccver < (6, 0, 0):
elif ccver < (7, 0, 0):
errmsg = ('The version of clang you are using is too old.\n'
'The minimum supported clang version is 6.0.')
'The minimum supported clang version is 7.0.')
conf.flags = ClangFlags()
else:
warnmsg = f'{cxx} compiler is unsupported'
@@ -45,7 +50,7 @@ def configure(conf):
else:
conf.end_msg(ccverstr)
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
# General flags are always applied (e.g., selecting C++ language standard)
generalFlags = conf.flags.getGeneralFlags(conf)
@@ -53,6 +58,7 @@ def configure(conf):
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
conf.env.DEFINES += generalFlags['DEFINES']
@Configure.conf
def check_compiler_flags(conf):
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
@@ -75,10 +81,11 @@ def check_compiler_flags(conf):
conf.env.DEFINES += extraFlags['DEFINES']
@Configure.conf
def add_supported_cxxflags(self, cxxflags):
"""
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
"""
if len(cxxflags) == 0:
return
@@ -94,10 +101,11 @@ def add_supported_cxxflags(self, cxxflags):
self.end_msg(' '.join(supportedFlags))
self.env.prepend_value('CXXFLAGS', supportedFlags)
@Configure.conf
def add_supported_linkflags(self, linkflags):
"""
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
Check which linkflags are supported by the active compiler and add them to env.LINKFLAGS variable.
"""
if len(linkflags) == 0:
return
@@ -114,13 +122,17 @@ def add_supported_linkflags(self, linkflags):
self.env.prepend_value('LINKFLAGS', supportedFlags)
class CompilerFlags(object):
class CompilerFlags:
def getCompilerVersion(self, conf):
return tuple(int(i) for i in conf.env.CC_VERSION)
def getGeneralFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
return {
'CXXFLAGS': [],
'LINKFLAGS': [],
'DEFINES': ['BOOST_FILESYSTEM_NO_DEPRECATED'],
}
def getDebugFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
@@ -130,94 +142,99 @@ class CompilerFlags(object):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
class GccBasicFlags(CompilerFlags):
class GccClangCommonFlags(CompilerFlags):
"""
This class defines basic flags that work for both gcc and clang compilers
This class defines common flags that work for both gcc and clang compilers.
"""
def getGeneralFlags(self, conf):
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
flags = super().getGeneralFlags(conf)
flags['CXXFLAGS'] += ['-std=c++17']
if Utils.unversioned_sys_platform() != 'darwin':
flags['LINKFLAGS'] += ['-fuse-ld=lld']
return flags
__cxxFlags = [
'-fdiagnostics-color',
'-Wall',
'-Wextra',
'-Wpedantic',
'-Wenum-conversion',
'-Wextra-semi',
'-Wno-unused-parameter',
]
__linkFlags = ['-Wl,-O1']
def getDebugFlags(self, conf):
flags = super(GccBasicFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-Og',
'-g3',
'-Wall',
'-Wextra',
'-Wpedantic',
'-Werror',
'-Wcatch-value=2',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-Wl,-O1']
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += ['-Og', '-g'] + self.__cxxFlags + [
'-Werror',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
]
flags['LINKFLAGS'] += self.__linkFlags
return flags
def getOptimizedFlags(self, conf):
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2',
'-g',
'-Wall',
'-Wextra',
'-Wpedantic',
'-Wcatch-value=2',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-unused-parameter',
]
flags['LINKFLAGS'] += ['-Wl,-O1']
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-O2', '-g1'] + self.__cxxFlags
flags['LINKFLAGS'] += self.__linkFlags
return flags
class GccFlags(GccBasicFlags):
class GccFlags(GccClangCommonFlags):
__cxxFlags = [
'-Wcatch-value=2',
'-Wcomma-subscript', # enabled by default in C++20
'-Wduplicated-branches',
'-Wduplicated-cond',
'-Wlogical-op',
'-Wredundant-tags',
'-Wvolatile', # enabled by default in C++20
]
def getDebugFlags(self, conf):
flags = super(GccFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fdiagnostics-color',
'-Wredundant-tags',
]
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
def getOptimizedFlags(self, conf):
flags = super(GccFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fdiagnostics-color',
'-Wredundant-tags',
]
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
if platform.machine() == 'armv7l':
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
class ClangFlags(GccBasicFlags):
class ClangFlags(GccClangCommonFlags):
def getGeneralFlags(self, conf):
flags = super(ClangFlags, self).getGeneralFlags(conf)
flags = super().getGeneralFlags(conf)
if Utils.unversioned_sys_platform() == 'darwin':
# Bug #4296
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
flags['CXXFLAGS'] += [['-isystem', f'{brewdir}/include'], # for Homebrew
['-isystem', '/opt/local/include']] # for MacPorts
flags['CXXFLAGS'] += [
['-isystem', f'{brewdir}/include'], # for Homebrew
['-isystem', '/opt/local/include'], # for MacPorts
]
elif Utils.unversioned_sys_platform() == 'freebsd':
# Bug #4790
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
return flags
__cxxFlags = [
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
def getDebugFlags(self, conf):
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
flags = super().getDebugFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
flags = super().getOptimizedFlags(conf)
flags['CXXFLAGS'] += self.__cxxFlags
return flags
+2 -1
View File
@@ -2,7 +2,7 @@
The following lists maintainers, primary developers, and all much-appreciated contributors to NFD in alphabetical order.
The specific contributions of individual authors can be obtained from the git history of the [official NFD repository](https://github.com/named-data/NFD).
If you would like to become a contributor to the official repository, please follow the recommendations in <https://github.com/named-data/.github/blob/master/CONTRIBUTING.md>.
If you would like to become a contributor to the official repository, please follow the recommendations in <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>.
* Jerald Paul Abraham <https://cs.arizona.edu/~jeraldabraham>
* ***(Maintainer)*** Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
@@ -19,6 +19,7 @@ If you would like to become a contributor to the official repository, please fol
* Nick Gordon <https://github.com/gorgonical>
* Giulio Grassi <https://www.lip6.fr/actualite/personnes-fiche.php?ident=D1461>
* Yi Huang <https://www.linkedin.com/in/yihuang1991>
* Alexander Lane <https://github.com/awlane>
* Jongseok Lee <https://github.com/imwhiz>
* Spencer Lee <https://www.linkedin.com/in/spenlee>
* Vince Lehman <http://vslehman.com>
+1 -1
View File
@@ -3,7 +3,7 @@ message: If you use NFD in your research, please cite it as below.
license: GPL-3.0-or-later
repository-code: "https://github.com/named-data/NFD"
title: Named Data Networking Forwarding Daemon
url: "https://named-data.net/doc/NFD/"
url: "https://docs.named-data.net/NFD/"
preferred-citation:
authors:
- name: Named Data Networking Project Team
+45
View File
@@ -0,0 +1,45 @@
FROM ghcr.io/named-data/ndn-cxx:latest as builder
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpcap-dev \
&& rm -rf /var/lib/apt/lists/*
COPY . /NFD
RUN cd /NFD \
&& ./waf configure --without-pch --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
&& ./waf \
&& ./waf install \
# get list of dependencies
&& mkdir -p /shlibdeps/debian && cd /shlibdeps && touch debian/control \
&& dpkg-shlibdeps --ignore-missing-info /usr/lib/libndn-cxx.so* /usr/bin/nfdc /usr/bin/nfd \
&& sed -n '/^shlibs:Depends=/ s|shlibs:Depends=||p' debian/substvars | sed -e 's|,||g' -e 's| ([^)]*)||g' > /deps.txt
# use same base distro version as named-data/ndn-cxx
FROM debian:bookworm
COPY --from=builder /deps.txt /
RUN apt-get update \
&& apt-get install -y --no-install-recommends $(cat /deps.txt) \
&& rm -rf /var/lib/apt/lists/* /deps.txt
COPY --from=builder /usr/lib/libndn-cxx.so* /usr/lib/
COPY --from=builder /usr/bin/nfd /usr/bin/
COPY --from=builder /usr/bin/nfdc /usr/bin/
COPY --from=builder /usr/bin/nfd-status-http-server /usr/bin/
COPY --from=builder /usr/share/ndn/ /usr/share/ndn/
COPY --from=builder /etc/ndn/nfd.conf.sample /config/nfd.conf
ENV HOME=/config
VOLUME /config
VOLUME /run/nfd
EXPOSE 6363/tcp
EXPOSE 6363/udp
EXPOSE 9696/tcp
ENTRYPOINT ["/usr/bin/nfd"]
CMD ["--config", "/config/nfd.conf"]
+7 -9
View File
@@ -1,7 +1,7 @@
# Notes for NFD developers
If you are new to the NDN software community, please read the
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md).
If you are new to the NDN software community, please read our
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md).
## Code style
@@ -9,11 +9,9 @@ NFD code is subject to [NFD code style](https://redmine.named-data.net/projects/
## Licensing
Contributions to NFD must be licensed under the GPL 3.0 or compatible license. If you
are choosing GPL 3.0, please use the following license boilerplate in all `.hpp` and
`.cpp` files:
Include the following license boilerplate into all `.hpp` and `.cpp` files:
Contributions to NFD must be licensed under the GPL v3 or a compatible license.
If you choose the GPL v3, please use the following license boilerplate in all `.hpp`
and `.cpp` files:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
@@ -61,7 +59,7 @@ The simplest way to run the tests is to launch the compiled binary without any p
# Run NFD RIB management tests
./build/unit-tests-rib
The [Boost.Test framework](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html)
The [Boost.Test framework](https://www.boost.org/doc/libs/1_71_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:
@@ -94,4 +92,4 @@ or `-p` to show a progress bar:
There are many more command line options available, information about which can be obtained
either from the command line using the `--help` switch, or online on the
[Boost.Test website](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html).
[Boost.Test website](https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/runtime_config.html).
+13 -14
View File
@@ -1,6 +1,6 @@
<div align="center">
[<img alt height="70" src="docs/named_data_theme/static/ndn-logo.svg"/>](https://named-data.net/)
[<img alt height="65" src="docs/named_data_theme/static/ndn-logo.svg"/>](https://named-data.net/)
# NFD: Named Data Networking Forwarding Daemon
@@ -13,8 +13,8 @@
## Overview
NFD is a network forwarder that implements and evolves together with the Named Data
Networking (NDN) [protocol](https://named-data.net/doc/NDN-packet-spec/current/).
NFD is a network forwarder that implements and evolves together with the Named
Data Networking (NDN) [protocol](https://docs.named-data.net/NDN-packet-spec/).
Since the initial public release in 2014, NFD has been a core component of the
[NDN Platform](https://named-data.net/codebase/platform/).
@@ -34,13 +34,12 @@ various features, some of which may eventually work into the protocol spec.
See [`docs/INSTALL.rst`](docs/INSTALL.rst) for compilation and installation instructions.
Extensive documentation is available on NFD's [homepage](https://named-data.net/doc/NFD/).
Extensive documentation is available on NFD's [homepage](https://docs.named-data.net/NFD/).
## Reporting bugs
Bug reports and feedback are highly appreciated and can be submitted through the
[NFD issue tracker](https://redmine.named-data.net/projects/nfd/issues) or the
[ndn-interest mailing list](http://www.lists.cs.ucla.edu/mailman/listinfo/ndn-interest).
Please submit any bug reports or feature requests to the
[NFD issue tracker](https://redmine.named-data.net/projects/nfd/issues).
## Contributing
@@ -50,13 +49,13 @@ it already contains significant contributions from people outside the project te
[`AUTHORS.md`](AUTHORS.md)). We strongly encourage participation from all interested parties,
since broader community support is key for NDN to succeed as a new Internet architecture.
If you are new to the NDN software community, please read [`README-dev.md`](README-dev.md)
and the [Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md)
to get started.
Contributions to NFD are greatly appreciated and can be made through our
[Gerrit code review site](https://gerrit.named-data.net/).
If you are new to the NDN software community, please read our
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md)
and [`README-dev.md`](README-dev.md) to get started.
## License
NFD is a free and open-source software package licensed under the GPL version 3 and
is the centerpiece of our committement to making NDN's core technology free and open
to all Internet users and developers. For more information about licensing, refer to
[`COPYING.md`](COPYING.md).
NFD is free software distributed under the GNU General Public License version 3.
See [`COPYING.md`](COPYING.md) for details.
+7 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -78,8 +78,6 @@ namespace nfd {
using std::size_t;
using boost::noncopyable;
using std::shared_ptr;
using std::unique_ptr;
using std::weak_ptr;
@@ -90,12 +88,13 @@ using std::static_pointer_cast;
using std::dynamic_pointer_cast;
using std::const_pointer_cast;
using std::to_string;
using namespace std::string_literals;
using namespace std::string_view_literals;
using ndn::span;
using ndn::to_string;
using boost::noncopyable;
using ndn::span;
using ndn::Block;
using ndn::Data;
using ndn::FaceUri;
@@ -113,10 +112,11 @@ using namespace ndn::tlv;
namespace lp = ndn::lp;
namespace name = ndn::name;
namespace scheduler = ndn::scheduler;
namespace signal = ndn::util::signal;
namespace signal = ndn::signal;
namespace time = ndn::time;
using namespace ndn::block_literals;
using namespace ndn::time_literals;
using ndn::operator""_block;
} // namespace nfd
+9 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -48,7 +48,7 @@ const Network&
Network::getMaxRangeV4()
{
using boost::asio::ip::address_v4;
static Network range{address_v4{}, address_v4{0xffffffff}};
static const Network range{address_v4{}, address_v4{0xffffffff}};
return range;
}
@@ -56,14 +56,14 @@ const Network&
Network::getMaxRangeV6()
{
using boost::asio::ip::address_v6;
static address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static Network range{address_v6{}, address_v6{maxV6}};
static const address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static const Network range{address_v6{}, address_v6{maxV6}};
return range;
}
bool
Network::isValidCidr(std::string_view cidr)
Network::isValidCidr(std::string_view cidr) noexcept
{
auto pos = cidr.find('/');
if (pos == std::string::npos) {
@@ -96,8 +96,8 @@ operator>>(std::istream& is, Network& network)
size_t position = networkStr.find('/');
if (position == std::string::npos) {
try {
network.m_minAddress = ip::address::from_string(networkStr);
network.m_maxAddress = ip::address::from_string(networkStr);
network.m_minAddress = ip::make_address(networkStr);
network.m_maxAddress = ip::make_address(networkStr);
}
catch (const boost::system::system_error&) {
is.setstate(std::ios::failbit);
@@ -106,7 +106,7 @@ operator>>(std::istream& is, Network& network)
}
else {
boost::system::error_code ec;
auto address = ip::address::from_string(networkStr.substr(0, position), ec);
auto address = ip::make_address(networkStr.substr(0, position), ec);
if (ec) {
is.setstate(std::ios::failbit);
return is;
+15 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,11 +27,13 @@
#define NFD_CORE_NETWORK_HPP
#include <boost/asio/ip/address.hpp>
#include <boost/operators.hpp>
#include <string_view>
namespace nfd {
class Network
class Network : private boost::equality_comparable<Network>
{
public:
Network();
@@ -40,7 +42,7 @@ public:
const boost::asio::ip::address& maxAddress);
bool
doesContain(const boost::asio::ip::address& address) const
doesContain(const boost::asio::ip::address& address) const noexcept
{
return m_minAddress <= address && address <= m_maxAddress;
}
@@ -52,29 +54,25 @@ public:
getMaxRangeV6();
static bool
isValidCidr(std::string_view cidr);
isValidCidr(std::string_view cidr) noexcept;
bool
operator==(const Network& rhs) const
private: // non-member operators
friend bool
operator==(const Network& lhs, const Network& rhs) noexcept
{
return m_minAddress == rhs.m_minAddress && m_maxAddress == rhs.m_maxAddress;
return lhs.m_minAddress == rhs.m_minAddress &&
lhs.m_maxAddress == rhs.m_maxAddress;
}
bool
operator!=(const Network& rhs) const
{
return !(*this == rhs);
}
private:
boost::asio::ip::address m_minAddress;
boost::asio::ip::address m_maxAddress;
friend std::ostream&
operator<<(std::ostream& os, const Network& network);
friend std::istream&
operator>>(std::istream& is, Network& network);
private:
boost::asio::ip::address m_minAddress;
boost::asio::ip::address m_maxAddress;
};
std::ostream&
+2 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -115,7 +115,7 @@ public: // parse helpers
auto value = node.get_value_optional<T>();
// Unsigned logic is workaround for https://redmine.named-data.net/issues/4489
if (value &&
(std::is_signed<T>() || node.get_value<std::string>().find("-") == std::string::npos)) {
(std::is_signed_v<T> || node.get_value<std::string>().find("-") == std::string::npos)) {
return *value;
}
NDN_THROW(Error("Invalid value '" + node.get_value<std::string>() +
+23 -18
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -34,15 +34,15 @@ namespace nfd {
* \brief Represents a counter that encloses an integer value.
*
* SimpleCounter is noncopyable, because increment should be called on the counter,
* not a copy of it; it's implicitly convertible to an integral type to be observed.
* not a copy of it. It's implicitly convertible to an integral type to be observed.
*/
class SimpleCounter : noncopyable
{
public:
typedef uint64_t rep;
using rep = uint64_t;
/**
* \brief Observe the counter's value.
* \brief Return the counter's value.
*/
operator rep() const noexcept
{
@@ -62,14 +62,16 @@ protected:
rep m_value = 0;
};
/** \brief Represents a counter of number of packets.
/**
* \brief Represents a counter of number of packets.
*
* \warning The counter value may wrap after exceeding the range of underlying integer type.
* \warning The counter value may wrap after exceeding the range of the underlying integer type.
*/
class PacketCounter : public SimpleCounter
{
public:
/** \brief Increment the counter by one.
/**
* \brief Increment the counter by one.
*/
PacketCounter&
operator++() noexcept
@@ -77,17 +79,18 @@ public:
++m_value;
return *this;
}
// postfix ++ operator is not provided because it's not needed
};
/** \brief Represents a counter of number of bytes.
/**
* \brief Represents a counter of number of bytes.
*
* \warning The counter value may wrap after exceeding the range of underlying integer type.
* \warning The counter value may wrap after exceeding the range of the underlying integer type.
*/
class ByteCounter : public SimpleCounter
{
public:
/** \brief Increase the counter.
/**
* \brief Increase the counter.
*/
ByteCounter&
operator+=(rep n) noexcept
@@ -97,16 +100,17 @@ public:
}
};
/** \brief Provides a counter that observes the size of a table.
* \tparam T a type that provides a size() const member function
/**
* \brief Provides a counter that observes the size of a table.
* \tparam T a type that provides a `size()` const member function
*
* if table not specified in constructor, it can be added later by invoking observe()
* If the table is not specified in the constructor, it can be added later by calling observe().
*/
template<typename T>
class SizeCounter : noncopyable
{
public:
typedef size_t Rep;
using rep = size_t;
explicit constexpr
SizeCounter(const T* table = nullptr) noexcept
@@ -120,16 +124,17 @@ public:
m_table = table;
}
/** \brief Observe the counter.
/**
* \brief Return the counter's value, i.e., the current size of the table being observed.
*/
operator Rep() const
operator rep() const
{
BOOST_ASSERT(m_table != nullptr);
return m_table->size();
}
private:
const T* m_table;
const T* m_table = nullptr;
};
} // namespace nfd
+19 -31
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2021, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,18 +27,18 @@
namespace nfd {
static thread_local unique_ptr<boost::asio::io_service> g_ioService;
static thread_local unique_ptr<boost::asio::io_context> g_ioCtx;
static thread_local unique_ptr<Scheduler> g_scheduler;
static boost::asio::io_service* g_mainIoService = nullptr;
static boost::asio::io_service* g_ribIoService = nullptr;
static boost::asio::io_context* g_mainIoCtx = nullptr;
static boost::asio::io_context* g_ribIoCtx = nullptr;
boost::asio::io_service&
boost::asio::io_context&
getGlobalIoService()
{
if (g_ioService == nullptr) {
g_ioService = make_unique<boost::asio::io_service>();
if (g_ioCtx == nullptr) {
g_ioCtx = make_unique<boost::asio::io_context>();
}
return *g_ioService;
return *g_ioCtx;
}
Scheduler&
@@ -55,46 +55,34 @@ void
resetGlobalIoService()
{
g_scheduler.reset();
g_ioService.reset();
g_ioCtx.reset();
}
#endif
boost::asio::io_service&
boost::asio::io_context&
getMainIoService()
{
BOOST_ASSERT(g_mainIoService != nullptr);
return *g_mainIoService;
BOOST_ASSERT(g_mainIoCtx != nullptr);
return *g_mainIoCtx;
}
boost::asio::io_service&
boost::asio::io_context&
getRibIoService()
{
BOOST_ASSERT(g_ribIoService != nullptr);
return *g_ribIoService;
BOOST_ASSERT(g_ribIoCtx != nullptr);
return *g_ribIoCtx;
}
void
setMainIoService(boost::asio::io_service* mainIo)
setMainIoService(boost::asio::io_context* mainIo)
{
g_mainIoService = mainIo;
g_mainIoCtx = mainIo;
}
void
setRibIoService(boost::asio::io_service* ribIo)
setRibIoService(boost::asio::io_context* ribIo)
{
g_ribIoService = ribIo;
}
void
runOnMainIoService(const std::function<void()>& f)
{
getMainIoService().post(f);
}
void
runOnRibIoService(const std::function<void()>& f)
{
getRibIoService().post(f);
g_ribIoCtx = ribIo;
}
} // namespace nfd
+14 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022 Regents of the University of California,
* Copyright (c) 2014-2023 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,46 +27,39 @@
#include "core/common.hpp"
#include <boost/asio/io_service.hpp>
#include <boost/asio/io_context.hpp>
namespace nfd {
/** \brief Returns the global io_service instance for the calling thread.
/**
* \brief Returns the global io_context instance for the calling thread.
*/
boost::asio::io_service&
boost::asio::io_context&
getGlobalIoService();
/** \brief Returns the global Scheduler instance for the calling thread.
/**
* \brief Returns the global Scheduler instance for the calling thread.
*/
Scheduler&
getScheduler();
boost::asio::io_service&
boost::asio::io_context&
getMainIoService();
boost::asio::io_service&
boost::asio::io_context&
getRibIoService();
void
setMainIoService(boost::asio::io_service* mainIo);
setMainIoService(boost::asio::io_context* 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);
setRibIoService(boost::asio::io_context* ribIo);
#ifdef NFD_WITH_TESTS
/** \brief Destroy the global io_service instance.
/**
* \brief Destroy the global io_context instance.
*
* It will be recreated at the next invocation of getGlobalIoService().
* It will be recreated at the next invocation of getGlobalIoService().
*/
void
resetGlobalIoService();
+42
View File
@@ -0,0 +1,42 @@
#include "TokenBucket.hpp"
#include "common/global.hpp"
#include "common/logger.hpp"
#include <functional>
namespace nfd {
namespace face {
NFD_LOG_INIT(QSCCPTokenBucket);
TokenBucket::TokenBucket(uint64_t rateLimit, uint64_t bucketSize, const std::string& name): rateLimit(rateLimit), bucketSize(bucketSize), name(name) {
this->eachStep = this->rateLimit / 250.0;
this->currentTokenSize = 0;
this->isStart = false;
// NFD_LOG_DEBUG("Create tokenBucket: " << name << ", eachStep: " << this->eachStep << ", rateLimit: " << this->rateLimit);
}
void TokenBucket::start() {
if (this->isStart) {
return;
}
// 每 4ms 增加一次令牌
getScheduler().schedule(time::milliseconds(4), std::bind(&TokenBucket::generateToken, this));
}
void TokenBucket::generateToken() {
// NFD_LOG_DEBUG(this->name << "=> do generateToken => " << this->currentTokenSize);
if (this->currentTokenSize + this->eachStep > this->bucketSize) {
this->currentTokenSize = this->bucketSize;
} else {
this->currentTokenSize += this->eachStep;
}
getScheduler().schedule(time::milliseconds(4), std::bind(&TokenBucket::generateToken, this));
}
bool TokenBucket::use(uint64_t tokenNum) {
if(this->currentTokenSize > tokenNum) {
this->currentTokenSize -= tokenNum;
// NFD_LOG_DEBUG(this->name << "=> use success => " << this->currentTokenSize);
return true;
} else {
// NFD_LOG_DEBUG(this->name << "=> use failed => " << this->currentTokenSize);
return false;
}
}
}
}
+34
View File
@@ -0,0 +1,34 @@
//
// Created by gdcni21 on 3/25/22.
//
#ifndef NS_TOKENBUCKET_H
#define NS_TOKENBUCKET_H
#include <memory>
#include <string>
namespace nfd {
namespace face {
class TokenBucket {
public:
explicit TokenBucket(uint64_t rateLimit, uint64_t bucketSize, const std::string& name);
void start();
/**
* 周期性增加token
**/
void generateToken();
/**
* 尝试消费n个token
* @param tokenNum
* @return
*/
bool use(uint64_t tokenNum);
public:
double eachStep; // 每个周期增加的令牌
double currentTokenSize; // 当前令牌数
uint64_t rateLimit; // 令牌生成速率
uint64_t bucketSize; // 令牌桶容量
std::string name;
bool isStart; // 标识是否启动
};
}
}
#endif //NS_TOKENBUCKET_H
+8 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,13 +32,15 @@
#include <array>
#include <boost/asio/defer.hpp>
namespace nfd::face {
struct Unicast {};
struct Multicast {};
/**
* \brief Implements Transport for datagram-based protocols.
* \brief Implements a Transport for datagram-based protocols.
*
* \tparam Protocol A datagram-based protocol in Boost.Asio
* \tparam Addressing The addressing mode, either Unicast or Multicast
@@ -50,9 +52,10 @@ public:
using protocol = Protocol;
using addressing = Addressing;
/** \brief Construct datagram transport.
/**
* \brief Construct datagram transport.
*
* \param socket Protocol-specific socket for the created transport
* \param socket Protocol-specific socket for the created transport
*/
explicit
DatagramTransport(typename protocol::socket&& socket);
@@ -149,7 +152,7 @@ DatagramTransport<T, U>::doClose()
// Ensure that the Transport stays alive at least until
// all pending handlers are dispatched
getGlobalIoService().post([this] {
boost::asio::defer(getGlobalIoService(), [this] {
this->setState(TransportState::CLOSED);
});
}
+4 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -101,8 +101,9 @@ void
EthernetChannel::asyncRead(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
{
m_socket.async_read_some(boost::asio::null_buffers(),
[=] (const auto& e, auto) { this->handleRead(e, onFaceCreated, onReceiveFailed); });
m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read, [=] (const auto& e) {
handleRead(e, onFaceCreated, onReceiveFailed);
});
}
void
+8 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -36,13 +36,13 @@
namespace nfd::face {
/**
* \brief Class implementing Ethernet-based channel to create faces
* \brief Class implementing an Ethernet-based channel to create faces.
*/
class EthernetChannel final : public Channel
{
public:
/**
* \brief EthernetChannel-related error
* \brief EthernetChannel-related error.
*/
class Error : public std::runtime_error
{
@@ -51,10 +51,10 @@ public:
};
/**
* \brief Create an Ethernet channel on the given \p localEndpoint (network interface)
* \brief Create an Ethernet channel on the given \p localEndpoint (network interface).
*
* To enable creation of faces upon incoming connections,
* one needs to explicitly call EthernetChannel::listen method.
* To enable the creation of faces upon incoming connections, one needs to
* explicitly call listen().
*/
EthernetChannel(shared_ptr<const ndn::net::NetworkInterface> localEndpoint,
time::nanoseconds idleTimeout);
@@ -72,7 +72,7 @@ public:
}
/**
* \brief Create a unicast Ethernet face toward \p remoteEndpoint
* \brief Create a unicast Ethernet face toward \p remoteEndpoint.
*/
void
connect(const ethernet::Address& remoteEndpoint,
@@ -81,7 +81,7 @@ public:
const FaceCreationFailedCallback& onConnectFailed);
/**
* \brief Start listening
* \brief Start listening.
*
* Enable listening on the local endpoint, waiting for incoming frames,
* and creating a face when a frame is received from a new remote host.
+32 -29
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -46,8 +46,8 @@ EthernetFactory::EthernetFactory(const CtorParams& params)
: ProtocolFactory(params)
{
m_netifAddConn = netmon->onInterfaceAdded.connect([this] (const auto& netif) {
this->applyUnicastConfigToNetif(netif);
this->applyMcastConfigToNetif(*netif);
applyUnicastConfigToNetif(netif);
applyMcastConfigToNetif(*netif);
});
}
@@ -156,11 +156,11 @@ EthernetFactory::doProcessConfig(OptionalConfigSection configSection,
}
}
// Even if there's no configuration change, we still need to re-apply configuration because
// netifs may have changed.
m_unicastConfig = unicastConfig;
m_mcastConfig = mcastConfig;
this->applyConfig(context);
// Even if there are no configuration changes, we still need to re-apply
// the configuration because netifs may have changed.
m_unicastConfig = std::move(unicastConfig);
m_mcastConfig = std::move(mcastConfig);
applyConfig(context);
}
void
@@ -169,13 +169,13 @@ EthernetFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (!req.localUri || req.localUri->getScheme() != "dev") {
NFD_LOG_TRACE("Cannot create unicast Ethernet face without dev:// LocalUri");
NFD_LOG_TRACE("createFace: dev:// LocalUri required");
onFailure(406, "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing Ethernet faces do not support on-demand persistency");
return;
}
@@ -184,14 +184,14 @@ EthernetFactory::doCreateFace(const CreateFaceRequest& req,
std::string localEndpoint(req.localUri->getHost());
if (remoteEndpoint.isMulticast()) {
NFD_LOG_TRACE("createFace does not support multicast faces");
NFD_LOG_TRACE("createFace: unsupported multicast endpoint");
onFailure(406, "Cannot create multicast Ethernet faces");
return;
}
if (req.params.wantLocalFields) {
// Ethernet faces are never local
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -257,7 +257,9 @@ EthernetFactory::createMulticastFace(const ndn::net::NetworkInterface& netif,
connectFaceClosedSignal(*face, [this, key] { m_mcastFaces.erase(key); });
auto channelIt = m_channels.find(netif.getName());
face->setChannel(channelIt != m_channels.end() ? channelIt->second : nullptr);
if (channelIt != m_channels.end()) {
face->setChannel(channelIt->second);
}
return face;
}
@@ -269,13 +271,13 @@ EthernetFactory::applyUnicastConfigToNetif(const shared_ptr<const ndn::net::Netw
return nullptr;
}
if (netif->getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": incompatible netif type");
if (!netif->isUp()) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": netif is down");
return nullptr;
}
if (!netif->isUp()) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": netif is down");
if (netif->getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": incompatible netif type");
return nullptr;
}
@@ -303,18 +305,13 @@ EthernetFactory::applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif
return nullptr;
}
if (netif.getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": incompatible netif type");
return nullptr;
}
if (!netif.isUp()) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif is down");
return nullptr;
}
if (!netif.canMulticast()) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif cannot multicast");
if (netif.getType() != ndn::net::InterfaceType::ETHERNET) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": incompatible netif type");
return nullptr;
}
@@ -323,6 +320,11 @@ EthernetFactory::applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif
return nullptr;
}
if (!netif.canMulticast()) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif cannot multicast");
return nullptr;
}
if (!m_mcastConfig.netifPredicate(netif)) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": rejected by whitelist/blacklist");
return nullptr;
@@ -331,17 +333,18 @@ EthernetFactory::applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif
NFD_LOG_DEBUG("Creating multicast face on " << netif.getName());
shared_ptr<Face> face;
try {
face = this->createMulticastFace(netif, m_mcastConfig.group);
face = createMulticastFace(netif, m_mcastConfig.group);
}
catch (const EthernetTransport::Error& e) {
catch (const std::runtime_error& e) {
NFD_LOG_WARN("Cannot create multicast face on " << netif.getName() << ": " << e.what());
return nullptr;
return nullptr; // not a fatal error
}
if (face->getId() == INVALID_FACEID) {
// new face: register with forwarding
this->addFace(face);
}
return face;
}
@@ -361,9 +364,9 @@ EthernetFactory::applyConfig(const FaceSystem::ConfigContext&)
// create channels and multicast faces if requested by config
for (const auto& netif : netmon->listNetworkInterfaces()) {
this->applyUnicastConfigToNetif(netif);
applyUnicastConfigToNetif(netif);
auto face = this->applyMcastConfigToNetif(*netif);
auto face = applyMcastConfigToNetif(*netif);
if (face != nullptr) {
// don't destroy face
oldFaces.erase(face);
+14 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,10 +28,12 @@
#include "protocol-factory.hpp"
#include "ethernet-channel.hpp"
#include "network-predicate.hpp"
namespace nfd::face {
/** \brief Protocol factory for Ethernet.
/**
* \brief Protocol factory for Ethernet.
*/
class EthernetFactory final : public ProtocolFactory
{
@@ -48,7 +50,7 @@ public:
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
* \return always a valid pointer to a EthernetChannel object, an exception
* \return Always a valid pointer to a EthernetChannel object, an exception
* is thrown if it cannot be created.
* \throw PcapHelper::Error channel creation failed
*/
@@ -65,7 +67,7 @@ public:
* \param localEndpoint local network interface
* \param group multicast group address
*
* \throw EthernetTransport::Error transport creation fails
* \throw std::runtime_error %Face creation failed
*/
shared_ptr<Face>
createMulticastFace(const ndn::net::NetworkInterface& localEndpoint,
@@ -84,14 +86,16 @@ private:
std::vector<shared_ptr<const Channel>>
doGetChannels() const final;
/** \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
* \return new or existing channel, or nullptr if no channel should be created
/**
* \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
* \return New or existing channel, or nullptr if no channel should be created.
*/
shared_ptr<EthernetChannel>
applyUnicastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
/** \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
* \return new or existing face, or nullptr if no face should be created
/**
* \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
* \return New or existing face, or nullptr if no face should be created.
*/
shared_ptr<Face>
applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif);
@@ -100,7 +104,8 @@ private:
applyConfig(const FaceSystem::ConfigContext& context);
private:
std::map<std::string, shared_ptr<EthernetChannel>> m_channels; ///< ifname => channel
// ifname => channel
std::map<std::string, shared_ptr<EthernetChannel>> m_channels;
struct UnicastConfig
{
+5 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,6 +29,7 @@
#include <pcap/pcap.h>
#include <boost/asio/defer.hpp>
#include <boost/endian/conversion.hpp>
namespace nfd::face {
@@ -87,7 +88,7 @@ EthernetTransport::doClose()
// Ensure that the Transport stays alive at least
// until all pending handlers are dispatched
getGlobalIoService().post([this] {
boost::asio::defer(getGlobalIoService(), [this] {
this->setState(TransportState::CLOSED);
});
}
@@ -146,8 +147,8 @@ EthernetTransport::sendPacket(const ndn::Block& block)
void
EthernetTransport::asyncRead()
{
m_socket.async_read_some(boost::asio::null_buffers(),
[this] (const auto& e, auto) { this->handleRead(e); });
m_socket.async_wait(boost::asio::posix::stream_descriptor::wait_read,
[this] (const auto& e) { this->handleRead(e); });
}
void
+4 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -36,7 +36,7 @@
namespace nfd::face {
/**
* @brief Base class for Ethernet-based Transports
* @brief Base class for Ethernet-based Transports.
*/
class EthernetTransport : public Transport
{
@@ -48,7 +48,7 @@ public:
};
/**
* @brief Processes the payload of an incoming frame
* @brief Processes the payload of an incoming frame.
* @param payload Payload bytes, starting from the first byte after the Ethernet header
* @param sender Sender address
*/
@@ -82,7 +82,7 @@ private:
doSend(const Block& packet) final;
/**
* @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
* @brief Sends the specified TLV block on the network wrapped in an Ethernet frame.
*/
void
sendPacket(const ndn::Block& block);
+4 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,9 +24,8 @@
*/
#include "face-system.hpp"
#include "protocol-factory.hpp"
#include "netdev-bound.hpp"
#include "common/global.hpp"
#include "protocol-factory.hpp"
#include "fw/face-table.hpp"
namespace nfd::face {
@@ -71,14 +70,14 @@ FaceSystem::listProtocolFactories() const
}
ProtocolFactory*
FaceSystem::getFactoryById(const std::string& id)
FaceSystem::getFactoryById(const std::string& id) const
{
auto found = m_factories.find(id);
return found == m_factories.end() ? nullptr : found->second.get();
}
ProtocolFactory*
FaceSystem::getFactoryByScheme(const std::string& scheme)
FaceSystem::getFactoryByScheme(const std::string& scheme) const
{
auto found = m_factoryByScheme.find(scheme);
return found == m_factoryByScheme.end() ? nullptr : found->second;
+7 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,7 +26,6 @@
#ifndef NFD_DAEMON_FACE_FACE_SYSTEM_HPP
#define NFD_DAEMON_FACE_FACE_SYSTEM_HPP
#include "network-predicate.hpp"
#include "common/config-file.hpp"
#include <ndn-cxx/net/network-address.hpp>
@@ -62,15 +61,17 @@ public:
[[nodiscard]] std::set<const ProtocolFactory*>
listProtocolFactories() const;
/** \return ProtocolFactory for the specified registered factory id or nullptr if not found.
/**
* \return ProtocolFactory for the specified registered factory id or nullptr if not found.
*/
ProtocolFactory*
getFactoryById(const std::string& id);
getFactoryById(const std::string& id) const;
/** \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found.
/**
* \return ProtocolFactory for the specified FaceUri scheme or nullptr if not found.
*/
ProtocolFactory*
getFactoryByScheme(const std::string& scheme);
getFactoryByScheme(const std::string& scheme) const;
bool
hasFactoryForScheme(const std::string& scheme) const;
+65 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,7 +24,8 @@
*/
#include "generic-link-service.hpp"
#include <iostream>
#include <ndn-cxx/lp/fields.hpp>
#include <ndn-cxx/lp/pit-token.hpp>
#include <ndn-cxx/lp/tags.hpp>
@@ -46,10 +47,41 @@ GenericLinkService::GenericLinkService(const GenericLinkService::Options& option
, m_lastSeqNo(-2)
, m_nextMarkTime(time::steady_clock::time_point::max())
, m_nMarkedSinceInMarkingState(0)
, globalSp(options.C * 0.99, options.vqSize)
{
m_reassembler.beforeTimeout.connect([this] (auto&&...) { ++nReassemblyTimeouts; });
m_reliability.onDroppedInterest.connect([this] (const auto& i) { notifyDroppedInterest(i); });
nReassembling.observe(&m_reassembler);
this->sendPacketCallback = [this](std::shared_ptr<VirtualQueueItem> taskPtr) {
if (taskPtr != nullptr) {
const Block &block = taskPtr->item->wireEncode();
// std::cout << "interest wireEncode size: " << block.size() << std::endl;
lp::Packet lpPacket(block);
// std::cout << "Interest lppacket size before encode lp fields: " << lpPacket.wireEncode().size() << std::endl;
encodeLpFields(*(taskPtr->item), lpPacket);
// std::cout << "Interest lppacket size after encode lp fields: " << lpPacket.wireEncode().size() << std::endl;
this->sendNetPacket(std::move(lpPacket), true);
// lp::Packet lpPacket(taskPtr->item->wireEncode());
// encodeLpFields(*(taskPtr->item), lpPacket);
// this->sendNetPacket(std::move(lpPacket), taskPtr->endpointId, true);
}
// 得到下一个需要调度的包
auto newTaskPtr = this->globalSp.scheduleNext();
if (newTaskPtr == nullptr) {
//NFD_LOG_ERROR("FUCK");
// 如果没有可调度的包,则 1 ms 之后再调度
this->canScheduler = true;
// getScheduler().schedule(time::milliseconds(1), std::bind(this->sendPacketCallback, nullptr));
} else {
// 等待足够的 token 再发送
this->canScheduler = false;
// NFD_LOG_DEBUG("Route waitTime: " << newTaskPtr->waitNsTime);
getScheduler().schedule(time::nanoseconds((uint32_t)(newTaskPtr->waitNsTime)),
std::bind(this->sendPacketCallback, newTaskPtr));
}
};
// getScheduler().schedule(time::nanoseconds(0), std::bind(this->sendPacketCallback, nullptr));
}
void
@@ -114,19 +146,46 @@ GenericLinkService::sendLpPacket(lp::Packet&& pkt)
void
GenericLinkService::doSendInterest(const Interest& interest)
{
lp::Packet lpPacket(interest.wireEncode());
if (interest.getName().getPrefix(1).toUri() == "/localhost") {
const Block &block = interest.wireEncode();
// // std::cout << "interest wireEncode size: " << block.size() << std::endl;
lp::Packet lpPacket(block);
// // std::cout << "lppacket size before encode lp fields: " << lpPacket.wireEncode().size() << std::endl;
encodeLpFields(interest, lpPacket);
// // std::cout << "lppacket size after encode lp fields: " << lpPacket.wireEncode().size() << std::endl;
this->sendNetPacket(std::move(lpPacket), true);
} else {
this->globalSp.appendInterest(interest);
if (this->canScheduler) {
this->sendPacketCallback(nullptr);
}
//if (!success) {
// // send Nack
// lp::Nack nack(interest);
// nack.setReason(lp::NackReason::CONGESTION);
// if (this->nwfq.canMark(nack)) {
// // 拥塞标记
// nack.getInterest().setTag(make_shared<lp::CongestionMarkTag>(1));
// }
// this->receiveNack(nack, endpointId);
//}
}
// lp::Packet lpPacket(interest.wireEncode());
encodeLpFields(interest, lpPacket);
// encodeLpFields(interest, lpPacket);
this->sendNetPacket(std::move(lpPacket), true);
// this->sendNetPacket(std::move(lpPacket), true);
}
void
GenericLinkService::doSendData(const Data& data)
{
// const Block& block = data.wireEncode();
// std::cout << "Data wireEncode size: " << block.size() << std::endl;
lp::Packet lpPacket(data.wireEncode());
// std::cout << "Data before encode LpFields size: " << lpPacket.wireEncode().size() << std::endl;
encodeLpFields(data, lpPacket);
// std::cout << "Data After encode LpFields size: " << lpPacket.wireEncode().size() << std::endl;
this->sendNetPacket(std::move(lpPacket), false);
}
+8
View File
@@ -30,6 +30,7 @@
#include "lp-fragmenter.hpp"
#include "lp-reassembler.hpp"
#include "lp-reliability.hpp"
#include "queues.hpp"
namespace nfd::face {
@@ -164,6 +165,9 @@ public:
* being set with canOverrideMtuTo().
*/
ssize_t overrideMtu = std::numeric_limits<ssize_t>::max();
uint64_t C = 10000000;
size_t vqSize = 20;
};
/** \brief %Counters provided by GenericLinkService.
@@ -316,6 +320,10 @@ NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/// number of marked packets in the current incident of congestion
size_t m_nMarkedSinceInMarkingState;
GlobalSP globalSp;
bool canScheduler = true;
std::function<void(std::shared_ptr<VirtualQueueItem>)> sendPacketCallback;
friend LpReliability;
};
+5 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,6 +26,8 @@
#include "internal-transport.hpp"
#include "common/global.hpp"
#include <boost/asio/post.hpp>
namespace nfd::face {
NFD_LOG_MEMBER_INIT(InternalForwarderTransport, InternalForwarderTransport);
@@ -47,7 +49,7 @@ InternalForwarderTransport::InternalForwarderTransport(const FaceUri& localUri,
void
InternalForwarderTransport::receivePacket(const Block& packet)
{
getGlobalIoService().post([this, packet] {
boost::asio::post(getGlobalIoService(), [this, packet] {
NFD_LOG_FACE_TRACE("Received: " << packet.size() << " bytes");
receive(packet);
});
@@ -105,7 +107,7 @@ InternalClientTransport::connectToForwarder(InternalForwarderTransport* forwarde
void
InternalClientTransport::receivePacket(const Block& packet)
{
getGlobalIoService().post([this, packet] {
boost::asio::post(getGlobalIoService(), [this, packet] {
NFD_LOG_TRACE("Received: " << packet.size() << " bytes");
if (m_receiveCallback) {
m_receiveCallback(packet);
+11 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,19 +32,21 @@
namespace nfd::face {
/** \brief Abstracts a transport that can be paired with another.
/**
* \brief Abstracts a transport that can be paired with another.
*/
class InternalTransportBase
{
public:
virtual
~InternalTransportBase() = default;
virtual void
receivePacket(const Block& packet) = 0;
protected:
~InternalTransportBase() = default;
};
/** \brief Implements a forwarder-side transport that can be paired with another transport.
/**
* \brief Implements a forwarder-side transport that can be paired with another transport.
*/
class InternalForwarderTransport final : public Transport, public InternalTransportBase
{
@@ -56,7 +58,7 @@ public:
ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_POINT_TO_POINT);
void
setPeer(InternalTransportBase* peer)
setPeer(InternalTransportBase* peer) noexcept
{
m_peer = peer;
}
@@ -78,7 +80,8 @@ private:
InternalTransportBase* m_peer = nullptr;
};
/** \brief Implements a client-side transport that can be paired with an InternalForwarderTransport.
/**
* \brief Implements a client-side transport that can be paired with an InternalForwarderTransport.
*/
class InternalClientTransport final : public ndn::Transport, public InternalTransportBase
{
+2 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,7 +26,7 @@
#include "lp-fragmenter.hpp"
#include "link-service.hpp"
#include <ndn-cxx/encoding/tlv.hpp>
#include <ndn-cxx/lp/fields.hpp>
namespace nfd::face {
+4 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,8 +24,10 @@
*/
#include "lp-reassembler.hpp"
#include "link-service.hpp"
#include "common/global.hpp"
#include "link-service.hpp"
#include <ndn-cxx/lp/fields.hpp>
#include <numeric>
+2 -1
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -29,6 +29,7 @@
#include "face-common.hpp"
#include <ndn-cxx/lp/packet.hpp>
#include <ndn-cxx/lp/sequence.hpp>
namespace nfd::face {
+4 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,9 +24,11 @@
*/
#include "lp-reliability.hpp"
#include "common/global.hpp"
#include "generic-link-service.hpp"
#include "transport.hpp"
#include "common/global.hpp"
#include <ndn-cxx/lp/fields.hpp>
namespace nfd::face {
+2 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -103,8 +103,7 @@ MulticastEthernetTransport::joinMulticastGroup()
#if defined(__APPLE__) || defined(__FreeBSD__)
// see bug #2327
using boost::asio::ip::udp;
udp::socket sock(getGlobalIoService(), udp::v4());
boost::asio::ip::udp::socket sock(getGlobalIoService(), boost::asio::ip::udp::v4());
int fd = sock.native_handle();
// Differences between Linux and the BSDs (including macOS):
+4 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,13 +31,13 @@
namespace nfd::face {
/**
* @brief A multicast Transport that uses raw Ethernet II frames
* @brief A multicast Transport that uses raw Ethernet II frames.
*/
class MulticastEthernetTransport final : public EthernetTransport
{
public:
/**
* @brief Creates an Ethernet-based transport for multicast communication
* @brief Creates an Ethernet-based transport for multicast communication.
*/
MulticastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
const ethernet::Address& mcastAddress,
@@ -45,7 +45,7 @@ public:
private:
/**
* @brief Enables receiving frames addressed to our MAC multicast group
* @brief Enables receiving frames addressed to our MAC multicast group.
*/
void
joinMulticastGroup();
+22 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -40,11 +40,13 @@
namespace nfd::face {
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>), MulticastUdpTransport);
namespace ip = boost::asio::ip;
MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
protocol::socket&& sendSocket,
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<ip::udp, Multicast>), MulticastUdpTransport);
MulticastUdpTransport::MulticastUdpTransport(const ip::udp::endpoint& multicastGroup,
ip::udp::socket&& recvSocket,
ip::udp::socket&& sendSocket,
ndn::nfd::LinkType linkType)
: DatagramTransport(std::move(recvSocket))
, m_multicastGroup(multicastGroup)
@@ -57,7 +59,7 @@ MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& multicast
this->setLinkType(linkType);
this->setMtu(udp::computeMtu(m_sendSocket.local_endpoint()));
protocol::socket::send_buffer_size sendBufferSizeOption;
boost::asio::socket_base::send_buffer_size sendBufferSizeOption;
boost::system::error_code error;
m_sendSocket.get_option(sendBufferSizeOption);
if (error) {
@@ -131,27 +133,26 @@ bindToDevice(int fd, const std::string& ifname)
}
void
MulticastUdpTransport::openRxSocket(protocol::socket& sock,
const protocol::endpoint& multicastGroup,
const boost::asio::ip::address& localAddress,
MulticastUdpTransport::openRxSocket(ip::udp::socket& sock,
const ip::udp::endpoint& multicastGroup,
const ip::address& localAddress,
const ndn::net::NetworkInterface* netif)
{
BOOST_ASSERT(!sock.is_open());
sock.open(multicastGroup.protocol());
sock.set_option(protocol::socket::reuse_address(true));
sock.set_option(boost::asio::socket_base::reuse_address(true));
if (multicastGroup.address().is_v4()) {
BOOST_ASSERT(localAddress.is_v4());
sock.bind(multicastGroup);
sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v4(),
localAddress.to_v4()));
sock.set_option(ip::multicast::join_group(multicastGroup.address().to_v4(), localAddress.to_v4()));
}
else {
BOOST_ASSERT(multicastGroup.address().to_v6().scope_id() != 0);
sock.set_option(boost::asio::ip::v6_only(true));
sock.set_option(ip::v6_only(true));
sock.bind(multicastGroup);
sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v6()));
sock.set_option(ip::multicast::join_group(multicastGroup.address().to_v6()));
}
if (netif)
@@ -159,27 +160,27 @@ MulticastUdpTransport::openRxSocket(protocol::socket& sock,
}
void
MulticastUdpTransport::openTxSocket(protocol::socket& sock,
const protocol::endpoint& localEndpoint,
MulticastUdpTransport::openTxSocket(ip::udp::socket& sock,
const ip::udp::endpoint& localEndpoint,
const ndn::net::NetworkInterface* netif,
bool enableLoopback)
{
BOOST_ASSERT(!sock.is_open());
sock.open(localEndpoint.protocol());
sock.set_option(protocol::socket::reuse_address(true));
sock.set_option(boost::asio::ip::multicast::enable_loopback(enableLoopback));
sock.set_option(boost::asio::socket_base::reuse_address(true));
sock.set_option(ip::multicast::enable_loopback(enableLoopback));
if (localEndpoint.address().is_v4()) {
sock.bind(localEndpoint);
if (!localEndpoint.address().is_unspecified())
sock.set_option(boost::asio::ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
sock.set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
}
else {
sock.set_option(boost::asio::ip::v6_only(true));
sock.set_option(ip::v6_only(true));
sock.bind(localEndpoint);
if (netif)
sock.set_option(boost::asio::ip::multicast::outbound_interface(netif->getIndex()));
sock.set_option(ip::multicast::outbound_interface(netif->getIndex()));
}
}
+14 -14
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -36,7 +36,7 @@ namespace nfd::face {
NFD_LOG_MEMBER_DECL_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>));
/**
* \brief A Transport that communicates on a UDP multicast group
* \brief A Transport that communicates on a UDP multicast group.
*/
class MulticastUdpTransport final : public DatagramTransport<boost::asio::ip::udp, Multicast>
{
@@ -48,35 +48,35 @@ public:
};
/**
* \brief Creates a UDP-based transport for multicast communication
* \brief Creates a UDP-based transport for multicast communication.
* \param multicastGroup multicast group
* \param recvSocket socket used to receive multicast packets
* \param sendSocket socket used to send to the multicast group
* \param linkType either `ndn::nfd::LINK_TYPE_MULTI_ACCESS` or `ndn::nfd::LINK_TYPE_AD_HOC`
*/
MulticastUdpTransport(const protocol::endpoint& multicastGroup,
protocol::socket&& recvSocket,
protocol::socket&& sendSocket,
MulticastUdpTransport(const boost::asio::ip::udp::endpoint& multicastGroup,
boost::asio::ip::udp::socket&& recvSocket,
boost::asio::ip::udp::socket&& sendSocket,
ndn::nfd::LinkType linkType);
ssize_t
getSendQueueLength() final;
/**
* \brief Opens and configures the receive-side socket
* \brief Opens and configures the receive-side socket.
*/
static void
openRxSocket(protocol::socket& sock,
const protocol::endpoint& multicastGroup,
openRxSocket(boost::asio::ip::udp::socket& sock,
const boost::asio::ip::udp::endpoint& multicastGroup,
const boost::asio::ip::address& localAddress = {},
const ndn::net::NetworkInterface* netif = nullptr);
/**
* \brief Opens and configures the transmit-side socket
* \brief Opens and configures the transmit-side socket.
*/
static void
openTxSocket(protocol::socket& sock,
const protocol::endpoint& localEndpoint,
openTxSocket(boost::asio::ip::udp::socket& sock,
const boost::asio::ip::udp::endpoint& localEndpoint,
const ndn::net::NetworkInterface* netif = nullptr,
bool enableLoopback = false);
@@ -88,8 +88,8 @@ private:
doClose() final;
private:
protocol::endpoint m_multicastGroup;
protocol::socket m_sendSocket;
boost::asio::ip::udp::endpoint m_multicastGroup;
boost::asio::ip::udp::socket m_sendSocket;
};
} // namespace nfd::face
+2 -1
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, 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_NETDEV_BOUND_HPP
#define NFD_DAEMON_FACE_NETDEV_BOUND_HPP
#include "network-predicate.hpp"
#include "protocol-factory.hpp"
namespace nfd::face {
+1 -10
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -38,8 +38,6 @@ NetworkPredicateBase::NetworkPredicateBase()
this->clear();
}
NetworkPredicateBase::~NetworkPredicateBase() = default;
void
NetworkPredicateBase::clear()
{
@@ -163,13 +161,6 @@ IpAddressPredicate::isRuleValid(const std::string& key, const std::string& value
}
}
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)
{
+32 -15
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,21 +28,20 @@
#include "core/common.hpp"
#include <boost/operators.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <ndn-cxx/net/network-interface.hpp>
namespace nfd::face {
class NetworkPredicateBase
class NetworkPredicateBase : private boost::equality_comparable<NetworkPredicateBase>
{
public:
NetworkPredicateBase();
virtual
~NetworkPredicateBase();
/**
* \brief Set the whitelist to "*" and clear the blacklist
* \brief Set the whitelist to "*" and clear the blacklist.
*/
void
clear();
@@ -57,14 +56,24 @@ public:
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;
protected:
// Explicitly declare the following four special member functions
// to avoid -Wdeprecated-copy-with-dtor warnings from clang.
bool
operator!=(const NetworkPredicateBase& other) const
{
return !this->operator==(other);
}
NetworkPredicateBase(const NetworkPredicateBase&) = delete;
NetworkPredicateBase(NetworkPredicateBase&&) = default;
NetworkPredicateBase&
operator=(const NetworkPredicateBase&) = delete;
NetworkPredicateBase&
operator=(NetworkPredicateBase&&) = default;
// NetworkPredicateBase is not supposed to be used polymorphically, so we make the destructor
// protected to prevent deletion of derived objects through a pointer to the base class,
// which would be UB when the destructor is non-virtual.
~NetworkPredicateBase() = default;
private:
virtual bool
@@ -79,6 +88,14 @@ private:
void
parseList(std::set<std::string>& set, std::initializer_list<std::pair<std::string, std::string>> list);
private: // non-member operators (hidden friends)
friend bool
operator==(const NetworkPredicateBase& lhs, const NetworkPredicateBase& rhs)
{
return lhs.m_whitelist == rhs.m_whitelist &&
lhs.m_blacklist == rhs.m_blacklist;
}
NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
std::set<std::string> m_whitelist;
std::set<std::string> m_blacklist;
@@ -94,7 +111,7 @@ NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
* 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
class NetworkInterfacePredicate final : public NetworkPredicateBase
{
public:
bool
@@ -116,7 +133,7 @@ private:
* 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
class IpAddressPredicate final : public NetworkPredicateBase
{
public:
bool
+505
View File
@@ -0,0 +1,505 @@
#include "queues.hpp"
#include "common/global.hpp"
#include <ndn-cxx/encoding/estimator.hpp>
namespace nfd
{
namespace face
{
NFD_LOG_INIT(QSCCPQueue);
bool VirtualQueue::push(int seq, const std::shared_ptr<const Interest> &interest,
uint64_t dataSize, bool needInsert)
{
this->recvBits += dataSize;
if (!needInsert)
{
return false;
}
if (this->currentSize >= this->size)
{
return false;
}
this->lastSeq = seq;
VirtualQueueItem vqi;
vqi.seq = seq;
vqi.item = interest;
vqi.queue = shared_from_this();
vqi.dataSize = dataSize;
this->innerQueue.push_back(vqi);
this->currentSize++;
auto serviceClass = interest->getServiceClass();
if (serviceClass && *serviceClass > 7)
{
this->penaltyFactor = 0.5;
}
return true;
}
WDRRQueue::WDRRQueue(uint32_t rateLimit, uint32_t availableBandwidth, double weight, const std::string &name,
uint32_t tos, size_t vqSize) : availableBandwidth(availableBandwidth),
weight(weight), name(name), tos(tos), vqSize(vqSize)
{
if (rateLimit > 0)
{
this->needRateLimit = true;
this->tokenBucket = std::make_shared<TokenBucket>(rateLimit, 20 * 1000 * 8, name);
this->tokenBucket->start();
}
else
{
this->needRateLimit = false;
}
}
void WDRRQueue::updateAvailableBandwidth(uint32_t C)
{
this->availableBandwidth = C;
}
bool WDRRQueue::appendInterest(const Interest &interest)
{
std::string key = interest.getName().getPrefix(1).toUri();
if (this->virtualQueues.count(key) == 0)
{
this->virtualQueues[key] = std::make_shared<VirtualQueue>(1, this->vqSize);
this->virtualQueues[key]->tos = this->tos;
this->flows.push_back(key);
this->totalWeight += 1;
for (auto &item : this->virtualQueues)
{
item.second->objectRate = this->availableBandwidth * item.second->weight / this->totalWeight;
item.second->objectRate = item.second->objectRate * item.second->penaltyFactor;
}
}
bool needInsert = true;
if (this->cdt > 0 && this->currentPacketNum >= this->cdt)
{
needInsert = false;
}
uint64_t dataSize = 9000;
auto dsz = interest.getDsz();
if (dsz)
{
dataSize = *dsz;
}
this->recvBits += dataSize;
auto success = this->virtualQueues[key]->push(0, interest.shared_from_this(), dataSize, needInsert);
if (success)
{
this->currentPacketNum++;
}
return success;
}
std::shared_ptr<VirtualQueueItem> WDRRQueue::scheduleNext()
{
if (this->nextScheduleQueue >= this->flows.size())
{
for (auto &key : this->flows)
{
if (this->virtualQueues.count(key) == 0)
{
continue;
}
auto &item = this->virtualQueues[key];
item->balance += item->weight * item->penaltyFactor * this->MTU_QUANTA;
}
this->nextScheduleQueue = 0;
}
std::shared_ptr<VirtualQueue> selectedVQ = nullptr;
for (; this->nextScheduleQueue < this->flows.size(); this->nextScheduleQueue++)
{
auto &item = this->virtualQueues[this->flows[this->nextScheduleQueue]];
if (item->empty())
{
item->balance = 0;
continue;
}
if (item->front().dataSize < item->balance)
{
selectedVQ = item;
break;
}
if (item->len() > 10)
{
}
}
if (selectedVQ == nullptr && this->currentPacketNum > 0)
{
return scheduleNext();
}
if (selectedVQ != nullptr)
{
if (needRateLimit && !this->tokenBucket->use(selectedVQ->front().dataSize))
{
return nullptr;
}
auto item = std::make_shared<VirtualQueueItem>(selectedVQ->front());
selectedVQ->balance -= item->dataSize;
selectedVQ->pop();
if (selectedVQ->penaltyFactor < 0.9)
{
item->item->setServiceClass(selectedVQ->tos + 8);
}
this->sendBits += item->dataSize;
this->currentPacketNum--;
return item;
}
return nullptr;
}
uint32_t WDRRQueue::calObjectRate(bool getCurrentRateOnly)
{
uint32_t currentRate = this->recvBits * 1000 / this->calObjectRateInterval;
uint32_t currentSendRate = this->sendBits * 1000 / this->calObjectRateInterval;
if (getCurrentRateOnly)
{
return currentRate;
}
bool hasCleanFlow = false;
for (auto it = this->virtualQueues.begin(); it != this->virtualQueues.end();)
{
if (it->second->recvBits == 0 && it->second->empty())
{
this->totalWeight -= it->second->weight;
this->virtualQueues.erase(it++); // here is the key
hasCleanFlow = true;
}
else
{
it++;
}
}
if (hasCleanFlow)
{
this->flows.resize(this->virtualQueues.size());
int idx = 0;
for (auto it = this->virtualQueues.begin(); it != this->virtualQueues.end(); it++, idx++)
{
this->flows[idx] = it->first;
}
}
double totalHightSpeedFlowWeight = 0;
int hightSppedFlowNum = 0;
uint32_t consumeRate = 0;
double totalWeightThisTerm = 0;
for (auto &item : this->virtualQueues)
{
totalWeightThisTerm += (item.second->weight * item.second->penaltyFactor);
}
for (auto &item : this->virtualQueues)
{
item.second->objectRate = this->availableBandwidth * item.second->weight * item.second->penaltyFactor / totalWeightThisTerm;
item.second->currentFlowRate = item.second->recvBits * 1000 / this->calObjectRateInterval;
item.second->currentRatio = item.second->currentFlowRate * 1.0 / item.second->objectRate;
auto targetHighFlowRate = (item.second->objectRate - 500000) * 1.0 / item.second->objectRate;
if (item.second->currentRatio > targetHighFlowRate)
{
if (item.second->penaltyFactor > 0.99)
{
hightSppedFlowNum++;
totalHightSpeedFlowWeight += item.second->weight;
}
consumeRate += item.second->objectRate;
}
else
{
consumeRate += item.second->currentFlowRate;
}
NFD_LOG_DEBUG(this->name << " => currentRate: " << item.second->currentFlowRate << ", consumerRate: " << consumeRate << ", objectRate: " << item.second->objectRate << ", availableBandwidth" << this->availableBandwidth << ", weight: " << item.second->weight << ", totalWeight: " << this->totalWeight << ", currentSendRate: " << currentSendRate);
item.second->recvBits = 0;
}
if (consumeRate < this->availableBandwidth && hightSppedFlowNum > 0)
{
auto remainRate = this->availableBandwidth - consumeRate;
for (auto &item : this->virtualQueues)
{
if (item.second->penaltyFactor > 0.99 && item.second->currentRatio > 0.8)
{
item.second->objectRate += (remainRate * item.second->weight / totalHightSpeedFlowWeight);
}
NFD_LOG_DEBUG(this->name << " => objectRate: " << item.second->objectRate << ", remainRate: " << remainRate << ", item.weight: " << item.second->weight << ", totalWeight: " << totalHightSpeedFlowWeight);
}
}
for (auto &item : this->virtualQueues)
{
if (item.second->currentFlowRate * 1.0 / item.second->objectRate > item.second->gredyRatio)
{
if (item.second->gredyTimes < item.second->gredyThreshold)
{
item.second->gredyTimes++;
}
if (item.second->gredyTimes == item.second->gredyThreshold)
{
item.second->penaltyFactor = 0.5;
item.second->size = 20;
}
}
else
{
if (item.second->gredyTimes > 0)
{
item.second->gredyTimes--;
}
}
}
for (auto &item : this->virtualQueues)
{
if (item.second->penaltyFactor > 0.99)
{
auto rate = this->calDiscountFactor(item.second->currentSize * 1.0 / item.second->size);
item.second->objectRate *= rate;
}
}
this->sendBits = 0;
this->recvBits = 0;
return currentRate;
}
uint32_t WDRRQueue::scheduleOnePacketForWFQ(uint32_t totalLastSeq)
{
if (this->cachePacketForWFQ != nullptr)
{
return this->cachePacketForWFQ->seq;
}
if (this->currentPacketNum == 0)
{
return UINT32_MAX;
}
this->cachePacketForWFQ = this->scheduleNext();
if (this->cachePacketForWFQ == nullptr)
{
return UINT32_MAX;
}
if (this->lastSeq == -1)
{
this->lastSeq = totalLastSeq;
}
this->cachePacketForWFQ->seq = this->lastSeq + 1.0 * this->cachePacketForWFQ->dataSize / this->weight;
if (this->currentPacketNum == 0)
{
this->lastSeq = -1;
}
else
{
this->lastSeq = this->cachePacketForWFQ->seq;
}
return this->cachePacketForWFQ->seq;
}
std::shared_ptr<VirtualQueueItem> DelaySensitiveServiceSP::scheduleNext()
{
auto res = this->CS7Queue->scheduleNext();
if (res == nullptr)
{
res = this->CS6Queue->scheduleNext();
}
if (res == nullptr)
{
res = this->EFQueue->scheduleNext();
}
return res;
}
uint32_t DelaySensitiveServiceSP::calObjectRate(bool getCurrentRateOnly)
{
uint32_t res = this->CS7Queue->calObjectRate(getCurrentRateOnly);
res += this->CS6Queue->calObjectRate(getCurrentRateOnly);
res += this->EFQueue->calObjectRate(getCurrentRateOnly);
return res;
}
std::shared_ptr<VirtualQueueItem> WFQQueue::scheduleNext()
{
std::shared_ptr<WDRRQueue> selectedQueue = nullptr;
uint32_t currentMinSeq = UINT32_MAX;
for (auto &queue : this->queues)
{
uint32_t seq = queue->scheduleOnePacketForWFQ(this->lastSeq);
if (seq < currentMinSeq)
{
currentMinSeq = seq;
selectedQueue = queue;
}
}
if (selectedQueue != nullptr)
{
this->lastSeq = currentMinSeq;
auto selectPacket = selectedQueue->frontForWFQ(this->lastSeq);
selectedQueue->popForWFQ();
return selectPacket;
}
return nullptr;
}
uint32_t WFQQueue::calObjectRate(uint32_t availableBandwidth)
{
int totalRate = 0;
double totalHightSpeedFlowWeight = 0;
int hightSppedFlowNum = 0;
double totalHasFlowQueueWeight = 0;
int hasFlowQueueNum = 0;
for (auto &queue : this->queues)
{
auto recvRate = queue->calObjectRate(true);
queue->originAvaliableBandwidth = (queue->getWeight() / totalWeight) * availableBandwidth;
auto remainRate = queue->getRemainBandwidthRate(queue->originAvaliableBandwidth);
if (remainRate < 0.2)
{
hightSppedFlowNum++;
totalHightSpeedFlowWeight += queue->getWeight();
totalRate += queue->originAvaliableBandwidth;
}
else if (remainRate < 0.95)
{
hasFlowQueueNum++;
totalHasFlowQueueWeight += queue->getWeight();
totalRate += recvRate;
}
else
{
totalRate += recvRate;
}
}
this->availableBandwidth = availableBandwidth;
int remain = this->availableBandwidth - totalRate;
if (hightSppedFlowNum > 0)
{
for (auto &queue : this->queues)
{
if (queue->getRemainBandwidthRate(queue->originAvaliableBandwidth) < 0.2)
{
queue->updateAvailableBandwidth(
queue->getWeight() * remain * 1.0 / totalHightSpeedFlowWeight +
queue->originAvaliableBandwidth);
}
else
{
queue->updateAvailableBandwidth(queue->originAvaliableBandwidth);
}
}
}
else
{
for (auto &queue : this->queues)
{
if (queue->getRemainBandwidthRate(queue->originAvaliableBandwidth) < 0.95)
{
queue->updateAvailableBandwidth(
queue->getWeight() * remain * 1.0 / totalHasFlowQueueWeight +
queue->originAvaliableBandwidth);
}
else
{
queue->updateAvailableBandwidth(queue->originAvaliableBandwidth);
}
}
}
uint32_t currentTotalRate = 0;
for (auto &queue : this->queues)
{
currentTotalRate += queue->calObjectRate(false);
}
return currentTotalRate;
}
std::shared_ptr<VirtualQueueItem> GlobalSP::scheduleNext()
{
std::shared_ptr<VirtualQueueItem> selectedPacket = this->delaySensitiveServiceSp.scheduleNext();
if (selectedPacket == nullptr)
{
selectedPacket = wfqQueue.scheduleNext();
}
if (selectedPacket != nullptr)
{
selectedPacket->waitNsTime = selectedPacket->dataSize * 1000000000.0 / this->availableBandwidth + 1;
// 计算 DR => DR'(/p, j) = min(OR(/p, j), RR(/p, j) / sum(RR(/p)) * sum(AR(/p)))
auto currentObjectRate = selectedPacket->queue->objectRate;
auto downstreamRate = selectedPacket->item->getDownstreamRate();
if (downstreamRate)
{
if (*downstreamRate > currentObjectRate)
{
selectedPacket->item->setDownstreamRate(currentObjectRate);
}
}
else
{
selectedPacket->item->setDownstreamRate(currentObjectRate);
}
}
return selectedPacket;
}
std::shared_ptr<WDRRQueue> GlobalSP::getQueueByTos(int tosValue)
{
switch (tosValue)
{
case 0:
return this->delaySensitiveServiceSp.getCS7Queue();
case 1:
return this->delaySensitiveServiceSp.getCS6Queue();
case 2:
return this->delaySensitiveServiceSp.getEFQueue();
case 3:
return this->wfqQueue.getAF4Queue();
case 4:
return this->wfqQueue.getAF3Queue();
case 5:
return this->wfqQueue.getAF2Queue();
case 6:
return this->wfqQueue.getAF1Queue();
case 7:
default:
return this->wfqQueue.getBEQueue();
}
}
bool GlobalSP::appendInterest(const Interest &interest)
{
int serviceClass = 7;
if (interest.getServiceClass())
{
serviceClass = (*interest.getServiceClass()) % 8;
}
return this->getQueueByTos(serviceClass)->appendInterest(interest);
}
void GlobalSP::receiveInterest(const Interest &interest)
{
ndn::encoding::EncodingEstimator estimator;
auto size = interest.wireEncode(estimator) + 9;
this->interestBytes += size;
}
void GlobalSP::calObjectRate(bool getCurrentRateOnly)
{
getScheduler().schedule(time::nanoseconds(1000000 * this->calObjectRateInterval),
[this]
{ this->calObjectRate(false); });
uint32_t remain = this->availableBandwidth;
remain -= this->interestBytes * 8000 / this->calObjectRateInterval;
this->interestBytes = 0;
remain -= this->delaySensitiveServiceSp.calObjectRate(false);
this->wfqQueue.calObjectRate(remain);
}
void GlobalSP::assignObjectRate(const Data &data)
{
std::string key = data.getName().getPrefix(1).toUri();
int serviceClass = 7;
if (data.getServiceClass())
{
serviceClass = (*data.getServiceClass()) % 8;
}
auto objectRate = this->getQueueByTos(serviceClass)->getObjectRateByFlowKey(key);
auto targetRate = data.getTargetRate();
if (!targetRate || *targetRate > objectRate)
{
data.setTargetRate(objectRate);
}
}
}
}
+338
View File
@@ -0,0 +1,338 @@
#ifndef NS_QUEUES_HPP
#define NS_QUEUES_HPP
#include <deque>
#include <unordered_map>
#include <memory>
#include "common/global.hpp"
#include "link-service.hpp"
#include <ndn-cxx/lp/tags.hpp>
#include "TokenBucket.hpp"
#include <iostream>
namespace nfd
{
namespace face
{
class VirtualQueue;
struct VirtualQueueItem
{
int seq;
std::shared_ptr<const Interest> item;
EndpointId endpointId;
uint32_t dataSize;
uint32_t waitNsTime;
std::shared_ptr<VirtualQueue> queue;
};
class VirtualQueue : public std::enable_shared_from_this<VirtualQueue>
{
public:
explicit VirtualQueue(double weight, int size) : std::enable_shared_from_this<VirtualQueue>(),
penaltyFactor(1.0),
weight(weight), size(size), currentSize(0), lastSeq(0),
C(0)
{
}
void enableTokenBucket(uint32_t limitRate)
{
this->C = limitRate;
}
bool push(int seq, const std::shared_ptr<const Interest> &interest, const EndpointId &endpointId,
uint64_t dataSize, bool needInsert);
bool empty()
{
return this->innerQueue.empty();
}
uint32_t frontSeq()
{
if (this->innerQueue.empty())
{
return this->lastSeq;
}
return this->innerQueue.front().seq;
}
VirtualQueueItem front()
{
return this->innerQueue.front();
}
uint32_t backSeq()
{
return this->lastSeq;
}
VirtualQueueItem back()
{
return this->innerQueue.back();
}
void pop()
{
if (this->currentSize <= 0)
{
return;
}
this->currentSize--;
this->innerQueue.pop_front();
}
void popBack()
{
if (this->currentSize <= 0)
{
return;
}
this->currentSize--;
this->innerQueue.pop_back();
}
int len()
{
return this->innerQueue.size();
}
void setLastSeq(uint32_t seq)
{
this->lastSeq = seq;
}
uint32_t getLastSeq()
{
return lastSeq;
}
void setWeight(double weight)
{
this->weight = weight;
}
double getWeight()
{
return this->weight;
}
public:
uint32_t objectRate;
double penaltyFactor = 1.0;
uint32_t gredyTimes = 0;
double gredyRatio = 1.2;
double gredyThreshold = 5;
double weight = 1.0;
uint32_t tos = 5;
double balance = 0;
int size = 0;
int currentSize = 0;
uint32_t recvBits = 0;
uint32_t currentFlowRate = 0;
double currentRatio = 0.0;
private:
uint32_t lastSeq;
int C;
std::deque<VirtualQueueItem> innerQueue;
};
class WDRRQueue
{
public:
explicit WDRRQueue(uint32_t rateLimit, uint32_t availableBandwidth, double weight, const std::string &name,
uint32_t tos = 5, size_t vqSize = 20);
void updateAvailableBandwidth(uint32_t C);
bool appendInterest(const Interest &interest, const EndpointId &endpointId);
std::shared_ptr<VirtualQueueItem> scheduleNext();
uint32_t calObjectRate(bool getCurrentRateOnly);
void setCDTLimit(int cdt)
{
this->cdt = cdt;
}
uint32_t scheduleOnePacketForWFQ(uint32_t totalLastSeq);
std::shared_ptr<VirtualQueueItem> frontForWFQ(uint32_t totalLastSeq)
{
if (this->cachePacketForWFQ == nullptr)
{
this->scheduleOnePacketForWFQ(totalLastSeq);
}
return this->cachePacketForWFQ;
}
void popForWFQ()
{
this->cachePacketForWFQ = nullptr;
}
double getRemainBandwidthRate(double curAvailableBandWidth)
{
auto currentRate = this->calObjectRate(true);
if (currentRate > curAvailableBandWidth)
{
return 0;
}
return (curAvailableBandWidth - currentRate) * 1.0 / curAvailableBandWidth;
}
uint32_t getRemainBandwidth()
{
return this->availableBandwidth - this->calObjectRate(true);
}
double getWeight()
{
return this->weight;
}
uint32_t getAvailableBandwidth()
{
return this->availableBandwidth;
}
/**
* @brief
*
* \sigma=\frac{1}{3}\arccot\funcapply(8\delta-4)
* @param x
* @return double
*/
double calDiscountFactor(double x)
{
return 1.0 / 3 * (M_PI / 2 - atan(8 * x - 4)) + 0.034;
}
/**
* @brief Get the Object Rate By Flow Key object
*
* @param key
* @return uint32_t
*/
uint32_t getObjectRateByFlowKey(const std::string &key)
{
if (this->virtualQueues.count(key) == 0)
{
std::cout << "FUCK: " << key << ", count: " << this->virtualQueues.size() << ", flow: " << this->flows.size() << "availbleRate: " << this->availableBandwidth << std::endl;
return 0;
}
return this->virtualQueues[key]->objectRate;
}
public:
double originAvaliableBandwidth = 0;
private:
std::unordered_map<std::string, std::shared_ptr<VirtualQueue>> virtualQueues;
std::vector<std::string> flows;
size_t nextScheduleQueue = 0;
std::shared_ptr<TokenBucket> tokenBucket;
uint32_t availableBandwidth;
// uint32_t extraBandwidth;
double weight;
std::string name;
uint32_t tos = 5;
bool needRateLimit;
double totalWeight;
uint32_t sendBits = 0;
uint32_t recvBits = 0;
int vqSize = 20;
int cdt = -1;
int currentPacketNum = 0;
int MTU_QUANTA = 2 * 1000 * 8;
int calObjectRateInterval = 100;
int64_t lastSeq = -1;
std::shared_ptr<VirtualQueueItem> cachePacketForWFQ = nullptr;
};
class DelaySensitiveServiceSP
{
public:
explicit DelaySensitiveServiceSP(uint32_t availableBandwidth, size_t vqSize = 20)
{
this->CS7Queue = std::make_shared<WDRRQueue>((uint32_t)(0.2 * availableBandwidth), (uint32_t)(0.2 * availableBandwidth), 2, "CS7", 2, vqSize);
this->CS6Queue = std::make_shared<WDRRQueue>((uint32_t)(0.2 * availableBandwidth), (uint32_t)(0.2 * availableBandwidth), 2, "CS6", 1, vqSize);
this->EFQueue = std::make_shared<WDRRQueue>((uint32_t)(0.3 * availableBandwidth), (uint32_t)(0.3 * availableBandwidth), 3, "EF", 0, vqSize);
}
std::shared_ptr<VirtualQueueItem> scheduleNext();
uint32_t calObjectRate(bool getCurrentRateOnly);
std::shared_ptr<WDRRQueue> getCS7Queue()
{
return this->CS7Queue;
}
std::shared_ptr<WDRRQueue> getCS6Queue()
{
return this->CS6Queue;
}
std::shared_ptr<WDRRQueue> getEFQueue()
{
return this->EFQueue;
}
private:
std::shared_ptr<WDRRQueue> CS7Queue;
std::shared_ptr<WDRRQueue> CS6Queue;
std::shared_ptr<WDRRQueue> EFQueue;
};
class WFQQueue
{
public:
explicit WFQQueue(uint32_t availableBandwidth, size_t vqSize) : AF4Weight(5),
AF3Weight(4),
AF2Weight(3),
AF1Weight(2),
BEWeight(1),
totalWeight(AF4Weight + AF3Weight + AF2Weight + AF1Weight + BEWeight),
queues(5),
lastSeq(0),
availableBandwidth(availableBandwidth)
{
this->queues[0] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF4Weight / totalWeight, 5, "AF4", 3, vqSize);
this->queues[1] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF3Weight / totalWeight, 4, "AF3", 4, vqSize);
this->queues[2] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF2Weight / totalWeight, 3, "AF2", 5, vqSize);
this->queues[3] = std::make_shared<WDRRQueue>(0, availableBandwidth * AF1Weight / totalWeight, 2, "AF1", 6, vqSize);
this->queues[4] = std::make_shared<WDRRQueue>(0, availableBandwidth * BEWeight / totalWeight, 1, "BE", 7, vqSize);
for (auto &queue : this->queues)
{
queue->setCDTLimit(this->cdt);
}
}
std::shared_ptr<VirtualQueueItem> scheduleNext();
uint32_t calObjectRate(uint32_t availableBandwidth);
std::shared_ptr<WDRRQueue> getAF4Queue()
{
return this->queues[0];
}
std::shared_ptr<WDRRQueue> getAF3Queue()
{
return this->queues[1];
}
std::shared_ptr<WDRRQueue> getAF2Queue()
{
return this->queues[2];
}
std::shared_ptr<WDRRQueue> getAF1Queue()
{
return this->queues[3];
}
std::shared_ptr<WDRRQueue> getBEQueue()
{
return this->queues[4];
}
private:
double AF4Weight = 5;
double AF3Weight = 4;
double AF2Weight = 3;
double AF1Weight = 2;
double BEWeight = 1;
double totalWeight = 15;
std::vector<std::shared_ptr<WDRRQueue>> queues;
uint32_t lastSeq;
u_int32_t availableBandwidth;
int cdt = 200;
int hql;
};
class GlobalSP
{
public:
explicit GlobalSP(uint32_t availableBandwidth, size_t vqSize = 20) : delaySensitiveServiceSp(availableBandwidth, vqSize),
wfqQueue(availableBandwidth, vqSize),
availableBandwidth(availableBandwidth)
{
getScheduler().schedule(time::nanoseconds(1000000 * this->calObjectRateInterval),
[this]
{ this->calObjectRate(false); });
}
std::shared_ptr<VirtualQueueItem> scheduleNext();
bool appendInterest(const Interest &interest, const EndpointId &endpointId);
void receiveInterest(const Interest &interest);
void calObjectRate(bool getCurrentRateOnly);
std::shared_ptr<WDRRQueue> getQueueByTos(int tosValue);
void assignObjectRate(const Data &data);
private:
DelaySensitiveServiceSP delaySensitiveServiceSp;
WFQQueue wfqQueue;
int calObjectRateInterval = 100;
uint32_t availableBandwidth;
size_t interestBytes = 0;
};
}
}
#endif // NS_QUEUES_HPP
+10 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,13 +32,15 @@
#include <queue>
#include <boost/asio/defer.hpp>
#include <boost/asio/write.hpp>
namespace nfd::face {
/** \brief Implements Transport for stream-based protocols.
/**
* \brief Implements a Transport for stream-based protocols.
*
* \tparam Protocol a stream-based protocol in Boost.Asio
* \tparam Protocol a stream-based protocol in Boost.Asio
*/
template<class Protocol>
class StreamTransport : public Transport
@@ -46,9 +48,10 @@ class StreamTransport : public Transport
public:
using protocol = Protocol;
/** \brief Construct stream transport.
/**
* \brief Construct stream transport.
*
* \param socket Protocol-specific socket for the created transport
* \param socket Protocol-specific socket for the created transport
*/
explicit
StreamTransport(typename protocol::socket&& socket);
@@ -144,12 +147,12 @@ StreamTransport<T>::doClose()
// Use the non-throwing variants and ignore errors, if any.
boost::system::error_code error;
m_socket.cancel(error);
m_socket.shutdown(protocol::socket::shutdown_both, error);
m_socket.shutdown(boost::asio::socket_base::shutdown_both, error);
}
// Ensure that the Transport stays alive at least until
// all pending handlers are dispatched
getGlobalIoService().post([this] { deferredClose(); });
boost::asio::defer(getGlobalIoService(), [this] { deferredClose(); });
// Some bug or feature of Boost.Asio (see https://redmine.named-data.net/issues/1856):
//
+22 -29
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -33,16 +33,15 @@
namespace nfd::face {
NFD_LOG_INIT(TcpChannel);
namespace ip = boost::asio::ip;
NFD_LOG_INIT(TcpChannel);
TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
DetermineFaceScopeFromAddress determineFaceScope)
: m_localEndpoint(localEndpoint)
, m_acceptor(getGlobalIoService())
, m_socket(getGlobalIoService())
, m_wantCongestionMarking(wantCongestionMarking)
, m_acceptor(getGlobalIoService())
, m_determineFaceScope(std::move(determineFaceScope))
{
setUri(FaceUri(m_localEndpoint));
@@ -52,7 +51,7 @@ TcpChannel::TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMa
void
TcpChannel::listen(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed,
int backlog/* = tcp::acceptor::max_connections*/)
int backlog)
{
if (isListening()) {
NFD_LOG_CHAN_WARN("Already listening");
@@ -60,7 +59,7 @@ TcpChannel::listen(const FaceCreatedCallback& onFaceCreated,
}
m_acceptor.open(m_localEndpoint.protocol());
m_acceptor.set_option(ip::tcp::acceptor::reuse_address(true));
m_acceptor.set_option(boost::asio::socket_base::reuse_address(true));
if (m_localEndpoint.address().is_v6()) {
m_acceptor.set_option(ip::v6_only(true));
}
@@ -150,7 +149,7 @@ TcpChannel::createFace(ip::tcp::socket&& socket,
NFD_LOG_CHAN_TRACE("Reusing existing face for " << remoteEndpoint);
boost::system::error_code error;
socket.shutdown(ip::tcp::socket::shutdown_both, error);
socket.shutdown(boost::asio::socket_base::shutdown_both, error);
socket.close(error);
}
@@ -163,31 +162,25 @@ void
TcpChannel::accept(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed)
{
m_acceptor.async_accept(m_socket, [=] (const auto& e) { this->handleAccept(e, onFaceCreated, onAcceptFailed); });
}
void
TcpChannel::handleAccept(const boost::system::error_code& error,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed)
{
if (error) {
if (error != boost::asio::error::operation_aborted) {
NFD_LOG_CHAN_DEBUG("Accept failed: " << error.message());
if (onAcceptFailed)
onAcceptFailed(500, "Accept failed: " + error.message());
m_acceptor.async_accept([=] (const boost::system::error_code& error, ip::tcp::socket socket) {
if (error) {
if (error != boost::asio::error::operation_aborted) {
NFD_LOG_CHAN_DEBUG("Accept failed: " << error.message());
if (onAcceptFailed)
onAcceptFailed(500, "Accept failed: " + error.message());
}
return;
}
return;
}
NFD_LOG_CHAN_TRACE("Incoming connection from " << m_socket.remote_endpoint());
NFD_LOG_CHAN_TRACE("Incoming connection from " << socket.remote_endpoint());
FaceParams params;
params.persistency = ndn::nfd::FACE_PERSISTENCY_ON_DEMAND;
createFace(std::move(m_socket), params, onFaceCreated, onAcceptFailed);
FaceParams params;
params.persistency = ndn::nfd::FACE_PERSISTENCY_ON_DEMAND;
createFace(std::move(socket), params, onFaceCreated, onAcceptFailed);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
});
}
void
+11 -18
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -40,20 +40,19 @@ using DetermineFaceScopeFromAddress = std::function<ndn::nfd::FaceScope(const bo
const boost::asio::ip::address& remote)>;
/**
* \brief Class implementing TCP-based channel to create faces
* \brief Class implementing a TCP-based channel to create faces.
*
* Channel can create faces as a response to incoming TCP
* connections (TcpChannel::listen needs to be called for that
* to work) or explicitly after using TcpChannel::connect method.
* The channel can create faces as a response to incoming TCP connections (TcpChannel::listen()
* needs to be called for that to work) or explicitly by using TcpChannel::connect().
*/
class TcpChannel final : public Channel
{
public:
/**
* \brief Create TCP channel for the local endpoint
* \brief Create a TCP channel for the specified \p localEndpoint.
*
* To enable creation faces upon incoming connections,
* one needs to explicitly call TcpChannel::listen method.
* To enable the creation of faces upon incoming connections, one needs to
* explicitly call listen().
*/
TcpChannel(const tcp::Endpoint& localEndpoint, bool wantCongestionMarking,
DetermineFaceScopeFromAddress determineFaceScope);
@@ -72,7 +71,7 @@ public:
/**
* \brief Enable listening on the local endpoint, accept connections,
* and create faces when remote host makes a connection
* and create faces when remote host makes a connection.
* \param onFaceCreated Callback to notify successful creation of the face
* \param onAcceptFailed Callback to notify when channel fails (accept call
* returns an error)
@@ -82,10 +81,10 @@ public:
void
listen(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed,
int backlog = boost::asio::ip::tcp::acceptor::max_connections);
int backlog = boost::asio::socket_base::max_listen_connections);
/**
* \brief Create a face by establishing a TCP connection to \p remoteEndpoint
* \brief Create a face by establishing a TCP connection to \p remoteEndpoint.
*/
void
connect(const tcp::Endpoint& remoteEndpoint,
@@ -105,11 +104,6 @@ private:
accept(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed);
void
handleAccept(const boost::system::error_code& error,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed);
void
handleConnect(const boost::system::error_code& error,
const tcp::Endpoint& remoteEndpoint,
@@ -126,10 +120,9 @@ private:
private:
const tcp::Endpoint m_localEndpoint;
const bool m_wantCongestionMarking;
boost::asio::ip::tcp::acceptor m_acceptor;
boost::asio::ip::tcp::socket m_socket;
std::map<tcp::Endpoint, shared_ptr<Face>> m_channelFaces;
bool m_wantCongestionMarking;
DetermineFaceScopeFromAddress m_determineFaceScope;
};
+8 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -152,31 +152,31 @@ TcpFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (req.localUri) {
NFD_LOG_TRACE("Cannot create unicast TCP face with LocalUri");
NFD_LOG_TRACE("createFace: unsupported LocalUri");
onFailure(406, "Unicast TCP faces cannot be created with a LocalUri");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing TCP faces do not support on-demand persistency");
return;
}
tcp::Endpoint endpoint(ip::address::from_string(req.remoteUri.getHost()),
tcp::Endpoint endpoint(ip::make_address(req.remoteUri.getHost()),
boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
// a canonical tcp4/tcp6 FaceUri cannot have a multicast address
BOOST_ASSERT(!endpoint.address().is_multicast());
if (req.params.wantLocalFields && !endpoint.address().is_loopback()) {
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
if (req.params.mtu) {
NFD_LOG_TRACE("createFace cannot create a TCP face with an overridden MTU");
NFD_LOG_TRACE("createFace: cannot create TCP face with overridden MTU");
onFailure(406, "TCP faces do not support MTU overrides");
return;
}
@@ -215,8 +215,8 @@ TcpFactory::doGetChannels() const
}
ndn::nfd::FaceScope
TcpFactory::determineFaceScopeFromAddresses(const boost::asio::ip::address& localAddress,
const boost::asio::ip::address& remoteAddress) const
TcpFactory::determineFaceScopeFromAddresses(const ip::address& localAddress,
const ip::address& remoteAddress) const
{
if (m_local(localAddress) && m_local(remoteAddress)) {
return ndn::nfd::FACE_SCOPE_LOCAL;
+6 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,11 +27,13 @@
#define NFD_DAEMON_FACE_TCP_FACTORY_HPP
#include "protocol-factory.hpp"
#include "network-predicate.hpp"
#include "tcp-channel.hpp"
namespace nfd::face {
/** \brief Protocol factory for TCP over IPv4 and IPv6.
/**
* \brief Protocol factory for TCP over IPv4 and IPv6.
*/
class TcpFactory final : public ProtocolFactory
{
@@ -44,12 +46,12 @@ public:
/**
* \brief Create TCP-based channel using tcp::Endpoint.
*
* tcp::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
* tcp::Endpoint is an alias for boost::asio::ip::tcp::endpoint.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
*
* \return always a valid pointer to a TcpChannel object, an exception
* \return Always a valid pointer to a TcpChannel object, an exception
* is thrown if it cannot be created.
*/
shared_ptr<TcpChannel>
+10 -12
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,6 +26,8 @@
#include "tcp-transport.hpp"
#include "common/global.hpp"
#include <boost/asio/defer.hpp>
#if defined(__linux__)
#include <linux/sockios.h>
#include <sys/ioctl.h>
@@ -33,9 +35,11 @@
namespace nfd::face {
NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>, TcpTransport);
namespace ip = boost::asio::ip;
TcpTransport::TcpTransport(protocol::socket&& socket,
NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<ip::tcp>, TcpTransport);
TcpTransport::TcpTransport(ip::tcp::socket&& socket,
ndn::nfd::FacePersistency persistency,
ndn::nfd::FaceScope faceScope)
: StreamTransport(std::move(socket))
@@ -105,7 +109,7 @@ TcpTransport::handleError(const boost::system::error_code& error)
m_socket.cancel(ec);
// do this asynchronously because there could be some callbacks still pending
getGlobalIoService().post([this] { reconnect(); });
boost::asio::defer(getGlobalIoService(), [this] { reconnect(); });
}
else {
StreamTransport::handleError(error);
@@ -128,13 +132,7 @@ TcpTransport::reconnect()
BOOST_ASSERT(getState() == TransportState::DOWN);
// recreate the socket
m_socket = protocol::socket(
#if BOOST_VERSION >= 107000
m_socket.get_executor()
#else
m_socket.get_io_service()
#endif // BOOST_VERSION >= 107000
);
m_socket = ip::tcp::socket(m_socket.get_executor());
this->resetReceiveBuffer();
this->resetSendQueue();
@@ -181,7 +179,7 @@ TcpTransport::handleReconnectTimeout()
MAX_RECONNECT_DELAY);
// do this asynchronously because there could be some callbacks still pending
getGlobalIoService().post([this] { reconnect(); });
boost::asio::defer(getGlobalIoService(), [this] { reconnect(); });
}
void
+10 -12
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -35,7 +35,7 @@ namespace nfd::face {
NFD_LOG_MEMBER_DECL_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>);
/**
* \brief A Transport that communicates on a connected TCP socket
* \brief A Transport that communicates on a connected TCP socket.
*
* When persistency is set to permanent, whenever the TCP connection is severed, the transport
* state is set to DOWN, and the connection is retried periodically with exponential backoff
@@ -44,7 +44,9 @@ NFD_LOG_MEMBER_DECL_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>);
class TcpTransport NFD_FINAL_UNLESS_WITH_TESTS : public StreamTransport<boost::asio::ip::tcp>
{
public:
TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency, ndn::nfd::FaceScope faceScope);
TcpTransport(boost::asio::ip::tcp::socket&& socket,
ndn::nfd::FacePersistency persistency,
ndn::nfd::FaceScope faceScope);
ssize_t
getSendQueueLength() final;
@@ -74,29 +76,25 @@ NFD_PROTECTED_WITH_TESTS_ELSE_PRIVATE:
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/**
* \brief Delay before the first reconnection attempt after the TCP connection has been severed
* \brief Delay before the first reconnection attempt after the TCP connection has been severed.
*/
static constexpr time::milliseconds INITIAL_RECONNECT_DELAY = 1_s;
/**
* \brief Maximum amount of time to wait before a reconnection attempt
* \brief Maximum amount of time to wait before a reconnection attempt.
*/
static constexpr time::milliseconds MAX_RECONNECT_DELAY = 5_min;
/**
* \brief Multiplier for the exponential backoff of the reconnection timer
* \brief Multiplier for the exponential backoff of the reconnection timer.
*/
static constexpr float RECONNECT_DELAY_MULTIPLIER = 2.0f;
private:
typename protocol::endpoint m_remoteEndpoint;
boost::asio::ip::tcp::endpoint m_remoteEndpoint;
/** \note valid only when persistency is set to permanent
*/
// The following members are valid only when the persistency is set to permanent
scheduler::ScopedEventId m_reconnectEvent;
/** \note valid only when persistency is set to permanent
*/
time::milliseconds m_nextReconnectWait;
};
+8 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -33,10 +33,10 @@
namespace nfd::face {
NFD_LOG_INIT(UdpChannel);
namespace ip = boost::asio::ip;
NFD_LOG_INIT(UdpChannel);
UdpChannel::UdpChannel(const udp::Endpoint& localEndpoint,
time::nanoseconds idleTimeout,
bool wantCongestionMarking,
@@ -83,7 +83,7 @@ UdpChannel::listen(const FaceCreatedCallback& onFaceCreated,
}
m_socket.open(m_localEndpoint.protocol());
m_socket.set_option(ip::udp::socket::reuse_address(true));
m_socket.set_option(boost::asio::socket_base::reuse_address(true));
if (m_localEndpoint.address().is_v6()) {
m_socket.set_option(ip::v6_only(true));
}
@@ -97,10 +97,9 @@ void
UdpChannel::waitForNewPeer(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed)
{
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint,
[=] (auto&&... args) {
this->handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
});
m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint, [=] (auto&&... args) {
handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
});
}
void
@@ -160,7 +159,7 @@ UdpChannel::createFace(const udp::Endpoint& remoteEndpoint,
// else, create a new face
ip::udp::socket socket(getGlobalIoService(), m_localEndpoint.protocol());
socket.set_option(ip::udp::socket::reuse_address(true));
socket.set_option(boost::asio::socket_base::reuse_address(true));
socket.bind(m_localEndpoint);
socket.connect(remoteEndpoint);
+8 -13
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -34,17 +34,16 @@
namespace nfd::face {
/**
* \brief Class implementing UDP-based channel to create faces
* \brief Class implementing a UDP-based channel to create faces.
*/
class UdpChannel final : public Channel
{
public:
/**
* \brief Create a UDP channel on the given \p localEndpoint
* \brief Create a UDP channel on the given \p localEndpoint.
*
* To enable creation of faces upon incoming connections,
* one needs to explicitly call UdpChannel::listen method.
* The created socket is bound to \p localEndpoint.
* To enable the creation of faces upon incoming connections, one needs to
* explicitly call listen(). The created socket is bound to \p localEndpoint.
*/
UdpChannel(const udp::Endpoint& localEndpoint,
time::nanoseconds idleTimeout,
@@ -64,7 +63,7 @@ public:
}
/**
* \brief Create a unicast UDP face toward \p remoteEndpoint
* \brief Create a unicast UDP face toward \p remoteEndpoint.
*/
void
connect(const udp::Endpoint& remoteEndpoint,
@@ -73,7 +72,7 @@ public:
const FaceCreationFailedCallback& onConnectFailed);
/**
* \brief Start listening
* \brief Start listening.
*
* Enable listening on the local endpoint, waiting for incoming datagrams,
* and creating a face when a datagram is received from a new remote host.
@@ -92,10 +91,6 @@ private:
waitForNewPeer(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onReceiveFailed);
/**
* \brief The channel has received a packet from a remote
* endpoint not associated with any UDP face yet
*/
void
handleNewPeer(const boost::system::error_code& error,
size_t nBytesReceived,
@@ -113,7 +108,7 @@ private:
std::array<uint8_t, ndn::MAX_NDN_PACKET_SIZE> m_receiveBuffer;
std::map<udp::Endpoint, shared_ptr<Face>> m_channelFaces;
const time::nanoseconds m_idleFaceTimeout; ///< Timeout for automatic closure of idle on-demand faces
bool m_wantCongestionMarking;
const bool m_wantCongestionMarking;
};
} // namespace nfd::face
+30 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,6 +28,7 @@
#include "multicast-udp-transport.hpp"
#include "common/global.hpp"
#include <boost/container/static_vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
@@ -51,7 +52,7 @@ UdpFactory::UdpFactory(const CtorParams& params)
: ProtocolFactory(params)
{
m_netifAddConn = netmon->onInterfaceAdded.connect([this] (const auto& netif) {
this->applyMcastConfigToNetif(netif);
applyMcastConfigToNetif(netif);
});
}
@@ -129,7 +130,7 @@ UdpFactory::doProcessConfig(OptionalConfigSection configSection,
else if (key == "mcast_group") {
const std::string& valueStr = value.get_value<std::string>();
boost::system::error_code ec;
mcastConfig.group.address(ip::address_v4::from_string(valueStr, ec));
mcastConfig.group.address(ip::make_address_v4(valueStr, ec));
if (ec) {
NDN_THROW(ConfigFile::Error("face_system.udp.mcast_group: '" +
valueStr + "' cannot be parsed as an IPv4 address"));
@@ -145,7 +146,7 @@ UdpFactory::doProcessConfig(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(ip::address_v6::from_string(valueStr, ec));
mcastConfig.groupV6.address(ip::make_address_v6(valueStr, ec));
if (ec) {
NDN_THROW(ConfigFile::Error("face_system.udp.mcast_group_v6: '" +
valueStr + "' cannot be parsed as an IPv6 address"));
@@ -196,7 +197,7 @@ UdpFactory::doProcessConfig(OptionalConfigSection configSection,
providedSchemes.insert("udp4");
}
else if (providedSchemes.count("udp4") > 0) {
NFD_LOG_WARN("Cannot close udp4 channel after its creation");
NFD_LOG_WARN("Cannot close UDP channel after its creation");
}
if (enableV6) {
@@ -209,7 +210,7 @@ UdpFactory::doProcessConfig(OptionalConfigSection configSection,
providedSchemes.insert("udp6");
}
else if (providedSchemes.count("udp6") > 0) {
NFD_LOG_WARN("Cannot close udp6 channel after its creation");
NFD_LOG_WARN("Cannot close UDP channel after its creation");
}
if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
@@ -238,10 +239,10 @@ UdpFactory::doProcessConfig(OptionalConfigSection configSection,
}
}
// Even if there's no configuration change, we still need to re-apply configuration because
// netifs may have changed.
m_mcastConfig = mcastConfig;
this->applyMcastConfig(context);
// Even if there are no configuration changes, we still need to re-apply
// the configuration because netifs may have changed.
m_mcastConfig = std::move(mcastConfig);
applyMcastConfig(context);
}
void
@@ -250,29 +251,29 @@ UdpFactory::doCreateFace(const CreateFaceRequest& req,
const FaceCreationFailedCallback& onFailure)
{
if (req.localUri) {
NFD_LOG_TRACE("Cannot create unicast UDP face with LocalUri");
NFD_LOG_TRACE("createFace: unsupported LocalUri");
onFailure(406, "Unicast UDP faces cannot be created with a LocalUri");
return;
}
if (req.params.persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
NFD_LOG_TRACE("createFace does not support FACE_PERSISTENCY_ON_DEMAND");
NFD_LOG_TRACE("createFace: unsupported FacePersistency");
onFailure(406, "Outgoing UDP faces do not support on-demand persistency");
return;
}
udp::Endpoint endpoint(ip::address::from_string(req.remoteUri.getHost()),
udp::Endpoint endpoint(ip::make_address(req.remoteUri.getHost()),
boost::lexical_cast<uint16_t>(req.remoteUri.getPort()));
if (endpoint.address().is_multicast()) {
NFD_LOG_TRACE("createFace does not support multicast faces");
NFD_LOG_TRACE("createFace: unsupported multicast endpoint");
onFailure(406, "Cannot create multicast UDP faces");
return;
}
if (req.params.wantLocalFields) {
// UDP faces are never local
NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
NFD_LOG_TRACE("createFace: cannot create non-local face with local fields enabled");
onFailure(406, "Local fields can only be enabled on faces with local scope");
return;
}
@@ -377,7 +378,9 @@ UdpFactory::createMulticastFace(const net::NetworkInterface& netif,
[isV4 = localEp.address().is_v4()] (const auto& it) {
return it.first.address().is_v4() == isV4;
});
face->setChannel(channelIt != m_channels.end() ? channelIt->second : nullptr);
if (channelIt != m_channels.end()) {
face->setChannel(channelIt->second);
}
return face;
}
@@ -423,7 +426,7 @@ UdpFactory::applyMcastConfigToNetif(const shared_ptr<const net::NetworkInterface
return {};
}
std::vector<ip::address> addrs;
boost::container::static_vector<ip::address, 2> addrs;
for (auto af : {net::AddressFamily::V4, net::AddressFamily::V6}) {
auto addr = pickAddress(*netif, af);
if (addr)
@@ -434,7 +437,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([=] (auto&&...) { this->applyMcastConfigToNetif(netif); });
netif->onAddressAdded.connect([=] (auto&&...) { applyMcastConfigToNetif(netif); });
return {};
}
@@ -442,8 +445,14 @@ UdpFactory::applyMcastConfigToNetif(const shared_ptr<const net::NetworkInterface
std::vector<shared_ptr<Face>> faces;
for (const auto& addr : addrs) {
auto face = this->createMulticastFace(*netif, addr,
addr.is_v4() ? m_mcastConfig.group : m_mcastConfig.groupV6);
shared_ptr<Face> face;
try {
face = createMulticastFace(*netif, addr, addr.is_v4() ? m_mcastConfig.group : m_mcastConfig.groupV6);
}
catch (const std::runtime_error& e) {
NFD_LOG_WARN("Cannot create multicast face on " << addr << ": " << e.what());
continue; // not a fatal error
}
if (face->getId() == INVALID_FACEID) {
// new face: register with forwarding
this->addFace(face);
@@ -464,7 +473,7 @@ UdpFactory::applyMcastConfig(const FaceSystem::ConfigContext&)
// create faces if requested by config
for (const auto& netif : netmon->listNetworkInterfaces()) {
auto facesToKeep = this->applyMcastConfigToNetif(netif);
auto facesToKeep = applyMcastConfigToNetif(netif);
for (const auto& face : facesToKeep) {
// don't destroy face
facesToClose.erase(face);
+14 -10
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,11 +27,13 @@
#define NFD_DAEMON_FACE_UDP_FACTORY_HPP
#include "protocol-factory.hpp"
#include "network-predicate.hpp"
#include "udp-channel.hpp"
namespace nfd::face {
/** \brief Protocol factory for UDP over IPv4 and IPv6.
/**
* \brief Protocol factory for UDP over IPv4 and IPv6.
*/
class UdpFactory final : public ProtocolFactory
{
@@ -51,7 +53,7 @@ public:
/**
* \brief Create UDP-based channel using udp::Endpoint.
*
* udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
* udp::Endpoint is an alias for boost::asio::ip::udp::endpoint.
*
* If this method is called twice with the same endpoint, only one channel
* will be created. The second call will just return the existing channel.
@@ -59,7 +61,7 @@ public:
* If a multicast face is already active on the same local endpoint,
* the creation fails and an exception is thrown.
*
* \return always a valid pointer to a UdpChannel object, an exception
* \return Always a valid pointer to a UdpChannel object, an exception
* is thrown if it cannot be created.
* \throw UdpFactory::Error
*/
@@ -70,7 +72,7 @@ public:
/**
* \brief Create a multicast UDP face.
*
* udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
* udp::Endpoint is an alias for boost::asio::ip::udp::endpoint.
*
* The face will join the specified multicast group.
*
@@ -85,9 +87,9 @@ public:
* \param localAddress the local IP address to which the face will be bound
* \param multicastEndpoint the multicast endpoint (multicast group and port number)
*
* \return always a valid shared pointer to the created face;
* \return Always a valid shared pointer to the created face;
* an exception is thrown if the face cannot be created.
* \throw UdpFactory::Error
* \throw std::runtime_error %Face creation failed
*/
shared_ptr<Face>
createMulticastFace(const ndn::net::NetworkInterface& netif,
@@ -107,13 +109,15 @@ private:
std::vector<shared_ptr<const Channel>>
doGetChannels() const final;
/** \brief Create UDP multicast faces on \p netif if needed by \p m_mcastConfig.
* \return list of faces (just created or already existing) on \p netif
/**
* \brief Create UDP multicast faces on \p netif if needed by \p m_mcastConfig.
* \return List of faces (just created or already existing) on \p netif.
*/
std::vector<shared_ptr<Face>>
applyMcastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
/** \brief Create and destroy UDP multicast faces according to \p m_mcastConfig.
/**
* \brief Create and destroy UDP multicast faces according to \p m_mcastConfig.
*/
void
applyMcastConfig(const FaceSystem::ConfigContext& context);
+3 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -55,7 +55,8 @@ getDefaultMulticastGroup()
inline Endpoint
getDefaultMulticastGroupV6()
{
return {boost::asio::ip::address_v6::from_string("FF02::1234"), 56363};
return {boost::asio::ip::address_v6({0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34}), 56363};
}
} // namespace nfd::udp
+3 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,13 +31,13 @@
namespace nfd::face {
/**
* @brief A unicast Transport that uses raw Ethernet II frames
* @brief A unicast Transport that uses raw Ethernet II frames.
*/
class UnicastEthernetTransport final : public EthernetTransport
{
public:
/**
* @brief Creates an Ethernet-based transport for unicast communication
* @brief Creates an Ethernet-based transport for unicast communication.
*/
UnicastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
const ethernet::Address& remoteEndpoint,
+5 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -36,9 +36,11 @@
namespace nfd::face {
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Unicast>), UnicastUdpTransport);
namespace ip = boost::asio::ip;
UnicastUdpTransport::UnicastUdpTransport(protocol::socket&& socket,
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<ip::udp, Unicast>), UnicastUdpTransport);
UnicastUdpTransport::UnicastUdpTransport(ip::udp::socket&& socket,
ndn::nfd::FacePersistency persistency,
time::nanoseconds idleTimeout)
: DatagramTransport(std::move(socket))
+3 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -35,12 +35,12 @@ namespace nfd::face {
NFD_LOG_MEMBER_DECL_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Unicast>));
/**
* \brief A Transport that communicates on a unicast UDP socket
* \brief A Transport that communicates on a unicast UDP socket.
*/
class UnicastUdpTransport final : public DatagramTransport<boost::asio::ip::udp, Unicast>
{
public:
UnicastUdpTransport(protocol::socket&& socket,
UnicastUdpTransport(boost::asio::ip::udp::socket&& socket,
ndn::nfd::FacePersistency persistency,
time::nanoseconds idleTimeout);
+25 -32
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -39,10 +39,8 @@ NFD_LOG_INIT(UnixStreamChannel);
UnixStreamChannel::UnixStreamChannel(const unix_stream::Endpoint& endpoint,
bool wantCongestionMarking)
: m_endpoint(endpoint)
, m_acceptor(getGlobalIoService())
, m_socket(getGlobalIoService())
, m_size(0)
, m_wantCongestionMarking(wantCongestionMarking)
, m_acceptor(getGlobalIoService())
{
setUri(FaceUri(m_endpoint));
NFD_LOG_CHAN_INFO("Creating channel");
@@ -63,7 +61,7 @@ UnixStreamChannel::~UnixStreamChannel()
void
UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed,
int backlog/* = acceptor::max_connections*/)
int backlog)
{
if (isListening()) {
NFD_LOG_CHAN_WARN("Already listening");
@@ -112,39 +110,34 @@ void
UnixStreamChannel::accept(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed)
{
m_acceptor.async_accept(m_socket, [=] (const auto& e) { this->handleAccept(e, onFaceCreated, onAcceptFailed); });
}
void
UnixStreamChannel::handleAccept(const boost::system::error_code& error,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed)
{
if (error) {
if (error != boost::asio::error::operation_aborted) {
NFD_LOG_CHAN_DEBUG("Accept failed: " << error.message());
if (onAcceptFailed)
onAcceptFailed(500, "Accept failed: " + error.message());
m_acceptor.async_accept([=] (const boost::system::error_code& error,
boost::asio::local::stream_protocol::socket socket) {
if (error) {
if (error != boost::asio::error::operation_aborted) {
NFD_LOG_CHAN_DEBUG("Accept failed: " << error.message());
if (onAcceptFailed)
onAcceptFailed(500, "Accept failed: " + error.message());
}
return;
}
return;
}
NFD_LOG_CHAN_TRACE("Incoming connection via fd " << m_socket.native_handle());
NFD_LOG_CHAN_TRACE("Incoming connection via fd " << socket.native_handle());
GenericLinkService::Options options;
options.allowCongestionMarking = m_wantCongestionMarking;
auto linkService = make_unique<GenericLinkService>(options);
auto transport = make_unique<UnixStreamTransport>(std::move(m_socket));
auto face = make_shared<Face>(std::move(linkService), std::move(transport));
face->setChannel(weak_from_this());
GenericLinkService::Options options;
options.allowCongestionMarking = m_wantCongestionMarking;
auto linkService = make_unique<GenericLinkService>(options);
auto transport = make_unique<UnixStreamTransport>(std::move(socket));
auto face = make_shared<Face>(std::move(linkService), std::move(transport));
face->setChannel(weak_from_this());
++m_size;
connectFaceClosedSignal(*face, [this] { --m_size; });
++m_size;
connectFaceClosedSignal(*face, [this] { --m_size; });
onFaceCreated(face);
onFaceCreated(face);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
// prepare accepting the next connection
accept(onFaceCreated, onAcceptFailed);
});
}
} // namespace nfd::face
+11 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -37,16 +37,16 @@ using Endpoint = boost::asio::local::stream_protocol::endpoint;
namespace nfd::face {
/**
* \brief Class implementing a local channel to create faces
* \brief Class implementing a local channel to create faces.
*
* Channel can create faces as a response to incoming IPC connections
* (UnixStreamChannel::listen needs to be called for that to work).
* (UnixStreamChannel::listen() needs to be called for that to work).
*/
class UnixStreamChannel final : public Channel
{
public:
/**
* \brief UnixStreamChannel-related error
* \brief UnixStreamChannel-related error.
*/
class Error : public std::runtime_error
{
@@ -55,10 +55,10 @@ public:
};
/**
* \brief Create UnixStream channel for the specified endpoint
* \brief Create a UnixStream channel for the specified \p endpoint.
*
* To enable creation of faces upon incoming connections, one
* needs to explicitly call UnixStreamChannel::listen method.
* To enable the creation of faces upon incoming connections, one needs to
* explicitly call listen().
*/
UnixStreamChannel(const unix_stream::Endpoint& endpoint, bool wantCongestionMarking);
@@ -77,7 +77,7 @@ public:
}
/**
* \brief Start listening
* \brief Start listening.
*
* Enable listening on the Unix socket, waiting for incoming connections,
* and creating a face when a connection is made.
@@ -94,24 +94,18 @@ public:
void
listen(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed,
int backlog = boost::asio::local::stream_protocol::acceptor::max_connections);
int backlog = boost::asio::socket_base::max_listen_connections);
private:
void
accept(const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed);
void
handleAccept(const boost::system::error_code& error,
const FaceCreatedCallback& onFaceCreated,
const FaceCreationFailedCallback& onAcceptFailed);
private:
const unix_stream::Endpoint m_endpoint;
const bool m_wantCongestionMarking;
boost::asio::local::stream_protocol::acceptor m_acceptor;
boost::asio::local::stream_protocol::socket m_socket;
size_t m_size;
bool m_wantCongestionMarking;
size_t m_size = 0;
};
} // namespace nfd::face
+4 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
namespace nfd::face {
/** \brief Protocol factory for stream-oriented Unix sockets.
/**
* \brief Protocol factory for stream-oriented Unix sockets.
*/
class UnixStreamFactory final : public ProtocolFactory
{
@@ -48,7 +49,7 @@ public:
* will be created. The second call will just retrieve the existing
* channel.
*
* \returns always a valid pointer to a UnixStreamChannel object,
* \returns Always a valid pointer to a UnixStreamChannel object,
* an exception will be thrown if the channel cannot be created.
*/
shared_ptr<UnixStreamChannel>
+6 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,13 +27,15 @@
namespace nfd::face {
NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<boost::asio::local::stream_protocol>, UnixStreamTransport);
namespace local = boost::asio::local;
UnixStreamTransport::UnixStreamTransport(protocol::socket&& socket)
NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<local::stream_protocol>, UnixStreamTransport);
UnixStreamTransport::UnixStreamTransport(local::stream_protocol::socket&& socket)
: StreamTransport(std::move(socket))
{
static_assert(
std::is_same_v<std::remove_cv_t<protocol::socket::native_handle_type>, int>,
std::is_same_v<std::remove_cv_t<local::stream_protocol::socket::native_handle_type>, int>,
"The native handle type for UnixStreamTransport sockets must be 'int'"
);
+3 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -39,13 +39,13 @@ namespace nfd::face {
NFD_LOG_MEMBER_DECL_SPECIALIZED(StreamTransport<boost::asio::local::stream_protocol>);
/**
* \brief A Transport that communicates on a stream-oriented Unix domain socket
* \brief A Transport that communicates on a stream-oriented Unix domain socket.
*/
class UnixStreamTransport final : public StreamTransport<boost::asio::local::stream_protocol>
{
public:
explicit
UnixStreamTransport(protocol::socket&& socket);
UnixStreamTransport(boost::asio::local::stream_protocol::socket&& socket);
};
} // namespace nfd::face
+10 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -36,17 +36,16 @@ using Endpoint = boost::asio::ip::tcp::endpoint;
namespace nfd::face {
/**
* \brief Class implementing WebSocket-based channel to create faces
* \brief Class implementing a WebSocket-based channel to create faces.
*/
class WebSocketChannel final : public Channel
{
public:
/**
* \brief Create WebSocket channel for the local endpoint
* \brief Create a WebSocket channel for the given \p localEndpoint.
*
* To enable creation of faces upon incoming connections,
* one needs to explicitly call WebSocketChannel::listen method.
* The created channel is bound to the localEndpoint.
* To enable the creation of faces upon incoming connections, one needs to
* explicitly call listen(). The created channel is bound to \p localEndpoint.
*/
explicit
WebSocketChannel(const websocket::Endpoint& localEndpoint);
@@ -65,7 +64,7 @@ public:
/**
* \brief Enable listening on the local endpoint, accept connections,
* and create faces when remote host makes a connection
* and create faces when remote host makes a connection.
*
* \param onFaceCreated Callback to notify successful creation of a face
*/
@@ -73,12 +72,14 @@ public:
listen(const FaceCreatedCallback& onFaceCreated);
NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/** \pre listen hasn't been invoked
/**
* \pre listen() has not been invoked.
*/
void
setPingInterval(time::milliseconds interval);
/** \pre listen hasn't been invoked
/**
* \pre listen() has not been invoked.
*/
void
setPongTimeout(time::milliseconds timeout);
+5 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
namespace nfd::face {
/** \brief Protocol factory for WebSocket.
/**
* \brief Protocol factory for WebSocket.
*/
class WebSocketFactory final : public ProtocolFactory
{
@@ -44,13 +45,13 @@ public:
/**
* \brief Create WebSocket-based channel using websocket::Endpoint.
*
* websocket::Endpoint is really an alias for boost::asio::ip::tcp::endpoint.
* websocket::Endpoint is an alias for boost::asio::ip::tcp::endpoint.
*
* If this method called twice with the same endpoint, only one channel
* will be created. The second call will just retrieve the existing
* channel.
*
* \returns always a valid pointer to a WebSocketChannel object, an exception
* \returns Always a valid pointer to a WebSocketChannel object, an exception
* is thrown if it cannot be created.
*/
shared_ptr<WebSocketChannel>
+4 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -36,12 +36,13 @@ isLoopback(const boost::asio::ip::address& addr)
if (addr.is_loopback()) {
return true;
}
// Workaround for loopback IPv4-mapped IPv6 addresses
// see https://svn.boost.org/trac/boost/ticket/9084
else if (addr.is_v6()) {
if (addr.is_v6()) {
auto addr6 = addr.to_v6();
if (addr6.is_v4_mapped()) {
return addr6.to_v4().is_loopback();
return boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, addr6).is_loopback();
}
}
+20 -21
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -65,7 +65,7 @@ AccessStrategy::afterReceiveInterest(const Interest& interest, const FaceEndpoin
case RetxSuppressionResult::FORWARD:
return afterReceiveRetxInterest(interest, ingress, pitEntry);
case RetxSuppressionResult::SUPPRESS:
NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " retx-suppress");
NFD_LOG_INTEREST_FROM(interest, ingress, "suppressed");
return;
}
}
@@ -79,7 +79,7 @@ AccessStrategy::afterReceiveNewInterest(const Interest& interest, const FaceEndp
// has measurements for Interest Name?
if (mi != nullptr) {
NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " new-interest mi=" << miName);
NFD_LOG_INTEREST_FROM(interest, ingress, "new mi=" << miName);
// send to last working nexthop
bool isSentToLastNexthop = this->sendToLastNexthop(interest, ingress, pitEntry, *mi, fibEntry);
@@ -88,7 +88,7 @@ AccessStrategy::afterReceiveNewInterest(const Interest& interest, const FaceEndp
}
}
else {
NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " new-interest no-mi");
NFD_LOG_INTEREST_FROM(interest, ingress, "new no-mi");
}
// no measurements, or last working nexthop unavailable
@@ -105,8 +105,8 @@ void
AccessStrategy::afterReceiveRetxInterest(const Interest& interest, const FaceEndpoint& ingress,
const shared_ptr<pit::Entry>& pitEntry)
{
NFD_LOG_INTEREST_FROM(interest, ingress, "retx");
const auto& fibEntry = this->lookupFib(*pitEntry);
NFD_LOG_DEBUG(interest << " interestFrom " << ingress << " retx-forward");
this->multicast(interest, ingress.face, pitEntry, fibEntry);
}
@@ -116,29 +116,29 @@ AccessStrategy::sendToLastNexthop(const Interest& interest, const FaceEndpoint&
const fib::Entry& fibEntry)
{
if (mi.lastNexthop == face::INVALID_FACEID) {
NFD_LOG_DEBUG(pitEntry->getInterest() << " no-last-nexthop");
NFD_LOG_INTEREST_FROM(interest, ingress, "no-last-nexthop");
return false;
}
if (mi.lastNexthop == ingress.face.getId()) {
NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-is-downstream");
NFD_LOG_INTEREST_FROM(interest, ingress, "last-nexthop-is-downstream");
return false;
}
Face* outFace = this->getFace(mi.lastNexthop);
if (outFace == nullptr || !fibEntry.hasNextHop(*outFace)) {
NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-gone");
NFD_LOG_INTEREST_FROM(interest, ingress, "last-nexthop-gone");
return false;
}
if (wouldViolateScope(ingress.face, interest, *outFace)) {
NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-violates-scope");
NFD_LOG_INTEREST_FROM(interest, ingress, "last-nexthop-violates-scope");
return false;
}
auto rto = mi.rtt.getEstimatedRto();
NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << mi.lastNexthop
<< " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
NFD_LOG_INTEREST_FROM(interest, ingress, "to=" << mi.lastNexthop << " last-nexthop rto="
<< time::duration_cast<time::microseconds>(rto).count() << "us");
if (!this->sendInterest(interest, *outFace, pitEntry)) {
return false;
@@ -164,8 +164,8 @@ AccessStrategy::afterRtoTimeout(const weak_ptr<pit::Entry>& pitWeak,
Face* inFace = this->getFace(inFaceId);
if (inFace == nullptr) {
NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId
<< " inFace-gone " << inFaceId);
NFD_LOG_DEBUG(pitEntry->getName() << " timeout from=" << firstOutFaceId
<< " in-face-gone=" << inFaceId);
return;
}
@@ -178,8 +178,7 @@ AccessStrategy::afterRtoTimeout(const weak_ptr<pit::Entry>& pitWeak,
const Interest& interest = inRecord->getInterest();
const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId
<< " multicast-except " << firstOutFaceId);
NFD_LOG_DEBUG(pitEntry->getName() << " timeout from=" << firstOutFaceId << " multicast");
this->multicast(interest, *inFace, pitEntry, fibEntry, firstOutFaceId);
}
@@ -195,7 +194,8 @@ AccessStrategy::multicast(const Interest& interest, const Face& inFace,
wouldViolateScope(inFace, interest, outFace)) {
continue;
}
NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << outFace.getId() << " multicast");
NFD_LOG_DEBUG(interest.getName() << " nonce=" << interest.getNonce()
<< " multicast to=" << outFace.getId());
if (this->sendInterest(interest, outFace, pitEntry)) {
++nSent;
}
@@ -213,19 +213,18 @@ AccessStrategy::beforeSatisfyInterest(const Data& data, const FaceEndpoint& ingr
}
if (!pitEntry->hasInRecords()) { // already satisfied by another upstream
NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << ingress << " not-fastest");
NFD_LOG_DATA_FROM(data, ingress, "not-fastest");
return;
}
auto outRecord = pitEntry->getOutRecord(ingress.face);
if (outRecord == pitEntry->out_end()) { // no out-record
NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << ingress << " no-out-record");
if (outRecord == pitEntry->out_end()) {
NFD_LOG_DATA_FROM(data, ingress, "no-out-record");
return;
}
auto rtt = time::steady_clock::now() - outRecord->getLastRenewed();
NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << ingress
<< " rtt=" << time::duration_cast<time::microseconds>(rtt).count());
NFD_LOG_DATA_FROM(data, ingress, "rtt=" << time::duration_cast<time::microseconds>(rtt).count() << "us");
this->updateMeasurements(ingress.face, data, rtt);
}
+15 -18
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,7 +25,6 @@
#include "asf-strategy.hpp"
#include "algorithm.hpp"
#include "common/global.hpp"
#include "common/logger.hpp"
namespace nfd::fw::asf {
@@ -75,11 +74,11 @@ AsfStrategy::afterReceiveInterest(const Interest& interest, const FaceEndpoint&
if (!hasPendingOutRecords(*pitEntry)) {
auto* faceToUse = getBestFaceForForwarding(interest, ingress.face, fibEntry, pitEntry);
if (faceToUse == nullptr) {
NFD_LOG_DEBUG(interest << " new-interest from=" << ingress << " no-nexthop");
NFD_LOG_INTEREST_FROM(interest, ingress, "new no-nexthop");
sendNoRouteNack(ingress.face, pitEntry);
}
else {
NFD_LOG_DEBUG(interest << " new-interest from=" << ingress << " forward-to=" << faceToUse->getId());
NFD_LOG_INTEREST_FROM(interest, ingress, "new forward-to=" << faceToUse->getId());
forwardInterest(interest, *faceToUse, fibEntry, pitEntry);
sendProbe(interest, ingress, *faceToUse, fibEntry, pitEntry);
}
@@ -91,13 +90,12 @@ AsfStrategy::afterReceiveInterest(const Interest& interest, const FaceEndpoint&
auto suppressResult = m_retxSuppression->decidePerUpstream(*pitEntry, *faceToUse);
if (suppressResult == RetxSuppressionResult::SUPPRESS) {
// Cannot be sent on this face, interest was received within the suppression window
NFD_LOG_DEBUG(interest << " retx-interest from=" << ingress
<< " forward-to=" << faceToUse->getId() << " suppressed");
NFD_LOG_INTEREST_FROM(interest, ingress, "retx forward-to=" << faceToUse->getId() << " suppressed");
}
else {
// The retx arrived after the suppression period: forward it but don't probe, because
// probing was done earlier for this interest when it was newly received
NFD_LOG_DEBUG(interest << " retx-interest from=" << ingress << " forward-to=" << faceToUse->getId());
NFD_LOG_INTEREST_FROM(interest, ingress, "retx forward-to=" << faceToUse->getId());
auto* outRecord = forwardInterest(interest, *faceToUse, fibEntry, pitEntry);
if (outRecord && suppressResult == RetxSuppressionResult::FORWARD) {
m_retxSuppression->incrementIntervalForOutRecord(*outRecord);
@@ -111,17 +109,16 @@ AsfStrategy::afterReceiveInterest(const Interest& interest, const FaceEndpoint&
const auto& nexthops = fibEntry.getNextHops();
auto it = findEligibleNextHopWithEarliestOutRecord(ingress.face, interest, nexthops, pitEntry);
if (it == nexthops.end()) {
NFD_LOG_DEBUG(interest << " retx-interest from=" << ingress << " no eligible nexthop");
NFD_LOG_INTEREST_FROM(interest, ingress, "retx no-nexthop");
return;
}
auto& outFace = it->getFace();
auto suppressResult = m_retxSuppression->decidePerUpstream(*pitEntry, outFace);
if (suppressResult == RetxSuppressionResult::SUPPRESS) {
NFD_LOG_DEBUG(interest << " retx-interest from=" << ingress
<< " retry-to=" << outFace.getId() << " suppressed");
NFD_LOG_INTEREST_FROM(interest, ingress, "retx retry-to=" << outFace.getId() << " suppressed");
}
else {
NFD_LOG_DEBUG(interest << " retx-interest from=" << ingress << " retry-to=" << outFace.getId());
NFD_LOG_INTEREST_FROM(interest, ingress, "retx retry-to=" << outFace.getId());
// sendInterest() is used here instead of forwardInterest() because the measurements info
// were already attached to this face in the previous forwarding
auto* outRecord = sendInterest(interest, outFace, pitEntry);
@@ -137,25 +134,24 @@ AsfStrategy::beforeSatisfyInterest(const Data& data, const FaceEndpoint& ingress
{
NamespaceInfo* namespaceInfo = m_measurements.getNamespaceInfo(pitEntry->getName());
if (namespaceInfo == nullptr) {
NFD_LOG_DEBUG(pitEntry->getName() << " data from=" << ingress << " no-measurements");
NFD_LOG_DATA_FROM(data, ingress, "no-measurements");
return;
}
// Record the RTT between the Interest out to Data in
FaceInfo* faceInfo = namespaceInfo->getFaceInfo(ingress.face.getId());
if (faceInfo == nullptr) {
NFD_LOG_DEBUG(pitEntry->getName() << " data from=" << ingress << " no-face-info");
NFD_LOG_DATA_FROM(data, ingress, "no-face-info");
return;
}
auto outRecord = pitEntry->getOutRecord(ingress.face);
if (outRecord == pitEntry->out_end()) {
NFD_LOG_DEBUG(pitEntry->getName() << " data from=" << ingress << " no-out-record");
NFD_LOG_DATA_FROM(data, ingress, "no-out-record");
}
else {
faceInfo->recordRtt(time::steady_clock::now() - outRecord->getLastRenewed());
NFD_LOG_DEBUG(pitEntry->getName() << " data from=" << ingress
<< " rtt=" << faceInfo->getLastRtt() << " srtt=" << faceInfo->getSrtt());
NFD_LOG_DATA_FROM(data, ingress, "rtt=" << faceInfo->getLastRtt() << " srtt=" << faceInfo->getSrtt());
}
// Extend lifetime for measurements associated with Face
@@ -169,7 +165,7 @@ void
AsfStrategy::afterReceiveNack(const lp::Nack& nack, const FaceEndpoint& ingress,
const shared_ptr<pit::Entry>& pitEntry)
{
NFD_LOG_DEBUG(nack.getInterest() << " nack from=" << ingress << " reason=" << nack.getReason());
NFD_LOG_NACK_FROM(nack, ingress, "");
onTimeoutOrNack(pitEntry->getName(), ingress.face.getId(), true);
}
@@ -213,7 +209,8 @@ AsfStrategy::sendProbe(const Interest& interest, const FaceEndpoint& ingress, co
Interest probeInterest(interest);
probeInterest.refreshNonce();
NFD_LOG_TRACE("Sending probe " << probeInterest << " to=" << faceToProbe->getId());
NFD_LOG_DEBUG("Sending probe " << probeInterest.getName() << " nonce=" << probeInterest.getNonce()
<< " to=" << faceToProbe->getId() << " trigger-nonce=" << interest.getNonce());
forwardInterest(probeInterest, *faceToProbe, fibEntry, pitEntry);
m_probing.afterForwardingProbe(fibEntry, interest.getName());
+8 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -61,9 +61,9 @@ void
BestRouteStrategy::afterReceiveInterest(const Interest& interest, const FaceEndpoint& ingress,
const shared_ptr<pit::Entry>& pitEntry)
{
RetxSuppressionResult suppression = m_retxSuppression->decidePerPitEntry(*pitEntry);
auto suppression = m_retxSuppression->decidePerPitEntry(*pitEntry);
if (suppression == RetxSuppressionResult::SUPPRESS) {
NFD_LOG_DEBUG(interest << " from=" << ingress << " suppressed");
NFD_LOG_INTEREST_FROM(interest, ingress, "suppressed");
return;
}
@@ -78,8 +78,7 @@ BestRouteStrategy::afterReceiveInterest(const Interest& interest, const FaceEndp
});
if (it == nexthops.end()) {
NFD_LOG_DEBUG(interest << " from=" << ingress << " noNextHop");
NFD_LOG_INTEREST_FROM(interest, ingress, "new no-nexthop");
lp::NackHeader nackHeader;
nackHeader.setReason(lp::NackReason::NO_ROUTE);
this->sendNack(nackHeader, ingress.face, pitEntry);
@@ -88,7 +87,7 @@ BestRouteStrategy::afterReceiveInterest(const Interest& interest, const FaceEndp
}
Face& outFace = it->getFace();
NFD_LOG_DEBUG(interest << " from=" << ingress << " newPitEntry-to=" << outFace.getId());
NFD_LOG_INTEREST_FROM(interest, ingress, "new to=" << outFace.getId());
this->sendInterest(interest, outFace, pitEntry);
return;
}
@@ -102,19 +101,19 @@ BestRouteStrategy::afterReceiveInterest(const Interest& interest, const FaceEndp
if (it != nexthops.end()) {
Face& outFace = it->getFace();
this->sendInterest(interest, outFace, pitEntry);
NFD_LOG_DEBUG(interest << " from=" << ingress << " retransmit-unused-to=" << outFace.getId());
NFD_LOG_INTEREST_FROM(interest, ingress, "retx unused-to=" << outFace.getId());
return;
}
// find an eligible upstream that is used earliest
it = findEligibleNextHopWithEarliestOutRecord(ingress.face, interest, nexthops, pitEntry);
if (it == nexthops.end()) {
NFD_LOG_DEBUG(interest << " from=" << ingress << " retransmitNoNextHop");
NFD_LOG_INTEREST_FROM(interest, ingress, "retx no-nexthop");
}
else {
Face& outFace = it->getFace();
this->sendInterest(interest, outFace, pitEntry);
NFD_LOG_DEBUG(interest << " from=" << ingress << " retransmit-retry-to=" << outFace.getId());
NFD_LOG_INTEREST_FROM(interest, ingress, "retx retry-to=" << outFace.getId());
}
}
+3 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,12 +28,10 @@
#include "common/logger.hpp"
#include "face/channel.hpp"
#include <ndn-cxx/util/concepts.hpp>
#include <boost/asio/defer.hpp>
namespace nfd {
NDN_CXX_ASSERT_FORWARD_ITERATOR(FaceTable::const_iterator);
NFD_LOG_INIT(FaceTable);
Face*
@@ -104,7 +102,7 @@ FaceTable::remove(FaceId faceId)
" local=" << face->getLocalUri());
// defer Face deallocation, so that Transport isn't deallocated during afterStateChange signal
getGlobalIoService().post([face] {});
boost::asio::defer(getGlobalIoService(), [face] {});
}
FaceTable::ForwardRange
+3 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2020, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,8 @@
namespace nfd {
/** \brief Counters provided by Forwarder
/**
* \brief Counters provided by Forwarder.
*/
class ForwarderCounters
{
+42 -36
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -89,35 +89,41 @@ Forwarder::Forwarder(FaceTable& faceTable)
void
Forwarder::onIncomingInterest(const Interest& interest, const FaceEndpoint& ingress)
{
// receive Interest
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress << " interest=" << interest.getName());
interest.setTag(make_shared<lp::IncomingFaceIdTag>(ingress.face.getId()));
++m_counters.nInInterests;
// ensure the received Interest has a Nonce
auto nonce = interest.getNonce();
auto hopLimit = interest.getHopLimit();
// drop if HopLimit zero, decrement otherwise (if present)
if (interest.getHopLimit()) {
if (*interest.getHopLimit() == 0) {
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress << " interest=" << interest.getName()
<< " hop-limit=0");
if (hopLimit) {
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress << " interest=" << interest.getName()
<< " nonce=" << nonce << " hop-limit=" << static_cast<unsigned>(*hopLimit));
if (*hopLimit == 0) {
++ingress.face.getCounters().nInHopLimitZero;
// drop
return;
}
const_cast<Interest&>(interest).setHopLimit(*interest.getHopLimit() - 1);
const_cast<Interest&>(interest).setHopLimit(*hopLimit - 1);
}
else {
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress << " interest=" << interest.getName()
<< " nonce=" << nonce);
}
// /localhost scope control
bool isViolatingLocalhost = ingress.face.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
scope_prefix::LOCALHOST.isPrefixOf(interest.getName());
if (isViolatingLocalhost) {
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress
<< " interest=" << interest.getName() << " violates /localhost");
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress << " interest=" << interest.getName()
<< " nonce=" << nonce << " violates /localhost");
// drop
return;
}
// detect duplicate Nonce with Dead Nonce List
bool hasDuplicateNonceInDnl = m_deadNonceList.has(interest.getName(), interest.getNonce());
bool hasDuplicateNonceInDnl = m_deadNonceList.has(interest.getName(), nonce);
if (hasDuplicateNonceInDnl) {
// goto Interest loop pipeline
this->onInterestLoop(interest, ingress);
@@ -127,8 +133,8 @@ Forwarder::onIncomingInterest(const Interest& interest, const FaceEndpoint& ingr
// strip forwarding hint if Interest has reached producer region
if (!interest.getForwardingHint().empty() &&
m_networkRegionTable.isInProducerRegion(interest.getForwardingHint())) {
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress
<< " interest=" << interest.getName() << " reaching-producer-region");
NFD_LOG_DEBUG("onIncomingInterest in=" << ingress << " interest=" << interest.getName()
<< " nonce=" << nonce << " reaching-producer-region");
const_cast<Interest&>(interest).setForwardingHint({});
}
@@ -136,7 +142,7 @@ Forwarder::onIncomingInterest(const Interest& interest, const FaceEndpoint& ingr
shared_ptr<pit::Entry> pitEntry = m_pit.insert(interest).first;
// detect duplicate Nonce in PIT entry
int dnw = fw::findDuplicateNonce(*pitEntry, interest.getNonce(), ingress.face);
int dnw = fw::findDuplicateNonce(*pitEntry, nonce, ingress.face);
bool hasDuplicateNonceInPit = dnw != fw::DUPLICATE_NONCE_NONE;
if (ingress.face.getLinkType() == ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
// for p2p face: duplicate Nonce from same incoming face is not loop
@@ -164,26 +170,27 @@ Forwarder::onInterestLoop(const Interest& interest, const FaceEndpoint& ingress)
{
// if multi-access or ad hoc face, drop
if (ingress.face.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
NFD_LOG_DEBUG("onInterestLoop in=" << ingress
<< " interest=" << interest.getName() << " drop");
NFD_LOG_DEBUG("onInterestLoop in=" << ingress << " interest=" << interest.getName()
<< " nonce=" << interest.getNonce() << " drop");
return;
}
NFD_LOG_DEBUG("onInterestLoop in=" << ingress << " interest=" << interest.getName()
<< " send-Nack-duplicate");
<< " nonce=" << interest.getNonce() << " nack");
// send Nack with reason=DUPLICATE
// note: Don't enter outgoing Nack pipeline because it needs an in-record.
lp::Nack nack(interest);
nack.setReason(lp::NackReason::DUPLICATE);
ingress.face.sendNack(nack);
++m_counters.nOutNacks;
}
void
Forwarder::onContentStoreMiss(const Interest& interest, const FaceEndpoint& ingress,
const shared_ptr<pit::Entry>& pitEntry)
{
NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName());
NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName() << " nonce=" << interest.getNonce());
++m_counters.nCsMisses;
// attach HopLimit if configured and not present in Interest
@@ -209,7 +216,7 @@ Forwarder::onContentStoreMiss(const Interest& interest, const FaceEndpoint& ingr
Face* nextHopFace = m_faceTable.get(*nextHopTag);
if (nextHopFace != nullptr) {
NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName()
<< " nexthop-faceid=" << nextHopFace->getId());
<< " nonce=" << interest.getNonce() << " nexthop-faceid=" << nextHopFace->getId());
// go to outgoing Interest pipeline
// scope control is unnecessary, because privileged app explicitly wants to forward
this->onOutgoingInterest(interest, *nextHopFace, pitEntry);
@@ -226,7 +233,7 @@ void
Forwarder::onContentStoreHit(const Interest& interest, const FaceEndpoint& ingress,
const shared_ptr<pit::Entry>& pitEntry, const Data& data)
{
NFD_LOG_DEBUG("onContentStoreHit interest=" << interest.getName());
NFD_LOG_DEBUG("onContentStoreHit interest=" << interest.getName() << " nonce=" << interest.getNonce());
++m_counters.nCsHits;
data.setTag(make_shared<lp::IncomingFaceIdTag>(face::FACEID_CONTENT_STORE));
@@ -249,13 +256,14 @@ Forwarder::onOutgoingInterest(const Interest& interest, Face& egress,
{
// drop if HopLimit == 0 but sending on non-local face
if (interest.getHopLimit() == 0 && egress.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL) {
NFD_LOG_DEBUG("onOutgoingInterest out=" << egress.getId() << " interest=" << pitEntry->getName()
<< " non-local hop-limit=0");
NFD_LOG_DEBUG("onOutgoingInterest out=" << egress.getId() << " interest=" << interest.getName()
<< " nonce=" << interest.getNonce() << " non-local hop-limit=0");
++egress.getCounters().nOutHopLimitZero;
return nullptr;
}
NFD_LOG_DEBUG("onOutgoingInterest out=" << egress.getId() << " interest=" << pitEntry->getName());
NFD_LOG_DEBUG("onOutgoingInterest out=" << egress.getId() << " interest=" << interest.getName()
<< " nonce=" << interest.getNonce());
// insert out-record
auto it = pitEntry->insertOrUpdateOutRecord(egress, interest);
@@ -264,6 +272,7 @@ Forwarder::onOutgoingInterest(const Interest& interest, Face& egress,
// send Interest
egress.sendInterest(interest);
++m_counters.nOutInterests;
return &*it;
}
@@ -292,10 +301,9 @@ Forwarder::onInterestFinalize(const shared_ptr<pit::Entry>& pitEntry)
void
Forwarder::onIncomingData(const Data& data, const FaceEndpoint& ingress)
{
// receive Data
NFD_LOG_DEBUG("onIncomingData in=" << ingress << " data=" << data.getName());
data.setTag(make_shared<lp::IncomingFaceIdTag>(ingress.face.getId()));
++m_counters.nInData;
NFD_LOG_DEBUG("onIncomingData in=" << ingress << " data=" << data.getName());
// /localhost scope control
bool isViolatingLocalhost = ingress.face.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
@@ -388,16 +396,16 @@ Forwarder::onIncomingData(const Data& data, const FaceEndpoint& ingress)
void
Forwarder::onDataUnsolicited(const Data& data, const FaceEndpoint& ingress)
{
++m_counters.nUnsolicitedData;
// accept to cache?
auto decision = m_unsolicitedDataPolicy->decide(ingress.face, data);
NFD_LOG_DEBUG("onDataUnsolicited in=" << ingress << " data=" << data.getName()
<< " decision=" << decision);
if (decision == fw::UnsolicitedDataDecision::CACHE) {
// CS insert
m_cs.insert(data, true);
}
NFD_LOG_DEBUG("onDataUnsolicited in=" << ingress << " data=" << data.getName()
<< " decision=" << decision);
++m_counters.nUnsolicitedData;
}
bool
@@ -431,15 +439,13 @@ Forwarder::onOutgoingData(const Data& data, Face& egress)
void
Forwarder::onIncomingNack(const lp::Nack& nack, const FaceEndpoint& ingress)
{
// receive Nack
nack.setTag(make_shared<lp::IncomingFaceIdTag>(ingress.face.getId()));
++m_counters.nInNacks;
// if multi-access or ad hoc face, drop
if (ingress.face.getLinkType() != ndn::nfd::LINK_TYPE_POINT_TO_POINT) {
NFD_LOG_DEBUG("onIncomingNack in=" << ingress
<< " nack=" << nack.getInterest().getName() << "~" << nack.getReason()
<< " link-type=" << ingress.face.getLinkType());
NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
<< "~" << nack.getReason() << " link-type=" << ingress.face.getLinkType());
return;
}
@@ -448,7 +454,7 @@ Forwarder::onIncomingNack(const lp::Nack& nack, const FaceEndpoint& ingress)
// if no PIT entry found, drop
if (pitEntry == nullptr) {
NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
<< "~" << nack.getReason() << " no-PIT-entry");
<< "~" << nack.getReason() << " no-pit-entry");
return;
}
@@ -464,13 +470,13 @@ Forwarder::onIncomingNack(const lp::Nack& nack, const FaceEndpoint& ingress)
// if out-record has different Nonce, drop
if (nack.getInterest().getNonce() != outRecord->getLastNonce()) {
NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
<< "~" << nack.getReason() << " wrong-Nonce " << nack.getInterest().getNonce()
<< "~" << nack.getReason() << " nonce-mismatch " << nack.getInterest().getNonce()
<< "!=" << outRecord->getLastNonce());
return;
}
NFD_LOG_DEBUG("onIncomingNack in=" << ingress << " nack=" << nack.getInterest().getName()
<< "~" << nack.getReason() << " OK");
<< "~" << nack.getReason());
// record Nack on out-record
outRecord->setIncomingNack(nack);
+7 -9
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -67,10 +67,9 @@ MulticastStrategy::afterReceiveInterest(const Interest& interest, const FaceEndp
for (const auto& nexthop : nexthops) {
Face& outFace = nexthop.getFace();
RetxSuppressionResult suppressResult = m_retxSuppression->decidePerUpstream(*pitEntry, outFace);
auto suppressResult = m_retxSuppression->decidePerUpstream(*pitEntry, outFace);
if (suppressResult == RetxSuppressionResult::SUPPRESS) {
NFD_LOG_DEBUG(interest << " from=" << ingress << " to=" << outFace.getId() << " suppressed");
NFD_LOG_INTEREST_FROM(interest, ingress, "to=" << outFace.getId() << " suppressed");
continue;
}
@@ -78,7 +77,7 @@ MulticastStrategy::afterReceiveInterest(const Interest& interest, const FaceEndp
continue;
}
NFD_LOG_DEBUG(interest << " from=" << ingress << " pitEntry-to=" << outFace.getId());
NFD_LOG_INTEREST_FROM(interest, ingress, "to=" << outFace.getId());
auto* sentOutRecord = this->sendInterest(interest, outFace, pitEntry);
if (sentOutRecord && suppressResult == RetxSuppressionResult::FORWARD) {
m_retxSuppression->incrementIntervalForOutRecord(*sentOutRecord);
@@ -93,16 +92,15 @@ MulticastStrategy::afterNewNextHop(const fib::NextHop& nextHop,
// no need to check for suppression, as it is a new next hop
auto nextHopFaceId = nextHop.getFace().getId();
auto& interest = pitEntry->getInterest();
const auto& interest = pitEntry->getInterest();
// try to find an incoming face record that doesn't violate scope restrictions
for (const auto& r : pitEntry->getInRecords()) {
auto& inFace = r.getFace();
if (isNextHopEligible(inFace, interest, nextHop, pitEntry)) {
NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " pitEntry-to=" << nextHopFaceId);
NFD_LOG_INTEREST_FROM(interest, inFace.getId(), "new-nexthop to=" << nextHopFaceId);
this->sendInterest(interest, nextHop.getFace(), pitEntry);
break; // just one eligible incoming face record is enough
}
}
+5 -11
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -58,26 +58,20 @@ ProcessNackTraitsBase::processNack(const lp::Nack& nack, const Face& inFace,
auto inR = pitEntry->getInRecord(*lastFaceNotNacked);
if (inR != pitEntry->in_end()) {
// one out-record not Nacked, which is also a downstream
NFD_LOG_DEBUG(nack.getInterest() << " nack-from=" << inFace.getId() <<
" nack=" << nack.getReason() <<
" nack-to(bidirectional)=" << lastFaceNotNacked->getId() <<
" out-nack=" << outNack.getReason());
NFD_LOG_NACK_FROM(nack, inFace.getId(), "bidirectional nack-to=" << lastFaceNotNacked->getId()
<< " out-nack=" << outNack.getReason());
this->sendNackForProcessNackTraits(pitEntry, *lastFaceNotNacked, outNack);
return;
}
}
if (nOutRecordsNotNacked > 0) {
NFD_LOG_DEBUG(nack.getInterest() << " nack-from=" << inFace.getId() <<
" nack=" << nack.getReason() <<
" waiting=" << nOutRecordsNotNacked);
NFD_LOG_NACK_FROM(nack, inFace.getId(), "waiting=" << nOutRecordsNotNacked);
// continue waiting
return;
}
NFD_LOG_DEBUG(nack.getInterest() << " nack-from=" << inFace.getId() <<
" nack=" << nack.getReason() <<
" nack-to=all out-nack=" << outNack.getReason());
NFD_LOG_NACK_FROM(nack, inFace.getId(), "nack-to=all out-nack=" << outNack.getReason());
this->sendNacksForProcessNackTraits(pitEntry, outNack);
}
+2 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -66,8 +66,7 @@ RandomStrategy::afterReceiveInterest(const Interest& interest, const FaceEndpoin
[&] (const auto& nh) { return isNextHopEligible(ingress.face, interest, nh, pitEntry); });
if (nhs.empty()) {
NFD_LOG_DEBUG(interest << " from=" << ingress << " no nexthop");
NFD_LOG_INTEREST_FROM(interest, ingress, "no-nexthop");
lp::NackHeader nackHeader;
nackHeader.setReason(lp::NackReason::NO_ROUTE);
this->sendNack(nackHeader, ingress.face, pitEntry);
+11 -8
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -51,19 +51,22 @@ public:
Duration maxInterval = DEFAULT_MAX_INTERVAL,
float multiplier = DEFAULT_MULTIPLIER);
/** \brief Determines whether Interest is a retransmission per pit entry
* and if so, whether it shall be forwarded or suppressed.
/**
* \brief Determines whether Interest is a retransmission per PIT entry
* and if so, whether it shall be forwarded or suppressed.
*/
RetxSuppressionResult
decidePerPitEntry(pit::Entry& pitEntry);
/** \brief Determines whether Interest is a retransmission per upstream
* and if so, whether it shall be forwarded or suppressed.
/**
* \brief Determines whether Interest is a retransmission per upstream
* and if so, whether it shall be forwarded or suppressed.
*/
RetxSuppressionResult
decidePerUpstream(pit::Entry& pitEntry, Face& outFace);
/** \brief Increment the suppression interval for out record.
/**
* \brief Increment the suppression interval for an out-record.
*/
void
incrementIntervalForOutRecord(pit::OutRecord& outRecord);
@@ -75,8 +78,8 @@ private: // non-member operators (hidden friends)
friend std::ostream&
operator<<(std::ostream& os, const RetxSuppressionExponential& retxSupp)
{
return os << "RetxSuppressionExponential initial-interval=" << retxSupp.m_initialInterval
<< " max-interval=" << retxSupp.m_maxInterval
return os << "RetxSuppressionExponential initial-interval=" << retxSupp.m_initialInterval.count()
<< " max-interval=" << retxSupp.m_maxInterval.count()
<< " multiplier=" << retxSupp.m_multiplier;
}
+4 -14
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -26,22 +26,12 @@
#ifndef NFD_DAEMON_FW_RETX_SUPPRESSION_HPP
#define NFD_DAEMON_FW_RETX_SUPPRESSION_HPP
#include "core/common.hpp"
namespace nfd::fw {
enum class RetxSuppressionResult {
/** \brief Interest is new (not a retransmission)
*/
NEW,
/** \brief Interest is retransmission and should be forwarded
*/
FORWARD,
/** \brief Interest is retransmission and should be suppressed
*/
SUPPRESS
NEW, ///< Interest is new (not a retransmission).
FORWARD, ///< Interest is a retransmission and should be forwarded.
SUPPRESS, ///< Interest is a retransmission and should be suppressed.
};
} // namespace nfd::fw
+44 -41
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -34,6 +34,7 @@
#include <ndn-cxx/lp/prefix-announcement-header.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <boost/asio/post.hpp>
#include <boost/range/adaptor/reversed.hpp>
namespace nfd::fw {
@@ -76,7 +77,7 @@ SelfLearningStrategy::afterReceiveInterest(const Interest& interest, const FaceE
if (isNonDiscovery) { // "non-discovery" Interest
inRecordInfo->isNonDiscoveryInterest = true;
if (nexthops.empty()) { // return NACK if no matching FIB entry exists
NFD_LOG_DEBUG("NACK non-discovery Interest=" << interest << " from=" << ingress << " noNextHop");
NFD_LOG_INTEREST_FROM(interest, ingress, "non-discovery no-nexthop");
lp::NackHeader nackHeader;
nackHeader.setReason(lp::NackReason::NO_ROUTE);
this->sendNack(nackHeader, ingress.face, pitEntry);
@@ -104,7 +105,7 @@ SelfLearningStrategy::afterReceiveData(const Data& data, const FaceEndpoint& ing
{
auto outRecord = pitEntry->getOutRecord(ingress.face);
if (outRecord == pitEntry->out_end()) {
NFD_LOG_DEBUG("Data " << data.getName() << " from=" << ingress << " no out-record");
NFD_LOG_DATA_FROM(data, ingress, "no-out-record");
return;
}
@@ -132,11 +133,11 @@ void
SelfLearningStrategy::afterReceiveNack(const lp::Nack& nack, const FaceEndpoint& ingress,
const shared_ptr<pit::Entry>& pitEntry)
{
NFD_LOG_DEBUG("Nack for " << nack.getInterest() << " from=" << ingress
<< " reason=" << nack.getReason());
NFD_LOG_NACK_FROM(nack, ingress, "");
if (nack.getReason() == lp::NackReason::NO_ROUTE) { // remove FIB entries
BOOST_ASSERT(this->lookupFib(*pitEntry).hasNextHops());
NFD_LOG_DEBUG("Send NACK to all downstreams");
NFD_LOG_DEBUG("Send Nack to all downstreams");
this->sendNacks(nack.getHeader(), pitEntry);
renewRoute(nack.getInterest().getName(), ingress.face.getId(), 0_ms);
}
@@ -153,8 +154,7 @@ SelfLearningStrategy::broadcastInterest(const Interest& interest, const Face& in
continue;
}
NFD_LOG_DEBUG("send discovery Interest=" << interest << " from=" << inFace.getId() <<
" to=" << outFace.getId());
NFD_LOG_INTEREST_FROM(interest, inFace.getId(), "send discovery to=" << outFace.getId());
auto outRecord = this->sendInterest(interest, outFace, pitEntry);
if (outRecord != nullptr) {
outRecord->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = false;
@@ -173,8 +173,7 @@ SelfLearningStrategy::multicastInterest(const Interest& interest, const Face& in
}
Face& outFace = nexthop.getFace();
NFD_LOG_DEBUG("send non-discovery Interest=" << interest << " from=" << inFace.getId() <<
" to=" << outFace.getId());
NFD_LOG_INTEREST_FROM(interest, inFace.getId(), "send non-discovery to=" << outFace.getId());
auto outRecord = this->sendInterest(interest, outFace, pitEntry);
if (outRecord != nullptr) {
outRecord->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest = true;
@@ -190,26 +189,28 @@ SelfLearningStrategy::asyncProcessData(const shared_ptr<pit::Entry>& pitEntry, c
// (the PIT entry's expiry timer was set to 0 before dispatching)
this->setExpiryTimer(pitEntry, 1_s);
runOnRibIoService([this, pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data] {
rib::Service::get().getRibManager().slFindAnn(data.getName(),
[this, pitEntryWeak, inFaceId, data] (std::optional<ndn::PrefixAnnouncement> paOpt) {
if (paOpt) {
runOnMainIoService([this, pitEntryWeak, inFaceId, data, pa = std::move(*paOpt)] {
auto pitEntry = pitEntryWeak.lock();
auto inFace = this->getFace(inFaceId);
if (pitEntry && inFace) {
NFD_LOG_DEBUG("found PrefixAnnouncement=" << pa.getAnnouncedName());
data.setTag(make_shared<lp::PrefixAnnouncementTag>(lp::PrefixAnnouncementHeader(pa)));
this->sendDataToAll(data, pitEntry, *inFace);
this->setExpiryTimer(pitEntry, 0_ms);
}
else {
NFD_LOG_DEBUG("PIT entry or Face no longer exists");
}
});
}
boost::asio::post(getRibIoService(),
[this, pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data] {
rib::Service::get().getRibManager().slFindAnn(data.getName(),
[this, pitEntryWeak, inFaceId, data] (std::optional<ndn::PrefixAnnouncement> paOpt) {
if (paOpt) {
boost::asio::post(getMainIoService(),
[this, pitEntryWeak, inFaceId, data, pa = std::move(*paOpt)] {
auto pitEntry = pitEntryWeak.lock();
auto inFace = this->getFace(inFaceId);
if (pitEntry && inFace) {
NFD_LOG_DEBUG("Found PrefixAnnouncement=" << pa.getAnnouncedName());
data.setTag(make_shared<lp::PrefixAnnouncementTag>(lp::PrefixAnnouncementHeader(pa)));
this->sendDataToAll(data, pitEntry, *inFace);
this->setExpiryTimer(pitEntry, 0_ms);
}
else {
NFD_LOG_DEBUG("PIT entry or face no longer exists");
}
});
}
});
});
});
}
bool
@@ -237,24 +238,26 @@ void
SelfLearningStrategy::addRoute(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace,
const Data& data, const ndn::PrefixAnnouncement& pa)
{
runOnRibIoService([pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data, pa] {
rib::Service::get().getRibManager().slAnnounce(pa, inFaceId, ROUTE_RENEW_LIFETIME,
[] (RibManager::SlAnnounceResult res) {
NFD_LOG_DEBUG("Add route via PrefixAnnouncement with result=" << res);
});
});
boost::asio::post(getRibIoService(),
[pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data, pa] {
rib::Service::get().getRibManager().slAnnounce(pa, inFaceId, ROUTE_RENEW_LIFETIME,
[] (RibManager::SlAnnounceResult res) {
NFD_LOG_DEBUG("Add route via PrefixAnnouncement with result=" << res);
});
});
}
void
SelfLearningStrategy::renewRoute(const Name& name, FaceId inFaceId, time::milliseconds maxLifetime)
{
// renew route with PA or ignore PA (if route has no PA)
runOnRibIoService([name, inFaceId, maxLifetime] {
rib::Service::get().getRibManager().slRenew(name, inFaceId, maxLifetime,
[] (RibManager::SlAnnounceResult res) {
NFD_LOG_DEBUG("Renew route with result=" << res);
});
});
boost::asio::post(getRibIoService(),
[name, inFaceId, maxLifetime] {
rib::Service::get().getRibManager().slRenew(name, inFaceId, maxLifetime,
[] (RibManager::SlAnnounceResult res) {
NFD_LOG_DEBUG("Renew route with result=" << res);
});
});
}
} // namespace nfd::fw
+25 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -490,9 +490,10 @@ public:
} // namespace nfd::fw
/** \brief Registers a strategy
/**
* \brief Registers a forwarding strategy.
*
* This macro should appear once in .cpp of each strategy.
* This macro should appear once in the `.cpp` of each strategy.
*/
#define NFD_REGISTER_STRATEGY(S) \
static class NfdAuto ## S ## StrategyRegistrationClass \
@@ -504,4 +505,25 @@ public: \
} \
} g_nfdAuto ## S ## StrategyRegistrationVariable
/// Logs the reception of \p interest on \p ingress, followed by \p msg, at DEBUG level.
#define NFD_LOG_INTEREST_FROM(interest, ingress, msg) \
NFD_LOG_DEBUG("interest=" << (interest).getName() << \
" nonce=" << (interest).getNonce() << \
" from=" << (ingress) << \
' ' << msg)
/// Logs the reception of \p data on \p ingress, followed by \p msg, at DEBUG level.
#define NFD_LOG_DATA_FROM(data, ingress, msg) \
NFD_LOG_DEBUG("data=" << (data).getName() << \
" from=" << (ingress) << \
' ' << msg)
/// Logs the reception of \p nack on \p ingress, followed by \p msg, at DEBUG level.
#define NFD_LOG_NACK_FROM(nack, ingress, msg) \
NFD_LOG_DEBUG("nack=" << (nack).getInterest().getName() << \
" nonce=" << (nack).getInterest().getNonce() << \
" reason=" << (nack).getReason() << \
" from=" << (ingress) << \
' ' << msg)
#endif // NFD_DAEMON_FW_STRATEGY_HPP
+1 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -66,7 +66,6 @@ UnsolicitedDataPolicy::getPolicyNames()
return policyNames;
}
const std::string DropAllUnsolicitedDataPolicy::POLICY_NAME("drop-all");
NFD_REGISTER_UNSOLICITED_DATA_POLICY(DropAllUnsolicitedDataPolicy);
UnsolicitedDataDecision
@@ -75,7 +74,6 @@ DropAllUnsolicitedDataPolicy::decide(const Face&, const Data&) const
return UnsolicitedDataDecision::DROP;
}
const std::string AdmitLocalUnsolicitedDataPolicy::POLICY_NAME("admit-local");
NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitLocalUnsolicitedDataPolicy);
UnsolicitedDataDecision
@@ -87,7 +85,6 @@ AdmitLocalUnsolicitedDataPolicy::decide(const Face& inFace, const Data&) const
return UnsolicitedDataDecision::DROP;
}
const std::string AdmitNetworkUnsolicitedDataPolicy::POLICY_NAME("admit-network");
NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitNetworkUnsolicitedDataPolicy);
UnsolicitedDataDecision
@@ -99,7 +96,6 @@ AdmitNetworkUnsolicitedDataPolicy::decide(const Face& inFace, const Data&) const
return UnsolicitedDataDecision::DROP;
}
const std::string AdmitAllUnsolicitedDataPolicy::POLICY_NAME("admit-all");
NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitAllUnsolicitedDataPolicy);
UnsolicitedDataDecision
+10 -10
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -60,10 +60,10 @@ public:
public: // registry
template<typename P>
static void
registerPolicy(const std::string& policyName = P::POLICY_NAME)
registerPolicy(std::string_view policyName = P::POLICY_NAME)
{
BOOST_ASSERT(!policyName.empty());
auto r = getRegistry().insert_or_assign(policyName, [] { return make_unique<P>(); });
auto r = getRegistry().insert_or_assign(std::string(policyName), [] { return make_unique<P>(); });
BOOST_VERIFY(r.second);
}
@@ -96,7 +96,7 @@ public:
decide(const Face& inFace, const Data& data) const final;
public:
static const std::string POLICY_NAME;
static constexpr std::string_view POLICY_NAME{"drop-all"};
};
/**
@@ -109,7 +109,7 @@ public:
decide(const Face& inFace, const Data& data) const final;
public:
static const std::string POLICY_NAME;
static constexpr std::string_view POLICY_NAME{"admit-local"};
};
/**
@@ -122,7 +122,7 @@ public:
decide(const Face& inFace, const Data& data) const final;
public:
static const std::string POLICY_NAME;
static constexpr std::string_view POLICY_NAME{"admit-network"};
};
/**
@@ -135,7 +135,7 @@ public:
decide(const Face& inFace, const Data& data) const final;
public:
static const std::string POLICY_NAME;
static constexpr std::string_view POLICY_NAME{"admit-all"};
};
/**
@@ -146,9 +146,9 @@ using DefaultUnsolicitedDataPolicy = DropAllUnsolicitedDataPolicy;
} // namespace nfd::fw
/**
* \brief Registers an unsolicited data policy
* \param P A subclass of nfd::fw::UnsolicitedDataPolicy. \p P must have a static data
* member `POLICY_NAME` convertible to std::string that contains the policy name.
* \brief Registers an unsolicited data policy.
* \param P A subclass of nfd::fw::UnsolicitedDataPolicy. \p P must have a static const data
* member `POLICY_NAME` convertible to std::string_view that contains the policy name.
*/
#define NFD_REGISTER_UNSOLICITED_DATA_POLICY(P) \
static class NfdAuto ## P ## UnsolicitedDataPolicyRegistrationClass \
+4 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -70,7 +70,7 @@ namespace nfd {
/** \brief Executes NFD with RIB manager
*
* NFD (main forwarding procedure) and RIB manager execute in two different threads.
* Each thread has its own instances of global io_service and global scheduler.
* Each thread has its own instances of global io_context and global scheduler.
*
* When either of the daemons fails, execution of non-failed daemon will be terminated as
* well. In other words, when NFD fails, RIB manager will be terminated; when RIB manager
@@ -107,9 +107,9 @@ public:
// a separate thread) fails.
std::atomic_int retval(0);
boost::asio::io_service* const mainIo = &getGlobalIoService();
boost::asio::io_context* const mainIo = &getGlobalIoService();
setMainIoService(mainIo);
boost::asio::io_service* ribIo = nullptr;
boost::asio::io_context* ribIo = nullptr;
// Mutex and conditional variable to implement synchronization between main and RIB manager
// threads:
+6 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -38,11 +38,11 @@ CsManager::CsManager(Cs& cs, const ForwarderCounters& fwCounters,
, m_fwCounters(fwCounters)
{
registerCommandHandler<ndn::nfd::CsConfigCommand>("config",
std::bind(&CsManager::changeConfig, this, _4, _5));
[this] (auto&&, auto&&, auto&&, auto&&... args) { changeConfig(std::forward<decltype(args)>(args)...); });
registerCommandHandler<ndn::nfd::CsEraseCommand>("erase",
std::bind(&CsManager::erase, this, _4, _5));
registerStatusDatasetHandler("info", std::bind(&CsManager::serveInfo, this, _1, _2, _3));
[this] (auto&&, auto&&, auto&&, auto&&... args) { erase(std::forward<decltype(args)>(args)...); });
registerStatusDatasetHandler("info",
[this] (auto&&, auto&&, auto&&... args) { serveInfo(std::forward<decltype(args)>(args)...); });
}
void
@@ -99,7 +99,7 @@ CsManager::erase(const ControlParameters& parameters,
}
void
CsManager::serveInfo(const Name&, const Interest&, ndn::mgmt::StatusDatasetContext& context) const
CsManager::serveInfo(ndn::mgmt::StatusDatasetContext& context) const
{
ndn::nfd::CsInfo info;
info.setCapacity(m_cs.getLimit());
+2 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2021, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -62,8 +62,7 @@ private:
/** \brief Serve CS information dataset.
*/
void
serveInfo(const Name& topPrefix, const Interest& interest,
ndn::mgmt::StatusDatasetContext& context) const;
serveInfo(ndn::mgmt::StatusDatasetContext& context) const;
public:
static constexpr size_t ERASE_LIMIT = 256;
+10 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -48,16 +48,19 @@ FaceManager::FaceManager(FaceSystem& faceSystem,
{
// register handlers for ControlCommand
registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
std::bind(&FaceManager::createFace, this, _4, _5));
[this] (auto&&, auto&&, auto&&, auto&&... args) { createFace(std::forward<decltype(args)>(args)...); });
registerCommandHandler<ndn::nfd::FaceUpdateCommand>("update",
std::bind(&FaceManager::updateFace, this, _3, _4, _5));
[this] (auto&&, auto&&, auto&&... args) { updateFace(std::forward<decltype(args)>(args)...); });
registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
std::bind(&FaceManager::destroyFace, this, _4, _5));
[this] (auto&&, auto&&, auto&&, auto&&... args) { destroyFace(std::forward<decltype(args)>(args)...); });
// register handlers for StatusDataset
registerStatusDatasetHandler("list", std::bind(&FaceManager::listFaces, this, _3));
registerStatusDatasetHandler("channels", std::bind(&FaceManager::listChannels, this, _3));
registerStatusDatasetHandler("query", std::bind(&FaceManager::queryFaces, this, _2, _3));
registerStatusDatasetHandler("list",
[this] (auto&&, auto&&, auto&&... args) { listFaces(std::forward<decltype(args)>(args)...); });
registerStatusDatasetHandler("channels",
[this] (auto&&, auto&&, auto&&... args) { listChannels(std::forward<decltype(args)>(args)...); });
registerStatusDatasetHandler("query",
[this] (auto&&, auto&&... args) { queryFaces(std::forward<decltype(args)>(args)...); });
// register notification stream
m_postNotification = registerNotificationStream("events");
+8 -11
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -45,16 +45,15 @@ FibManager::FibManager(Fib& fib, const FaceTable& faceTable,
, m_faceTable(faceTable)
{
registerCommandHandler<ndn::nfd::FibAddNextHopCommand>("add-nexthop",
std::bind(&FibManager::addNextHop, this, _2, _3, _4, _5));
[this] (auto&&, auto&&, auto&&... args) { addNextHop(std::forward<decltype(args)>(args)...); });
registerCommandHandler<ndn::nfd::FibRemoveNextHopCommand>("remove-nexthop",
std::bind(&FibManager::removeNextHop, this, _2, _3, _4, _5));
registerStatusDatasetHandler("list", std::bind(&FibManager::listEntries, this, _1, _2, _3));
[this] (auto&&, auto&&, auto&&... args) { removeNextHop(std::forward<decltype(args)>(args)...); });
registerStatusDatasetHandler("list",
[this] (auto&&, auto&&, auto&&... args) { listEntries(std::forward<decltype(args)>(args)...); });
}
void
FibManager::addNextHop(const Name&, const Interest& interest,
ControlParameters parameters,
FibManager::addNextHop(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done)
{
setFaceForSelfRegistration(interest, parameters);
@@ -84,8 +83,7 @@ FibManager::addNextHop(const Name&, const Interest& interest,
}
void
FibManager::removeNextHop(const Name&, const Interest& interest,
ControlParameters parameters,
FibManager::removeNextHop(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done)
{
setFaceForSelfRegistration(interest, parameters);
@@ -121,8 +119,7 @@ FibManager::removeNextHop(const Name&, const Interest& interest,
}
void
FibManager::listEntries(const Name&, const Interest&,
ndn::mgmt::StatusDatasetContext& context)
FibManager::listEntries(ndn::mgmt::StatusDatasetContext& context)
{
for (const auto& entry : m_fib) {
const auto& nexthops = entry.getNextHops() |
+4 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2021, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -48,18 +48,15 @@ public:
private:
void
addNextHop(const Name& topPrefix, const Interest& interest,
ControlParameters parameters,
addNextHop(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done);
void
removeNextHop(const Name& topPrefix, const Interest& interest,
ControlParameters parameters,
removeNextHop(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done);
void
listEntries(const Name& topPrefix, const Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
listEntries(ndn::mgmt::StatusDatasetContext& context);
private:
void
+3 -4
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2021, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -35,7 +35,7 @@ ForwarderStatusManager::ForwarderStatusManager(Forwarder& forwarder, Dispatcher&
, m_startTimestamp(time::system_clock::now())
{
m_dispatcher.addStatusDataset("status/general", ndn::mgmt::makeAcceptAllAuthorization(),
std::bind(&ForwarderStatusManager::listGeneralStatus, this, _1, _2, _3));
[this] (auto&&, auto&&, auto&& ctx) { listGeneralStatus(std::forward<decltype(ctx)>(ctx)); });
}
ndn::nfd::ForwarderStatus
@@ -67,8 +67,7 @@ ForwarderStatusManager::collectGeneralStatus()
}
void
ForwarderStatusManager::listGeneralStatus(const Name&, const Interest&,
ndn::mgmt::StatusDatasetContext& context)
ForwarderStatusManager::listGeneralStatus(ndn::mgmt::StatusDatasetContext& context)
{
auto status = this->collectGeneralStatus();
const auto& wire = status.wireEncode();
+2 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -51,8 +51,7 @@ private:
* \brief Provides the general status dataset.
*/
void
listGeneralStatus(const Name& topPrefix, const Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
listGeneralStatus(ndn::mgmt::StatusDatasetContext& context);
private:
Forwarder& m_forwarder;
+3 -3
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -27,13 +27,13 @@
namespace nfd {
ManagerBase::ManagerBase(const std::string& module, Dispatcher& dispatcher)
ManagerBase::ManagerBase(std::string_view module, Dispatcher& dispatcher)
: m_module(module)
, m_dispatcher(dispatcher)
{
}
ManagerBase::ManagerBase(const std::string& module, Dispatcher& dispatcher,
ManagerBase::ManagerBase(std::string_view module, Dispatcher& dispatcher,
CommandAuthenticator& authenticator)
: m_module(module)
, m_dispatcher(dispatcher)
+9 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -53,9 +53,6 @@ public:
using std::runtime_error::runtime_error;
};
virtual
~ManagerBase();
const std::string&
getModule() const
{
@@ -64,13 +61,18 @@ public:
protected:
/**
* @warning if you use this constructor, you MUST override makeAuthorization()
* @warning If you use this constructor, you MUST override makeAuthorization().
*/
ManagerBase(const std::string& module, Dispatcher& dispatcher);
ManagerBase(std::string_view module, Dispatcher& dispatcher);
ManagerBase(const std::string& module, Dispatcher& dispatcher,
ManagerBase(std::string_view module, Dispatcher& dispatcher,
CommandAuthenticator& authenticator);
// ManagerBase is not supposed to be used polymorphically, so we make the destructor
// protected to prevent deletion of derived objects through a pointer to the base class,
// which would be UB when the destructor is non-virtual.
~ManagerBase();
NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED: // registrations to the dispatcher
// difference from mgmt::ControlCommand: accepts nfd::ControlParameters
using ControlCommandHandler = std::function<void(const ControlCommand& command,
+19 -18
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -30,9 +30,11 @@
#include "rib/rib.hpp"
#include "table/fib.hpp"
#include <boost/asio/defer.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/mgmt/nfd/rib-entry.hpp>
#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
#include <ndn-cxx/security/certificate-fetcher-direct-fetch.hpp>
namespace nfd {
@@ -60,11 +62,11 @@ RibManager::RibManager(rib::Rib& rib, ndn::Face& face, ndn::KeyChain& keyChain,
, m_isLocalhopEnabled(false)
{
registerCommandHandler<ndn::nfd::RibRegisterCommand>("register",
std::bind(&RibManager::registerEntry, this, _2, _3, _4, _5));
[this] (auto&&, auto&&, auto&&... args) { registerEntry(std::forward<decltype(args)>(args)...); });
registerCommandHandler<ndn::nfd::RibUnregisterCommand>("unregister",
std::bind(&RibManager::unregisterEntry, this, _2, _3, _4, _5));
registerStatusDatasetHandler("list", std::bind(&RibManager::listEntries, this, _1, _2, _3));
[this] (auto&&, auto&&, auto&&... args) { unregisterEntry(std::forward<decltype(args)>(args)...); });
registerStatusDatasetHandler("list",
[this] (auto&&, auto&&, auto&&... args) { listEntries(std::forward<decltype(args)>(args)...); });
}
void
@@ -215,8 +217,7 @@ RibManager::registerTopPrefix(const Name& topPrefix)
}
void
RibManager::registerEntry(const Name& topPrefix, const Interest& interest,
ControlParameters parameters,
RibManager::registerEntry(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done)
{
if (parameters.getName().size() > Fib::getMaxDepth()) {
@@ -246,8 +247,7 @@ RibManager::registerEntry(const Name& topPrefix, const Interest& interest,
}
void
RibManager::unregisterEntry(const Name&, const Interest& interest,
ControlParameters parameters,
RibManager::unregisterEntry(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done)
{
setFaceForSelfRegistration(interest, parameters);
@@ -263,7 +263,7 @@ RibManager::unregisterEntry(const Name&, const Interest& interest,
}
void
RibManager::listEntries(const Name&, const Interest&, ndn::mgmt::StatusDatasetContext& context)
RibManager::listEntries(ndn::mgmt::StatusDatasetContext& context)
{
auto now = time::steady_clock::now();
for (const auto& kv : m_rib) {
@@ -426,9 +426,8 @@ RibManager::fetchActiveFaces()
NFD_LOG_DEBUG("Fetching active faces");
m_nfdController.fetch<ndn::nfd::FaceDataset>(
std::bind(&RibManager::removeInvalidFaces, this, _1),
std::bind(&RibManager::onFetchActiveFacesFailure, this, _1, _2),
ndn::nfd::CommandOptions());
[this] (auto&&... args) { removeInvalidFaces(std::forward<decltype(args)>(args)...); },
[this] (auto&&... args) { onFetchActiveFacesFailure(std::forward<decltype(args)>(args)...); });
}
void
@@ -449,11 +448,12 @@ RibManager::removeInvalidFaces(const std::vector<ndn::nfd::FaceStatus>& activeFa
{
NFD_LOG_DEBUG("Checking for invalid face registrations");
std::set<uint64_t> activeFaceIds;
std::set<uint64_t> activeIds;
for (const auto& faceStatus : activeFaces) {
activeFaceIds.insert(faceStatus.getFaceId());
activeIds.insert(faceStatus.getFaceId());
}
getGlobalIoService().post([=] { m_rib.beginRemoveFailedFaces(activeFaceIds); });
boost::asio::defer(getGlobalIoService(),
[this, active = std::move(activeIds)] { m_rib.beginRemoveFailedFaces(active); });
// Reschedule the check for future clean up
scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
@@ -466,7 +466,8 @@ RibManager::onNotification(const ndn::nfd::FaceEventNotification& notification)
if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
NFD_LOG_DEBUG("Received notification for destroyed FaceId " << notification.getFaceId());
getGlobalIoService().post([this, id = notification.getFaceId()] { m_rib.beginRemoveFace(id); });
boost::asio::defer(getGlobalIoService(),
[this, id = notification.getFaceId()] { m_rib.beginRemoveFace(id); });
}
}
+5 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -32,6 +32,7 @@
#include <ndn-cxx/mgmt/nfd/controller.hpp>
#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/security/validator-config.hpp>
#include <ndn-cxx/util/scheduler.hpp>
@@ -199,22 +200,19 @@ private: // management Dispatcher related
/** \brief Serve rib/register command.
*/
void
registerEntry(const Name& topPrefix, const Interest& interest,
ControlParameters parameters,
registerEntry(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done);
/** \brief Serve rib/unregister command.
*/
void
unregisterEntry(const Name& topPrefix, const Interest& interest,
ControlParameters parameters,
unregisterEntry(const Interest& interest, ControlParameters parameters,
const ndn::mgmt::CommandContinuation& done);
/** \brief Serve rib/list dataset.
*/
void
listEntries(const Name& topPrefix, const Interest& interest,
ndn::mgmt::StatusDatasetContext& context);
listEntries(ndn::mgmt::StatusDatasetContext& context);
void
setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
+4 -5
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -43,12 +43,11 @@ StrategyChoiceManager::StrategyChoiceManager(StrategyChoice& strategyChoice,
, m_table(strategyChoice)
{
registerCommandHandler<ndn::nfd::StrategyChoiceSetCommand>("set",
std::bind(&StrategyChoiceManager::setStrategy, this, _4, _5));
[this] (auto&&, auto&&, auto&&, auto&&... args) { setStrategy(std::forward<decltype(args)>(args)...); });
registerCommandHandler<ndn::nfd::StrategyChoiceUnsetCommand>("unset",
std::bind(&StrategyChoiceManager::unsetStrategy, this, _4, _5));
[this] (auto&&, auto&&, auto&&, auto&&... args) { unsetStrategy(std::forward<decltype(args)>(args)...); });
registerStatusDatasetHandler("list",
std::bind(&StrategyChoiceManager::listChoices, this, _3));
[this] (auto&&, auto&&, auto&&... args) { listChoices(std::forward<decltype(args)>(args)...); });
}
void
+20 -7
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,28 +28,41 @@
namespace nfd::rib {
FibUpdate
FibUpdate::createAddUpdate(const Name& name, const uint64_t faceId, const uint64_t cost)
FibUpdate::createAddUpdate(const Name& name, uint64_t faceId, uint64_t cost)
{
FibUpdate update;
update.name = name;
update.faceId = faceId;
update.cost = cost;
update.action = ADD_NEXTHOP;
return update;
}
FibUpdate
FibUpdate::createRemoveUpdate(const Name& name, const uint64_t faceId)
FibUpdate::createRemoveUpdate(const Name& name, uint64_t faceId)
{
FibUpdate update;
update.name = name;
update.faceId = faceId;
update.action = REMOVE_NEXTHOP;
return update;
}
std::ostream&
operator<<(std::ostream& os, const FibUpdate& update)
{
os << "FibUpdate(" << update.name << ", "
<< "faceid: " << update.faceId << ", ";
if (update.action == FibUpdate::ADD_NEXTHOP) {
os << "cost: " << update.cost << ", "
<< "action: ADD_NEXTHOP";
}
else {
os << "action: REMOVE_NEXTHOP";
}
return os << ")";
}
} // namespace nfd::rib
+27 -47
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2022, Regents of the University of California,
* Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,66 +28,46 @@
#include "core/common.hpp"
#include <boost/operators.hpp>
namespace nfd::rib {
/** \class FibUpdate
* \brief represents a FIB update
/**
* \brief Represents a FIB update.
*/
class FibUpdate
class FibUpdate : private boost::equality_comparable<FibUpdate>
{
public:
FibUpdate()
: faceId(0)
, cost(0)
{
}
bool
operator==(const FibUpdate& other) const
{
return (this->name == other.name &&
this->faceId == other.faceId &&
this->cost == other.cost &&
this->action == other.action);
}
static FibUpdate
createAddUpdate(const Name& name, const uint64_t faceId, const uint64_t cost);
static FibUpdate
createRemoveUpdate(const Name& name, const uint64_t faceId);
enum Action {
ADD_NEXTHOP = 0,
REMOVE_NEXTHOP = 1
REMOVE_NEXTHOP = 1,
};
static FibUpdate
createAddUpdate(const Name& name, uint64_t faceId, uint64_t cost);
static FibUpdate
createRemoveUpdate(const Name& name, uint64_t faceId);
public: // non-member operators (hidden friends)
friend bool
operator==(const FibUpdate& lhs, const FibUpdate& rhs) noexcept
{
return lhs.name == rhs.name &&
lhs.faceId == rhs.faceId &&
lhs.cost == rhs.cost &&
lhs.action == rhs.action;
}
public:
Name name;
uint64_t faceId;
uint64_t cost;
uint64_t faceId = 0;
uint64_t cost = 0;
Action action;
};
inline std::ostream&
operator<<(std::ostream& os, const FibUpdate& update)
{
os << "FibUpdate("
<< " Name: " << update.name << ", "
<< "faceId: " << update.faceId << ", ";
if (update.action == FibUpdate::ADD_NEXTHOP) {
os << "cost: " << update.cost << ", "
<< "action: ADD_NEXTHOP";
}
else {
os << "action: REMOVE_NEXTHOP";
}
os << ")";
return os;
}
std::ostream&
operator<<(std::ostream& os, const FibUpdate& update);
} // namespace nfd::rib
Loaded 100 of 241 files, more files were not shown because too many files have changed in this diff. Show more