Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bc57b880b | ||
|
|
9b877c3a23 | ||
|
|
23135a4cdd | ||
|
|
6ba08cd5cb | ||
|
|
e277f8b9e8 | ||
|
|
9a63bf22d0 | ||
|
|
ef6a528ae0 | ||
|
|
05bd6c2d69 | ||
|
|
a9ec67c52b | ||
|
|
d7083a507f | ||
|
|
c5a9f81fce | ||
|
|
0a05f7aea6 | ||
|
|
c0df94ed10 | ||
|
|
9c36a65b11 | ||
|
|
1e0c88e184 | ||
|
|
9bf64cc60d | ||
|
|
d91fe6d921 | ||
|
|
5d64263dcb | ||
|
|
a9e1ab2664 | ||
|
|
910232fce0 | ||
|
|
decaf509b4 | ||
|
|
8f0b8b6063 | ||
|
|
11f1fd8340 | ||
|
|
bf2e67fb14 | ||
|
|
5b15e2fe97 | ||
|
|
95afc6d8a4 | ||
|
|
653eb07e29 | ||
|
|
6bf94c02f5 | ||
|
|
191a7a24e6 | ||
|
|
ae43030f6f | ||
|
|
63b3ae818f | ||
|
|
4064127b97 | ||
|
|
d6ea0b1e0e | ||
|
|
c5e3e7a55d | ||
|
|
bf4c131f82 | ||
|
|
39c67f6291 | ||
|
|
269b702f3d |
No files matched your search
@@ -0,0 +1,8 @@
|
||||
Dockerfile
|
||||
|
||||
/build/
|
||||
.waf-*-*/
|
||||
.waf3-*-*/
|
||||
.lock-waf*
|
||||
|
||||
/VERSION.info
|
||||
+10
-58
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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).
|
||||
@@ -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
@@ -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
@@ -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
@@ -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&
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'"
|
||||
);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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,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
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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() |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
Reference in new issue
Block a user