Compare commits

...
29 Commits
Author SHA1 Message Date
Alexander Afanasyev 2fc649bfc6 docs+build: Prepare release of version 0.3.4
Change-Id: I7e0276ce210cf5322fd5f3195821b3edee74fc64
Refs: #3132
2015-08-31 09:10:26 -07:00
Junxiao Shi 67ba8d28df fw: rename BroadcastStrategy to MulticastStrategy
BroadcastStrategy is temporarily retained for backwards compatibility.

This commit also updates nfd.conf and ndn-autoconfig to use MulticastStrategy
in place of BroadcastStrategy.

refs #3011

Change-Id: I011f1cf75db26b3c93552f8322a0bba4ce8dd033
2015-08-21 21:21:28 -07:00
Yukai Tu 375dcb0bd6 face: minimal UDP permanent face
Change-Id: I44f652b95c911667107fd30829c7ce6e5acab706
Refs: #2989
2015-08-18 15:04:21 -07:00
Junxiao Shi 0e092aee5c mgmt: revert router name configuration options
This reverts commit ee7c8441c8.
That implementation introduces a global static variable which conflicts with ndnSIM.

refs #3026

Change-Id: I803e2ab497f71ec259d96d7b094ba0d04718c344
2015-08-18 15:03:15 -07:00
Vince Lehman faa5c0cd3c fw: Correct log message in onContentStoreHit
refs: #3114

Change-Id: I918cffc5d0551484b4cc31a4b7d6aeb73b8969ae
2015-08-18 15:02:25 -07:00
Spyridon Mastorakis 149e02cf7d Enhance exception throwing with Boost Exception library
Change-Id: I471023fc23ffaebe04d9668426b4c1b03e4919aa
Refs: #2541
2015-08-17 16:17:33 -07:00
Alexander Afanasyev a714792b03 docs: Remove nrd manpage
Change-Id: Ib6185c5e32ccbe01ea3803e2e9fb50749ffc9bfe
Refs: #2489
2015-08-09 23:51:06 -07:00
Alexander Afanasyev 66c569ddcc mgmt: Fix compilation and test cases when dropping privileges is not supported
Change-Id: I7da7eca3e5019dd5a7ed20b26f6e0c3260a03850
Refs: #3064, #2447
2015-08-09 23:45:13 -07:00
Alexander Afanasyev 3f41ade02d daemon: Reload face_system section of the config file when NIC configuration changes
The main desired effect of the reloading is re-creation of multicast
faces, e.g., when a new interface appears in the system.

Change-Id: I8384e5f96285ddca363981c92e1b6de39e0072ef
Refs: #2460
2015-08-07 12:17:14 -07:00
Minsheng Zhang 0315269228 table: add CS policy LRU
Change-Id: Ief9e3d993782730069cedc8a99b8011d5d18ce7c
refs: #2219
2015-08-04 12:32:08 -07:00
Stumble 62b19a6c09 docs: add spec of prefixes that are automaticly registered upon discovery of hub
Change-Id: I26a19e4c0f3608e0f159801e63e201d2d376d0ed
Refs: #2718
2015-08-03 18:15:07 -07:00
Yukai Tu 7c90e6dfea face: ProtocolFactory::createFace with FacePersistency
Change-Id: If02510bd631e9aaa63b3cca89ced31a42e192ded
Refs: #2989
2015-07-29 23:50:25 +08:00
Joao Pereira 4e274ac915 nfd-status-http-server: erroneous <!DOCTYPE html> display
refs: #3019

Change-Id: I9b400446c12ed1b6b0899dced0d9b4aff8720d4c
2015-07-23 11:54:52 -04:00
Vince Lehman ee7c8441c8 mgmt: Add router name configuration options
refs: #3026

Change-Id: I44250476e7e7f25cbc2b40d6a59f64b55872b24a
2015-07-17 19:06:24 -07:00
Vince Lehman c1dfdb44da rib: Accept KeyChain in RibManager constructor
refs: #2390

Change-Id: I45c9aae4bb111d75de63dcbcba4b3e6296eb2426
2015-07-17 08:18:28 -07:00
Alexander Afanasyev a4527cc837 ci: Fix TravisCI script
Change-Id: Ic5d725eb825b7db71735f865852685830dacfffd
Refs: #3041
2015-07-15 22:39:20 +08:00
hwyuan 8082993f7f table: Remove useless boolean in NameTree::const_iterator::operator++
Refs: #2808

Change-Id: Ief819d46a4c44eede5e1fecb951fb3e6002ad409
2015-07-12 19:41:38 -07:00
Alexander Afanasyev b81cff966e ci: Enable automatic dependency installation in Jenkins scripts
This commit also unifies TravisCI dependency installation using Jenkins
scripts.

Change-Id: Ia7bae2e2f31e781c07acea729d61fa07345760ab
Refs: #2843
2015-07-12 10:50:31 +08:00
Yukai Tu 731f0d70fa face: replace isOnDemand with FacePersistency
Change-Id: Ie6995b2d03bbb90faad158de2b055f72dd9ba73d
Refs: #2989
2015-07-09 07:46:52 -07:00
Joao Pereira 08f07016a3 ci: build ndn-cxx as shared library
refs #2992

Change-Id: Ia65a5d1868d2a63b30adf3bd496be071bc57dd6b
2015-07-08 03:52:25 -07:00
Alexander Afanasyev 2666473042 docs+build: Prepare release of version 0.3.3
Change-Id: Ia53f820fb60e8a9ed5da0ac1667b8d10ef79c414
Refs: #2812
2015-07-01 11:23:12 -07:00
Joao Pereira 5b6deaea18 docs: Fix indentation in nfdc manpage
refs #2995

Change-Id: I154b1ccc73022f59ff8166d4353ee3a23dc75215
2015-06-30 16:03:20 -07:00
Yukai Tu 971d3c2b09 tools: Simplify nfd-status using SegmentFetcher
refs #2456

Change-Id: I5beb402b211717816ae11d3474b41ade15c7418c
2015-06-29 09:47:43 -07:00
Alexander Afanasyev dbe4f9fefe tests: Fix compilation errors because of changes ndn-cxx library
Change-Id: I10fb7eb366a03c2e06e6d2efefdde8a9dd0da724
Refs: #2951
2015-06-28 11:24:51 -07:00
Alexander Afanasyev 692842d6ad rib: Avoid deprecated nfd::CommandOptions::setSigningIdentity method
Change-Id: Id98538d96368c67ac1db939e0ad0fd43ec0c6ab9
Refs: #2893
2015-06-23 14:26:45 -07:00
Minsheng Zhang cb6e05f2dd table: add CS policy interface
Change-Id: I1946fe03ca00150b1ff9f08acae48c01bc569904
Refs: #1207
2015-06-12 10:03:17 -05:00
Junxiao Shi 5620fb2ac9 tools: deprecate ndn-tlv-peek and ndn-tlv-poke
refs #2817

Change-Id: Iee198533659320bf2e9219b92195e06a3ba2b25f
2015-06-07 20:59:38 -07:00
Junxiao Shi 965d3a4e72 fw: AccessStrategy avoid loop back new Interest
refs #2831

Change-Id: I1680fd62cdf8f11eaa7817dd6d4b7794c305c5eb
2015-06-01 06:55:23 -07:00
Eric Newberry 187ade8566 contrib: Add unit file and instructions for systemd
refs #1586

Change-Id: I06b91804fc8b8613560ef98687307f56262689fb
2015-05-15 14:43:31 -07:00
113 changed files with 2357 additions and 841 deletions

No files matched your search

-39
View File
@@ -1,39 +0,0 @@
#!/usr/bin/env bash
set -x
set -e
cd /tmp
BUILD="no"
if [ ! -d ndn-cxx ]; then
git clone --depth 1 git://github.com/named-data/ndn-cxx
cd ndn-cxx
BUILD="yes"
else
cd ndn-cxx
INSTALLED_VERSION=`git rev-parse HEAD || echo NONE`
sudo rm -Rf latest-version
git clone --depth 1 git://github.com/named-data/ndn-cxx latest-version
cd latest-version
LATEST_VERSION=`git rev-parse HEAD || echo UNKNOWN`
cd ..
rm -Rf latest-version
if [ "$INSTALLED_VERSION" != "$LATEST_VERSION" ]; then
cd ..
sudo rm -Rf ndn-cxx
git clone --depth 1 git://github.com/named-data/ndn-cxx
cd ndn-cxx
BUILD="yes"
fi
fi
sudo rm -Rf /usr/local/include/ndn-cxx
sudo rm -f /usr/local/lib/libndn-cxx*
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx*
if [ "$BUILD" = "yes" ]; then
sudo ./waf distclean -j1 --color=yes
fi
./waf configure -j1 --color=yes --without-osx-keychain
./waf -j1 --color=yes
sudo ./waf install -j1 --color=yes
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
if has OSX $NODE_LABELS; then
if has OSX-10.8 $NODE_LABELS; then
EXTRA_FLAGS=--c++11
fi
set -x
brew update
brew upgrade
brew install boost pkg-config cryptopp $EXTRA_FLAGS
brew cleanup
fi
if has Ubuntu $NODE_LABELS; then
BOOST_PKG=libboost-all-dev
if has Ubuntu-12.04 $NODE_LABELS; then
BOOST_PKG=libboost1.48-all-dev
fi
set -x
sudo apt-get update -qq -y
sudo apt-get -qq -y install build-essential pkg-config $BOOST_PKG \
libcrypto++-dev libsqlite3-dev libpcap-dev
fi
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -x
set -e
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "$JDIR"/util.sh
pushd /tmp >/dev/null
INSTALLED_VERSION=$((cd ndn-cxx && git rev-parse HEAD) 2>/dev/null || echo NONE)
sudo rm -Rf ndn-cxx-latest
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
LATEST_VERSION=$((cd ndn-cxx-latest && git rev-parse HEAD) 2>/dev/null || echo UNKNOWN)
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -Rf ndn-cxx
mv ndn-cxx-latest ndn-cxx
else
sudo rm -Rf ndn-cxx-latest
fi
sudo rm -Rf /usr/local/include/ndn-cxx
sudo rm -f /usr/local/lib/libndn-cxx*
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx*
pushd ndn-cxx >/dev/null
./waf configure -j1 --color=yes --enable-shared --disable-static --without-osx-keychain
./waf -j1 --color=yes
sudo ./waf install -j1 --color=yes
popd >/dev/null
popd >/dev/null
if has Linux $NODE_LABELS; then
sudo ldconfig
elif has FreeBSD $NODE_LABELS; then
sudo ldconfig -a
fi
+30
View File
@@ -0,0 +1,30 @@
CONTINUOUS INTEGRATION SCRIPTS
==============================
Environment Variables Used in Build Scripts
-------------------------------------------
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
build scripts to select proper behavior for different OS.
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
Possible values for Linux OS:
* `[OS_TYPE]`: `Linux`
* `[DISTRO_TYPE]`: `Ubuntu`
* `[DISTRO_VERSION]`: `Ubuntu-12.04`, `Ubuntu-14.04`, `Ubuntu-15.04`
Possible values of OSX OS:
* `[OS_TYPE]`: `OSX`
* `[DISTRO_TYPE]`: `OSX` (can be absent)
* `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.9`, `OSX-10.8`, `OSX-10.7`
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
the build scripts can perform different tasks.
Possible values:
* empty: default build process
* `code-coverage` (Linux OS is assumed): build process with code coverage analysis
+9
View File
@@ -0,0 +1,9 @@
has() {
local p=$1
shift
local x
for x in "$@"; do
[[ "${x}" == "${p}" ]] && return 0
done
return 1
}
+4 -4
View File
@@ -1,4 +1,4 @@
# For Ubuntu only
sudo: true
language: cpp
os:
- linux
@@ -8,8 +8,8 @@ notifications:
email:
on_success: always
on_failure: always
before_install:
- travis_retry sudo apt-get update
- travis_retry sudo apt-get install -qq libssl-dev libpcap-dev libboost1.48-all-dev libcrypto++-dev libsqlite3-dev
script:
- if [[ $TRAVIS_OS_NAME == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-12.04"; fi
- if [[ $TRAVIS_OS_NAME == osx ]]; then export NODE_LABELS="OSX OSX-10.10"; fi
- echo $NODE_LABELS
- ./.jenkins
+4
View File
@@ -73,3 +73,7 @@ in the library:
* Tai-Lin Chu <https://www.linkedin.com/pub/tai-lin-chu/55/5b2/669>
* Spyridon Mastorakis <http://cs.ucla.edu/~mastorakis/>
* Eric Newberry <http://ericnewberry.com>
* Yukai Tu <tuyukai1994@gmail.com>
* João Pereira <http://website.jpereira.co.uk>
* Mathias Gibbens <gibmat@cs.arizona.edu>
+1
View File
@@ -71,6 +71,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/throw_exception.hpp>
namespace nfd {
+130
View File
@@ -0,0 +1,130 @@
Starting NFD on Linux with systemd
==================================
Newer versions of Ubuntu (starting with 15.04) and some other Linux distributions, including Debian
use systemd to start system daemons, monitor their health, and restart them when they die.
Initial setup
-------------
* Edit `nfd.service`, correcting the paths to the `nfd` executable, configuration, and
``HOME`` directories.
* Copy the systemd config file for NFD to the proper directory
sudo cp nfd.service /etc/systemd/system
* Reload the systemd manager configuration
sudo systemctl daemon-reload
### Assumptions in the default scripts
* `nfd` is installed into `/usr/local/bin`
* Configuraton file is `/usr/local/etc/ndn/nfd.conf`
* `nfd` will be run as root
* Log files will be written to `/usr/local/var/log/ndn` folder, which is owned by user `ndn`
### Creating users
If the `ndn` user and group do not exist, they need to be manually created.
# Create group `ndn`
sudo addgroup --system ndn
# Create user `ndn`
sudo adduser --system \
--disabled-login \
--ingroup ndn \
--home /nonexistent \
--gecos "NDN User" \
--shell /bin/false \
ndn
### Creating folders
Folder `/usr/local/var/log/ndn` should be created and assigned proper user and group:
sudo mkdir -p /usr/local/var/log/ndn
sudo chown -R ndn:ndn /usr/local/var/log/ndn
`HOME` directory for `nfd` should be created prior to starting. This is necessary to manage
unique security credentials for the daemon.
# Create HOME and generate self-signed NDN certificate for nfd
sudo sh -c ' \
mkdir -p /usr/local/var/lib/ndn/nfd/.ndn; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-keygen /localhost/daemons/nfd | ndnsec-install-cert -; \
'
### Configuring NFD's security
NFD sample configuration allows anybody to create faces, add nexthops to FIB, and set
strategy choice for namespaces. While such settings could be a good start, it is
generally not a good idea to run NFD in this mode.
While thorough discussion about the security configuration of NFD is outside the scope of
this document, at least the following change should be done in ``nfd.conf`` in the
authorize section:
authorizations
{
authorize
{
certfile certs/localhost_daemons_nfd.ndncert
privileges
{
faces
fib
strategy-choice
}
}
authorize
{
certfile any
privileges
{
faces
strategy-choice
}
}
}
While this configuration still allows the management of faces and updating strategy choice by
anyone, only NFD's RIB Manager (i.e., NFD itself) is allowed to manage FIB.
As the final step to make this configuration work, nfd's self-signed certificate needs to
be exported into the `localhost_daemons_nfd.ndncert` file:
sudo sh -c '\
mkdir -p /usr/local/etc/ndn/certs || true; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-dump-certificate -i /localhost/daemons/nfd > \
/usr/local/etc/ndn/certs/localhost_daemons_nfd.ndncert; \
'
Enable auto-start
-----------------
After copying the provided upstart script, auto-start of the `nfd` daemon can be enabled with:
sudo systemctl enable nfd
To manually start it, use the following command:
sudo systemctl start nfd
Disable auto-start
------------------
To stop the `nfd` daemon, use the following command:
sudo systemctl stop nfd
To permanently stop the `nfd` daemon and disable it from being automatically started on reboot,
disable the service:
sudo systemctl disable nfd
+42
View File
@@ -0,0 +1,42 @@
# Copyright (c) 2015, Regents of the University of California,
# Arizona Board of Regents,
# Colorado State University,
# University Pierre & Marie Curie, Sorbonne University,
# Washington University in St. Louis,
# Beijing Institute of Technology,
# The University of Memphis.
#
# This file is part of NFD (Named Data Networking Forwarding Daemon).
# See AUTHORS.md for complete list of NFD authors and contributors.
#
# NFD is free software: you can redistribute it and/or modify it under the terms
# of the GNU General Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version.
#
# NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
#
# Author: Eric Newberry <enewberry@email.arizona.edu>
[Unit]
Description=NDN Forwarding Daemon
Documentation=man:nfd man:nfdc man:nfd-status
Wants=network-online.target
After=network-online.target
[Service]
Environment=HOME=/usr/local/var/lib/ndn/nfd
ExecStart=/usr/local/bin/nfd --config /usr/local/etc/ndn/nfd.conf
ExecStartPost=/bin/sh -ec 'sleep 2; if [ -f /usr/local/etc/ndn/nfd-init.sh ]; then . /usr/local/etc/ndn/nfd-init.sh; fi'
Restart=on-failure
ProtectSystem=full
PrivateTmp=yes
PrivateDevices=yes
ProtectHome=yes
[Install]
WantedBy=multi-user.target
+4 -4
View File
@@ -40,7 +40,7 @@ ConfigFile::throwErrorOnUnknownSection(const std::string& filename,
msg += filename;
msg += ": no module subscribed for section \"" + sectionName + "\"";
throw ConfigFile::Error(msg);
BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
}
void
@@ -73,7 +73,7 @@ ConfigFile::parse(const std::string& filename, bool isDryRun)
{
std::string msg = "Failed to read configuration file: ";
msg += filename;
throw Error(msg);
BOOST_THROW_EXCEPTION(Error(msg));
}
parse(inputFile, isDryRun, filename);
inputFile.close();
@@ -100,7 +100,7 @@ ConfigFile::parse(std::istream& input, bool isDryRun, const std::string& filenam
msg << "Failed to parse configuration file";
msg << " " << filename;
msg << " " << error.message() << " line " << error.line();
throw Error(msg.str());
BOOST_THROW_EXCEPTION(Error(msg.str()));
}
process(isDryRun, filename);
@@ -124,7 +124,7 @@ ConfigFile::process(bool isDryRun, const std::string& filename)
std::string msg = "Error processing configuration file: ";
msg += filename;
msg += " no data";
throw Error(msg);
BOOST_THROW_EXCEPTION(Error(msg));
}
for (ConfigSection::const_iterator i = m_global.begin(); i != m_global.end(); ++i)
+2 -2
View File
@@ -87,7 +87,7 @@ LoggerFactory::parseLevel(const std::string& level)
catch (const boost::bad_lexical_cast& error) {
}
throw LoggerFactory::Error("Unsupported logging level \"" + level + "\"");
BOOST_THROW_EXCEPTION(LoggerFactory::Error("Unsupported logging level \"" + level + "\""));
}
LogLevel
@@ -101,7 +101,7 @@ LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
}
if (levelString.empty()) {
throw LoggerFactory::Error("No logging level found for option \"" + key + "\"");
BOOST_THROW_EXCEPTION(LoggerFactory::Error("No logging level found for option \"" + key + "\""));
}
return parseLevel(levelString);
+2 -1
View File
@@ -86,7 +86,8 @@ listNetworkInterfaces()
ifaddrs* ifa_list = nullptr;
if (::getifaddrs(&ifa_list) < 0)
throw std::runtime_error(std::string("getifaddrs() failed: ") + strerror(errno));
BOOST_THROW_EXCEPTION(std::runtime_error(std::string("getifaddrs() failed: ") +
strerror(errno)));
for (ifaddrs* ifa = ifa_list; ifa != nullptr; ifa = ifa->ifa_next) {
std::string ifname(ifa->ifa_name);
+4 -2
View File
@@ -36,8 +36,10 @@ class PrivilegeHelper
{
public:
/// \brief PrivilegeHelper::Error represents a serious seteuid/gid failure and
/// should only be caught by main in as part of a graceful program termination.
/** \brief represents a serious seteuid/gid failure
* \detail This should only be caught by main in as part of a graceful program termination.
* \note This is not an std::exception and BOOST_THROW_EXCEPTION should not be used.
*/
class Error
{
public:
+5 -1
View File
@@ -168,7 +168,11 @@ DatagramFace<T, U>::processErrorCode(const boost::system::error_code& error)
if (error == boost::asio::error::operation_aborted) // when cancel() is called
return;
// this should be unnecessary, but just in case
if (getPersistency() == ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERMANENT) {
NFD_LOG_FACE_DEBUG("Permanent face ignores error: " << error.message());
return;
}
if (!m_socket.is_open()) {
this->fail("Tunnel closed");
return;
+6 -6
View File
@@ -83,7 +83,7 @@ EthernetFace::EthernetFace(boost::asio::posix::stream_descriptor socket,
int fd = pcap_get_selectable_fd(m_pcap.get());
if (fd < 0)
throw Error("pcap_get_selectable_fd failed");
BOOST_THROW_EXCEPTION(Error("pcap_get_selectable_fd failed"));
// need to duplicate the fd, otherwise both pcap_close()
// and stream_descriptor::close() will try to close the
@@ -165,7 +165,7 @@ EthernetFace::pcapInit()
char errbuf[PCAP_ERRBUF_SIZE] = {};
m_pcap.reset(pcap_create(m_interfaceName.c_str(), errbuf));
if (!m_pcap)
throw Error("pcap_create: " + std::string(errbuf));
BOOST_THROW_EXCEPTION(Error("pcap_create: " + std::string(errbuf)));
#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
// Enable "immediate mode", effectively disabling any read buffering in the kernel.
@@ -176,10 +176,10 @@ EthernetFace::pcapInit()
#endif
if (pcap_activate(m_pcap.get()) < 0)
throw Error("pcap_activate failed");
BOOST_THROW_EXCEPTION(Error("pcap_activate failed"));
if (pcap_set_datalink(m_pcap.get(), DLT_EN10MB) < 0)
throw Error("pcap_set_datalink: " + std::string(pcap_geterr(m_pcap.get())));
BOOST_THROW_EXCEPTION(Error("pcap_set_datalink: " + std::string(pcap_geterr(m_pcap.get()))));
if (pcap_setdirection(m_pcap.get(), PCAP_D_IN) < 0)
// no need to throw on failure, BPF will filter unwanted packets anyway
@@ -191,12 +191,12 @@ EthernetFace::setPacketFilter(const char* filterString)
{
bpf_program filter;
if (pcap_compile(m_pcap.get(), &filter, filterString, 1, PCAP_NETMASK_UNKNOWN) < 0)
throw Error("pcap_compile: " + std::string(pcap_geterr(m_pcap.get())));
BOOST_THROW_EXCEPTION(Error("pcap_compile: " + std::string(pcap_geterr(m_pcap.get()))));
int ret = pcap_setfilter(m_pcap.get(), &filter);
pcap_freecode(&filter);
if (ret < 0)
throw Error("pcap_setfilter: " + std::string(pcap_geterr(m_pcap.get())));
BOOST_THROW_EXCEPTION(Error("pcap_setfilter: " + std::string(pcap_geterr(m_pcap.get()))));
}
bool
+3 -2
View File
@@ -36,7 +36,7 @@ EthernetFactory::createMulticastFace(const NetworkInterfaceInfo& interface,
const ethernet::Address &address)
{
if (!address.isMulticast())
throw Error(address.toString() + " is not a multicast address");
BOOST_THROW_EXCEPTION(Error(address.toString() + " is not a multicast address"));
shared_ptr<EthernetFace> face = findMulticastFace(interface.name, address);
if (face)
@@ -67,10 +67,11 @@ EthernetFactory::findMulticastFace(const std::string& interfaceName,
void
EthernetFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
throw Error("EthernetFactory does not support 'createFace' operation");
BOOST_THROW_EXCEPTION(Error("EthernetFactory does not support 'createFace' operation"));
}
std::list<shared_ptr<const Channel>>
+2 -1
View File
@@ -55,8 +55,9 @@ public:
// from ProtocolFactory
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
/**
* \brief Create an EthernetFace to communicate with the given multicast group
+2 -3
View File
@@ -34,7 +34,7 @@ Face::Face(const FaceUri& remoteUri, const FaceUri& localUri, bool isLocal, bool
, m_remoteUri(remoteUri)
, m_localUri(localUri)
, m_isLocal(isLocal)
, m_isOnDemand(false)
, m_persistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
, m_isMultiAccess(isMultiAccess)
, m_isFailed(false)
{
@@ -102,8 +102,7 @@ Face::copyStatusTo(FaceTraits& traits) const
.setLocalUri(getLocalUri().toString())
.setFaceScope(isLocal() ? ndn::nfd::FACE_SCOPE_LOCAL
: ndn::nfd::FACE_SCOPE_NON_LOCAL)
.setFacePersistency(isOnDemand() ? ndn::nfd::FACE_PERSISTENCY_ON_DEMAND
: ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
.setFacePersistency(getPersistency())
.setLinkType(isMultiAccess() ? ndn::nfd::LINK_TYPE_MULTI_ACCESS
: ndn::nfd::LINK_TYPE_POINT_TO_POINT);
}
+10 -10
View File
@@ -128,10 +128,10 @@ public: // attributes
bool
isLocal() const;
/** \brief Get whether face is created on demand or explicitly via FaceManagement protocol
/** \brief Get the persistency setting
*/
bool
isOnDemand() const;
ndn::nfd::FacePersistency
getPersistency() const;
/** \brief Get whether packets sent by this face may reach multiple peers
*/
@@ -171,7 +171,7 @@ public: // attributes
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
void
setOnDemand(bool isOnDemand);
setPersistency(ndn::nfd::FacePersistency persistency);
protected:
bool
@@ -202,7 +202,7 @@ private:
const FaceUri m_remoteUri;
const FaceUri m_localUri;
const bool m_isLocal;
bool m_isOnDemand;
ndn::nfd::FacePersistency m_persistency;
const bool m_isMultiAccess;
bool m_isFailed;
@@ -240,16 +240,16 @@ Face::isLocal() const
return m_isLocal;
}
inline bool
Face::isOnDemand() const
inline ndn::nfd::FacePersistency
Face::getPersistency() const
{
return m_isOnDemand;
return m_persistency;
}
inline void
Face::setOnDemand(bool isOnDemand)
Face::setPersistency(ndn::nfd::FacePersistency persistency)
{
m_isOnDemand = isOnDemand;
m_persistency = persistency;
}
inline bool
+1 -1
View File
@@ -54,7 +54,7 @@ inline uint64_t
SequenceBlock::operator[](size_t pos) const
{
if (pos >= m_count)
throw std::out_of_range("pos");
BOOST_THROW_EXCEPTION(std::out_of_range("pos"));
return m_start + static_cast<uint64_t>(pos);
}
+5 -3
View File
@@ -58,15 +58,17 @@ public:
Error(const std::string& what) : std::runtime_error(what) {}
};
/** \brief Try to create Face using the supplied Face URI
/** \brief Try to create Face using the supplied FaceUri
*
* This method should automatically choose channel, based on supplied Face URI
* This method should automatically choose channel, based on supplied FaceUri
* and create face.
*
* \throws Factory::Error if Factory does not support connect operation
* \throw Error Factory does not support connect operation
* \throw Error specified \p persistency is not supported
*/
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed) = 0;
+1 -1
View File
@@ -120,7 +120,7 @@ StreamFace<T, FaceBase>::StreamFace(const FaceUri& remoteUri, const FaceUri& loc
{
NFD_LOG_FACE_INFO("Creating face");
this->setOnDemand(isOnDemand);
this->setPersistency(isOnDemand ? ndn::nfd::FACE_PERSISTENCY_ON_DEMAND : ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
StreamFaceValidator<T, FaceBase>::validateSocket(m_socket);
m_socket.async_receive(boost::asio::buffer(m_inputBuffer, ndn::MAX_NDN_PACKET_SIZE),
+2 -1
View File
@@ -69,7 +69,8 @@ struct StreamFaceValidator<TcpLocalFace::protocol, LocalFace>
if (!socket.local_endpoint().address().is_loopback() ||
!socket.remote_endpoint().address().is_loopback())
{
throw Face::Error("TcpLocalFace can be created only on a loopback address");
BOOST_THROW_EXCEPTION(Face::Error("TcpLocalFace can be created only on a loopback "
"address"));
}
}
};
+5
View File
@@ -127,9 +127,14 @@ TcpFactory::findChannel(const tcp::Endpoint& localEndpoint)
void
TcpFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
if (persistency != ndn::nfd::FACE_PERSISTENCY_PERSISTENT) {
BOOST_THROW_EXCEPTION(Error("TcpFactory only supports persistent face"));
}
BOOST_ASSERT(uri.isCanonical());
boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost());
tcp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(uri.getPort()));
+3 -2
View File
@@ -77,12 +77,13 @@ public:
shared_ptr<TcpChannel>
createChannel(const std::string& localIp, const std::string& localPort);
// from Factory
// from ProtocolFactory
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
virtual std::list<shared_ptr<const Channel> >
getChannels() const;
+14 -8
View File
@@ -67,12 +67,13 @@ UdpChannel::listen(const FaceCreatedCallback& onFaceCreated,
void
UdpChannel::connect(const udp::Endpoint& remoteEndpoint,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed)
{
shared_ptr<UdpFace> face;
try {
face = createFace(remoteEndpoint, false).second;
face = createFace(remoteEndpoint, persistency).second;
}
catch (const boost::system::system_error& e) {
NFD_LOG_WARN("[" << m_localEndpoint << "] Connect failed: " << e.what());
@@ -93,15 +94,20 @@ UdpChannel::size() const
}
std::pair<bool, shared_ptr<UdpFace>>
UdpChannel::createFace(const udp::Endpoint& remoteEndpoint, bool isOnDemand)
UdpChannel::createFace(const udp::Endpoint& remoteEndpoint, ndn::nfd::FacePersistency persistency)
{
auto it = m_channelFaces.find(remoteEndpoint);
if (it != m_channelFaces.end()) {
// we already have a face for this endpoint, just reuse it
if (!isOnDemand)
// only on-demand -> non-on-demand transition is allowed
it->second->setOnDemand(false);
return {false, it->second};
auto face = it->second;
// only on-demand -> persistent -> permanent transition is allowed
bool isTransitionAllowed = persistency != face->getPersistency() &&
(face->getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND ||
persistency == ndn::nfd::FACE_PERSISTENCY_PERMANENT);
if (isTransitionAllowed) {
face->setPersistency(persistency);
}
return {false, face};
}
// else, create a new face
@@ -111,7 +117,7 @@ UdpChannel::createFace(const udp::Endpoint& remoteEndpoint, bool isOnDemand)
socket.connect(remoteEndpoint);
auto face = make_shared<UdpFace>(FaceUri(remoteEndpoint), FaceUri(m_localEndpoint),
std::move(socket), isOnDemand, m_idleFaceTimeout);
std::move(socket), persistency, m_idleFaceTimeout);
face->onFail.connectSingleShot([this, remoteEndpoint] (const std::string&) {
NFD_LOG_TRACE("Erasing " << remoteEndpoint << " from channel face map");
@@ -143,7 +149,7 @@ UdpChannel::handleNewPeer(const boost::system::error_code& error,
bool created;
shared_ptr<UdpFace> face;
try {
std::tie(created, face) = createFace(m_remoteEndpoint, true);
std::tie(created, face) = createFace(m_remoteEndpoint, ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
}
catch (const boost::system::system_error& e) {
NFD_LOG_WARN("[" << m_localEndpoint << "] Failed to create face for peer "
+2 -1
View File
@@ -78,6 +78,7 @@ public:
*/
void
connect(const udp::Endpoint& remoteEndpoint,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onFaceCreated,
const ConnectFailedCallback& onConnectFailed);
@@ -92,7 +93,7 @@ public:
private:
std::pair<bool, shared_ptr<UdpFace>>
createFace(const udp::Endpoint& remoteEndpoint, bool isOnDemand);
createFace(const udp::Endpoint& remoteEndpoint, ndn::nfd::FacePersistency persistency);
/**
* \brief The channel has received a new packet from a remote
+5 -5
View File
@@ -38,13 +38,13 @@ namespace nfd {
NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramFace, UdpFace::protocol, "UdpFace");
UdpFace::UdpFace(const FaceUri& remoteUri, const FaceUri& localUri,
protocol::socket socket, bool isOnDemand,
protocol::socket socket, ndn::nfd::FacePersistency persistency,
const time::seconds& idleTimeout)
: DatagramFace(remoteUri, localUri, std::move(socket))
, m_idleTimeout(idleTimeout)
, m_lastIdleCheck(time::steady_clock::now())
{
this->setOnDemand(isOnDemand);
this->setPersistency(persistency);
#ifdef __linux__
//
@@ -66,7 +66,7 @@ UdpFace::UdpFace(const FaceUri& remoteUri, const FaceUri& localUri,
}
#endif
if (this->isOnDemand() && m_idleTimeout > time::seconds::zero()) {
if (this->getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND && m_idleTimeout > time::seconds::zero()) {
m_closeIfIdleEvent = scheduler::schedule(m_idleTimeout, bind(&UdpFace::closeIfIdle, this));
}
}
@@ -76,7 +76,7 @@ UdpFace::getFaceStatus() const
{
auto status = DatagramFace::getFaceStatus();
if (isOnDemand()) {
if (this->getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
time::milliseconds left = m_idleTimeout;
left -= time::duration_cast<time::milliseconds>(time::steady_clock::now() - m_lastIdleCheck);
@@ -97,7 +97,7 @@ UdpFace::closeIfIdle()
{
// Face can be switched from on-demand to non-on-demand mode
// (non-on-demand -> on-demand transition is not allowed)
if (isOnDemand()) {
if (this->getPersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
if (!hasBeenUsedRecently()) {
NFD_LOG_FACE_INFO("Closing for inactivity");
close();
+1 -1
View File
@@ -39,7 +39,7 @@ class UdpFace : public DatagramFace<boost::asio::ip::udp>
{
public:
UdpFace(const FaceUri& remoteUri, const FaceUri& localUri,
protocol::socket socket, bool isOnDemand,
protocol::socket socket, ndn::nfd::FacePersistency persistency,
const time::seconds& idleTimeout);
ndn::nfd::FaceStatus
+26 -20
View File
@@ -120,13 +120,13 @@ UdpFactory::createChannel(const udp::Endpoint& endpoint,
//checking if the endpoint is already in use for multicast face
shared_ptr<MulticastUdpFace> multicast = findMulticastFace(endpoint);
if (static_cast<bool>(multicast))
throw Error("Cannot create the requested UDP unicast channel, local "
"endpoint is already allocated for a UDP multicast face");
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP unicast channel, local "
"endpoint is already allocated for a UDP multicast face"));
if (endpoint.address().is_multicast()) {
throw Error("This method is only for unicast channel. The provided "
"endpoint is multicast. Use createMulticastFace to "
"create a multicast face");
BOOST_THROW_EXCEPTION(Error("This method is only for unicast channel. The provided "
"endpoint is multicast. Use createMulticastFace to "
"create a multicast face"));
}
channel = make_shared<UdpChannel>(endpoint, timeout);
@@ -157,35 +157,36 @@ UdpFactory::createMulticastFace(const udp::Endpoint& localEndpoint,
if (face->getMulticastGroup() == multicastEndpoint)
return face;
else
throw Error("Cannot create the requested UDP multicast face, local "
"endpoint is already allocated for a UDP multicast face "
"on a different multicast group");
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, local "
"endpoint is already allocated for a UDP multicast face "
"on a different multicast group"));
}
// checking if the local endpoint is already in use for a unicast channel
shared_ptr<UdpChannel> unicast = findChannel(localEndpoint);
if (static_cast<bool>(unicast)) {
throw Error("Cannot create the requested UDP multicast face, local "
"endpoint is already allocated for a UDP unicast channel");
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, local "
"endpoint is already allocated for a UDP unicast channel"));
}
if (m_prohibitedEndpoints.find(multicastEndpoint) != m_prohibitedEndpoints.end()) {
throw Error("Cannot create the requested UDP multicast face, "
"remote endpoint is owned by this NFD instance");
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, "
"remote endpoint is owned by this NFD instance"));
}
if (localEndpoint.address().is_v6() || multicastEndpoint.address().is_v6()) {
throw Error("IPv6 multicast is not supported yet. Please provide an IPv4 address");
BOOST_THROW_EXCEPTION(Error("IPv6 multicast is not supported yet. Please provide an IPv4 "
"address"));
}
if (localEndpoint.port() != multicastEndpoint.port()) {
throw Error("Cannot create the requested UDP multicast face, "
"both endpoints should have the same port number. ");
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, "
"both endpoints should have the same port number. "));
}
if (!multicastEndpoint.address().is_multicast()) {
throw Error("Cannot create the requested UDP multicast face, "
"the multicast group given as input is not a multicast address");
BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, "
"the multicast group given as input is not a multicast address"));
}
ip::udp::socket receiveSocket(getGlobalIoService());
@@ -218,8 +219,8 @@ UdpFactory::createMulticastFace(const udp::Endpoint& localEndpoint,
if (!networkInterfaceName.empty()) {
if (::setsockopt(receiveSocket.native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
networkInterfaceName.c_str(), networkInterfaceName.size() + 1) < 0) {
throw Error("Cannot bind multicast face to " + networkInterfaceName +
": " + std::strerror(errno));
BOOST_THROW_EXCEPTION(Error("Cannot bind multicast face to " + networkInterfaceName +
": " + std::strerror(errno)));
}
}
#endif
@@ -250,9 +251,14 @@ UdpFactory::createMulticastFace(const std::string& localIp,
void
UdpFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
if (persistency == ndn::nfd::FacePersistency::FACE_PERSISTENCY_ON_DEMAND) {
BOOST_THROW_EXCEPTION(Error("UdpFactory::createFace does not support creating on-demand face"));
}
BOOST_ASSERT(uri.isCanonical());
boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost());
@@ -277,7 +283,7 @@ UdpFactory::createFace(const FaceUri& uri,
if ((channel->first.address().is_v4() && endpoint.address().is_v4()) ||
(channel->first.address().is_v6() && endpoint.address().is_v6()))
{
channel->second->connect(endpoint, onCreated, onConnectFailed);
channel->second->connect(endpoint, persistency, onCreated, onConnectFailed);
return;
}
}
+2 -1
View File
@@ -145,8 +145,9 @@ public:
// from ProtocolFactory
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
virtual std::list<shared_ptr<const Channel>>
getChannels() const;
+5 -4
View File
@@ -77,8 +77,8 @@ UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
+ error.message());
if (!error) {
// someone answered, leave the socket alone
throw Error("Socket file at " + m_endpoint.path()
+ " belongs to another NFD process");
BOOST_THROW_EXCEPTION(Error("Socket file at " + m_endpoint.path()
+ " belongs to another NFD process"));
}
else if (error == boost::asio::error::connection_refused ||
error == boost::asio::error::timed_out) {
@@ -89,7 +89,7 @@ UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
}
}
else if (type != fs::file_not_found) {
throw Error(m_endpoint.path() + " already exists and is not a socket file");
BOOST_THROW_EXCEPTION(Error(m_endpoint.path() + " already exists and is not a socket file"));
}
m_acceptor.open();
@@ -97,7 +97,8 @@ UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
m_acceptor.listen(backlog);
if (::chmod(m_endpoint.path().c_str(), 0666) < 0) {
throw Error("chmod(" + m_endpoint.path() + ") failed: " + std::strerror(errno));
BOOST_THROW_EXCEPTION(Error("chmod(" + m_endpoint.path() + ") failed: " +
std::strerror(errno)));
}
// start accepting connections
+2 -1
View File
@@ -57,10 +57,11 @@ UnixStreamFactory::findChannel(const unix_stream::Endpoint& endpoint)
void
UnixStreamFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
throw Error("UnixStreamFactory does not support 'createFace' operation");
BOOST_THROW_EXCEPTION(Error("UnixStreamFactory does not support 'createFace' operation"));
}
std::list<shared_ptr<const Channel> >
+2 -1
View File
@@ -61,8 +61,9 @@ public:
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
virtual std::list<shared_ptr<const Channel> >
getChannels() const;
+1 -1
View File
@@ -38,7 +38,7 @@ WebSocketFace::WebSocketFace(const FaceUri& remoteUri, const FaceUri& localUri,
, m_closed(false)
{
NFD_LOG_FACE_INFO("Creating face");
this->setOnDemand(true);
this->setPersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
}
void
+2 -1
View File
@@ -67,10 +67,11 @@ WebSocketFactory::findChannel(const websocket::Endpoint& localEndpoint)
void
WebSocketFactory::createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
throw Error("WebSocketFactory does not support 'createFace' operation");
BOOST_THROW_EXCEPTION(Error("WebSocketFactory does not support 'createFace' operation"));
}
std::list<shared_ptr<const Channel> >
+2 -1
View File
@@ -81,8 +81,9 @@ public:
// from ProtocolFactory
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed);
const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
virtual std::list<shared_ptr<const Channel> >
getChannels() const;
+4 -4
View File
@@ -97,8 +97,8 @@ AccessStrategy::afterReceiveNewInterest(const Face& inFace,
// no measurements, or last working nexthop unavailable
// multicast to all nexthops
this->multicast(pitEntry, fibEntry);
// multicast to all nexthops except incoming face
this->multicast(pitEntry, fibEntry, {inFace.getId()});
}
void
@@ -108,7 +108,7 @@ AccessStrategy::afterReceiveRetxInterest(const Face& inFace,
shared_ptr<pit::Entry> pitEntry)
{
NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " retx-forward");
this->multicast(pitEntry, fibEntry, std::unordered_set<FaceId>{inFace.getId()});
this->multicast(pitEntry, fibEntry, {inFace.getId()});
}
bool
@@ -167,7 +167,7 @@ AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, weak_ptr<fib::Entr
NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFace <<
" multicast-except " << inFace << ',' << firstOutFace);
this->multicast(pitEntry, fibEntry, std::unordered_set<FaceId>{inFace, firstOutFace});
this->multicast(pitEntry, fibEntry, {inFace, firstOutFace});
}
void
+10 -16
View File
@@ -28,15 +28,14 @@
namespace nfd {
namespace fw {
const Name BroadcastStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/broadcast/%FD%01");
NFD_LOG_INIT("BroadcastStrategy");
const Name BroadcastStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/broadcast/%FD%02");
NFD_REGISTER_STRATEGY(BroadcastStrategy);
BroadcastStrategy::BroadcastStrategy(Forwarder& forwarder, const Name& name)
: Strategy(forwarder, name)
{
}
BroadcastStrategy::~BroadcastStrategy()
: MulticastStrategy(forwarder, name)
, m_isFirstUse(true)
{
}
@@ -46,18 +45,13 @@ BroadcastStrategy::afterReceiveInterest(const Face& inFace,
shared_ptr<fib::Entry> fibEntry,
shared_ptr<pit::Entry> pitEntry)
{
const fib::NextHopList& nexthops = fibEntry->getNextHops();
for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
shared_ptr<Face> outFace = it->getFace();
if (pitEntry->canForwardTo(*outFace)) {
this->sendInterest(pitEntry, outFace);
}
if (m_isFirstUse) {
NFD_LOG_WARN("The broadcast strategy has been renamed as multicast strategy. "
"Use ndn:/localhost/nfd/strategy/multicast to select the multicast strategy.");
m_isFirstUse = false;
}
if (!pitEntry->hasUnexpiredOutRecords()) {
this->rejectPendingInterest(pitEntry);
}
this->MulticastStrategy::afterReceiveInterest(inFace, interest, fibEntry, pitEntry);
}
} // namespace fw
+14 -15
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -26,23 +26,19 @@
#ifndef NFD_DAEMON_FW_BROADCAST_STRATEGY_HPP
#define NFD_DAEMON_FW_BROADCAST_STRATEGY_HPP
#include "strategy.hpp"
#include "multicast-strategy.hpp"
namespace nfd {
namespace fw {
/** \class BroadcastStrategy
* \brief a forwarding strategy that forwards Interest
* to all nexthops
/** \brief identical to MulticastStrategy, for backwards compatibility
* \deprecated use MulticastStrategy instead
*/
class BroadcastStrategy : public Strategy
class BroadcastStrategy : public MulticastStrategy
{
public:
BroadcastStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
virtual
~BroadcastStrategy();
virtual void
afterReceiveInterest(const Face& inFace,
const Interest& interest,
@@ -51,6 +47,9 @@ public:
public:
static const Name STRATEGY_NAME;
private:
bool m_isFirstUse;
};
} // namespace fw
+1 -1
View File
@@ -128,7 +128,7 @@ Forwarder::onContentStoreHit(const Face& inFace,
const Interest& interest,
const Data& data)
{
NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName());
NFD_LOG_DEBUG("onContentStoreHit interest=" << interest.getName());
const_pointer_cast<Data>(data.shared_from_this())->setIncomingFaceId(FACEID_CONTENT_STORE);
// XXX should we lookup PIT for other Interests that also match csMatch?
+60
View File
@@ -0,0 +1,60 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "multicast-strategy.hpp"
namespace nfd {
namespace fw {
const Name MulticastStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/multicast/%FD%01");
NFD_REGISTER_STRATEGY(MulticastStrategy);
MulticastStrategy::MulticastStrategy(Forwarder& forwarder, const Name& name)
: Strategy(forwarder, name)
{
}
void
MulticastStrategy::afterReceiveInterest(const Face& inFace,
const Interest& interest,
shared_ptr<fib::Entry> fibEntry,
shared_ptr<pit::Entry> pitEntry)
{
const fib::NextHopList& nexthops = fibEntry->getNextHops();
for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
shared_ptr<Face> outFace = it->getFace();
if (pitEntry->canForwardTo(*outFace)) {
this->sendInterest(pitEntry, outFace);
}
}
if (!pitEntry->hasUnexpiredOutRecords()) {
this->rejectPendingInterest(pitEntry);
}
}
} // namespace fw
} // namespace nfd
+54
View File
@@ -0,0 +1,54 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FW_MULTICAST_STRATEGY_HPP
#define NFD_DAEMON_FW_MULTICAST_STRATEGY_HPP
#include "strategy.hpp"
namespace nfd {
namespace fw {
/** \brief a forwarding strategy that forwards Interest to all FIB nexthops
*/
class MulticastStrategy : public Strategy
{
public:
MulticastStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
virtual void
afterReceiveInterest(const Face& inFace,
const Interest& interest,
shared_ptr<fib::Entry> fibEntry,
shared_ptr<pit::Entry> pitEntry) DECL_OVERRIDE;
public:
static const Name STRATEGY_NAME;
};
} // namespace fw
} // namespace nfd
#endif // NFD_DAEMON_FW_MULTICAST_STRATEGY_HPP
+6 -3
View File
@@ -240,10 +240,12 @@ main(int argc, char** argv)
po::variables_map vm;
try {
po::store(po::command_line_parser(argc, argv).options(description).run(), vm);
po::notify(vm);
po::store(po::command_line_parser(argc, argv).options(description).run(), vm);
po::notify(vm);
}
catch (const std::exception& e) {
// avoid NFD_LOG_FATAL to ensure that errors related to command-line parsing always appear on the
// terminal and are not littered with timestamps and other things added by the logging subsystem
std::cerr << "ERROR: " << e.what() << std::endl;
NfdRunner::printUsage(std::cerr, argv[0]);
return 1;
@@ -273,11 +275,12 @@ main(int argc, char** argv)
if (e.code() == boost::system::errc::permission_denied) {
NFD_LOG_FATAL("Permissions denied for " << e.path1() << ". " <<
argv[0] << " should be run as superuser");
return 3;
}
else {
NFD_LOG_FATAL(e.what());
return 2;
}
return 1;
}
catch (const std::exception& e) {
NFD_LOG_FATAL(e.what());
+8 -8
View File
@@ -75,7 +75,7 @@ CommandValidator::onConfig(const ConfigSection& section,
if (section.begin() == section.end())
{
throw ConfigFile::Error("No authorize sections found");
BOOST_THROW_EXCEPTION(ConfigFile::Error("No authorize sections found"));
}
std::stringstream dryRunErrors;
@@ -92,7 +92,7 @@ CommandValidator::onConfig(const ConfigSection& section,
std::string msg = "No certfile specified";
if (!isDryRun)
{
throw ConfigFile::Error(msg);
BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
}
aggregateErrors(dryRunErrors, msg);
continue;
@@ -112,7 +112,7 @@ CommandValidator::onConfig(const ConfigSection& section,
std::string msg = "Unable to open certificate file " + certfilePath.native();
if (!isDryRun)
{
throw ConfigFile::Error(msg);
BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
}
aggregateErrors(dryRunErrors, msg);
continue;
@@ -131,7 +131,7 @@ CommandValidator::onConfig(const ConfigSection& section,
std::string msg = "Malformed certificate file " + certfilePath.native();
if (!isDryRun)
{
throw ConfigFile::Error(msg);
BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
}
aggregateErrors(dryRunErrors, msg);
continue;
@@ -160,7 +160,7 @@ CommandValidator::onConfig(const ConfigSection& section,
certfile + " (" + keyNameForLogging + ")";
if (!isDryRun)
{
throw ConfigFile::Error(msg);
BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
}
aggregateErrors(dryRunErrors, msg);
continue;
@@ -196,7 +196,7 @@ CommandValidator::onConfig(const ConfigSection& section,
"\" for certificate file " + certfile + " (" + keyNameForLogging + ")";
if (!isDryRun)
{
throw ConfigFile::Error(msg);
BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
}
aggregateErrors(dryRunErrors, msg);
}
@@ -205,7 +205,7 @@ CommandValidator::onConfig(const ConfigSection& section,
if (!dryRunErrors.str().empty())
{
throw ConfigFile::Error(dryRunErrors.str());
BOOST_THROW_EXCEPTION(ConfigFile::Error(dryRunErrors.str()));
}
}
@@ -214,7 +214,7 @@ CommandValidator::addSupportedPrivilege(const std::string& privilege)
{
if (m_supportedPrivileges.find(privilege) != m_supportedPrivileges.end())
{
throw CommandValidator::Error("Duplicated privilege: " + privilege);
BOOST_THROW_EXCEPTION(CommandValidator::Error("Duplicated privilege: " + privilege));
}
m_supportedPrivileges.insert(privilege);
}
+54 -47
View File
@@ -173,7 +173,7 @@ FaceManager::onConfig(const ConfigSection& configSection,
if (item.first == "unix")
{
if (hasSeenUnix)
throw Error("Duplicate \"unix\" section");
BOOST_THROW_EXCEPTION(Error("Duplicate \"unix\" section"));
hasSeenUnix = true;
processSectionUnix(item.second, isDryRun);
@@ -181,7 +181,7 @@ FaceManager::onConfig(const ConfigSection& configSection,
else if (item.first == "tcp")
{
if (hasSeenTcp)
throw Error("Duplicate \"tcp\" section");
BOOST_THROW_EXCEPTION(Error("Duplicate \"tcp\" section"));
hasSeenTcp = true;
processSectionTcp(item.second, isDryRun);
@@ -189,7 +189,7 @@ FaceManager::onConfig(const ConfigSection& configSection,
else if (item.first == "udp")
{
if (hasSeenUdp)
throw Error("Duplicate \"udp\" section");
BOOST_THROW_EXCEPTION(Error("Duplicate \"udp\" section"));
hasSeenUdp = true;
processSectionUdp(item.second, isDryRun, nicList);
@@ -197,7 +197,7 @@ FaceManager::onConfig(const ConfigSection& configSection,
else if (item.first == "ether")
{
if (hasSeenEther)
throw Error("Duplicate \"ether\" section");
BOOST_THROW_EXCEPTION(Error("Duplicate \"ether\" section"));
hasSeenEther = true;
processSectionEther(item.second, isDryRun, nicList);
@@ -205,14 +205,14 @@ FaceManager::onConfig(const ConfigSection& configSection,
else if (item.first == "websocket")
{
if (hasSeenWebSocket)
throw Error("Duplicate \"websocket\" section");
BOOST_THROW_EXCEPTION(Error("Duplicate \"websocket\" section"));
hasSeenWebSocket = true;
processSectionWebSocket(item.second, isDryRun);
}
else
{
throw Error("Unrecognized option \"" + item.first + "\"");
BOOST_THROW_EXCEPTION(Error("Unrecognized option \"" + item.first + "\""));
}
}
}
@@ -240,7 +240,8 @@ FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRu
}
else
{
throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"unix\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
"\"unix\" section"));
}
}
@@ -269,8 +270,8 @@ FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRu
m_factories.insert(std::make_pair("unix", factory));
}
#else
throw ConfigFile::Error("NFD was compiled without Unix sockets support, "
"cannot process \"unix\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without Unix sockets support, "
"cannot process \"unix\" section"));
#endif // HAVE_UNIX_SOCKETS
}
@@ -304,8 +305,8 @@ FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun
}
catch (const std::bad_cast& error)
{
throw ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"tcp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"tcp\" section"));
}
}
else if (i->first == "listen")
@@ -322,15 +323,16 @@ FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun
}
else
{
throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
"\"tcp\" section"));
}
}
if (!enableV4 && !enableV6)
{
throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
" Remove \"tcp\" section to disable TCP channels or"
" re-enable at least one channel type.");
BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
" Remove \"tcp\" section to disable TCP channels or"
" re-enable at least one channel type."));
}
if (!isDryRun)
@@ -413,8 +415,8 @@ FaceManager::processSectionUdp(const ConfigSection& configSection,
}
catch (const std::bad_cast& error)
{
throw ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"udp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"udp\" section"));
}
}
else if (i->first == "enable_v4")
@@ -433,8 +435,8 @@ FaceManager::processSectionUdp(const ConfigSection& configSection,
}
catch (const std::exception& e)
{
throw ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section"));
}
}
else if (i->first == "keep_alive_interval")
@@ -448,8 +450,8 @@ FaceManager::processSectionUdp(const ConfigSection& configSection,
}
catch (const std::exception& e)
{
throw ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section"));
}
}
else if (i->first == "mcast")
@@ -466,8 +468,8 @@ FaceManager::processSectionUdp(const ConfigSection& configSection,
}
catch (const std::bad_cast& error)
{
throw ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"udp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"udp\" section"));
}
}
else if (i->first == "mcast_group")
@@ -479,32 +481,34 @@ FaceManager::processSectionUdp(const ConfigSection& configSection,
address mcastGroupTest = address::from_string(mcastGroup);
if (!mcastGroupTest.is_v4())
{
throw ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section"));
}
}
catch(const std::runtime_error& e)
{
throw ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"udp\" section"));
}
}
else
{
throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"udp\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
"\"udp\" section"));
}
}
if (!enableV4 && !enableV6)
{
throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
" Remove \"udp\" section to disable UDP channels or"
" re-enable at least one channel type.");
BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
" Remove \"udp\" section to disable UDP channels or"
" re-enable at least one channel type."));
}
else if (useMcast && !enableV4)
{
throw ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
" have been disabled (conflicting configuration options set)");
BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
" have been disabled (conflicting configuration"
" options set)"));
}
/// \todo what is keep alive interval used for?
@@ -645,13 +649,14 @@ FaceManager::processSectionEther(const ConfigSection& configSection,
mcastGroup = ethernet::Address::fromString(i->second.get_value<std::string>());
if (mcastGroup.isNull())
{
throw ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"ether\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
i->first + "\" in \"ether\" section"));
}
}
else
{
throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"ether\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first +
"\" in \"ether\" section"));
}
}
@@ -729,7 +734,8 @@ FaceManager::processSectionEther(const ConfigSection& configSection,
}
}
#else
throw ConfigFile::Error("NFD was compiled without libpcap, cannot process \"ether\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without libpcap, cannot "
"process \"ether\" section"));
#endif // HAVE_LIBPCAP
}
@@ -766,8 +772,8 @@ FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool is
}
catch (const std::bad_cast& error)
{
throw ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"websocket\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
i->first + "\" in \"websocket\" section"));
}
}
else if (i->first == "listen")
@@ -784,21 +790,21 @@ FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool is
}
else
{
throw ConfigFile::Error("Unrecognized option \"" +
i->first + "\" in \"websocket\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
i->first + "\" in \"websocket\" section"));
}
}
if (!enableV4 && !enableV6)
{
throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
" Remove \"websocket\" section to disable WebSocket channels or"
" re-enable at least one channel type.");
BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
" Remove \"websocket\" section to disable WebSocket"
" channels or re-enable at least one channel type."));
}
if (!enableV4 && enableV6)
{
throw ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel.");
BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel."));
}
if (!isDryRun)
@@ -833,8 +839,8 @@ FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool is
}
}
#else
throw ConfigFile::Error("NFD was compiled without WebSocket, "
"cannot process \"websocket\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without WebSocket, "
"cannot process \"websocket\" section"));
#endif // HAVE_WEBSOCKET
}
@@ -975,6 +981,7 @@ FaceManager::createFace(const Interest& request,
try
{
factory->second->createFace(uri,
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind(&FaceManager::onCreated,
this, requestName, parameters, _1),
bind(&FaceManager::onConnectFailed,
+3 -3
View File
@@ -234,9 +234,9 @@ FaceManager::parseYesNo(const ConfigSection::const_iterator& i,
return false;
}
throw ConfigFile::Error("Invalid value for option \"" +
optionName + "\" in \"" +
sectionName + "\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
optionName + "\" in \"" +
sectionName + "\" section"));
}
inline void
+1 -2
View File
@@ -74,8 +74,7 @@ FaceQueryStatusPublisher::doesMatchFilter(const shared_ptr<Face>& face)
}
if (m_faceFilter.hasFacePersistency() &&
(m_faceFilter.getFacePersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) !=
face->isOnDemand()) {
m_faceFilter.getFacePersistency() != face->getPersistency()) {
return false;
}
+8 -8
View File
@@ -61,14 +61,14 @@ onConfig(const ConfigSection& configSection,
if (user.empty())
{
throw ConfigFile::Error("Invalid value for \"user\""
" in \"general\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\""
" in \"general\" section"));
}
}
catch (const boost::property_tree::ptree_error& error)
{
throw ConfigFile::Error("Invalid value for \"user\""
" in \"general\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\""
" in \"general\" section"));
}
}
else if (i->first == "group")
@@ -79,14 +79,14 @@ onConfig(const ConfigSection& configSection,
if (group.empty())
{
throw ConfigFile::Error("Invalid value for \"group\""
" in \"general\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\""
" in \"general\" section"));
}
}
catch (const boost::property_tree::ptree_error& error)
{
throw ConfigFile::Error("Invalid value for \"group\""
" in \"general\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\""
" in \"general\" section"));
}
}
}
+1 -1
View File
@@ -128,7 +128,7 @@ InternalFace::sendData(const Data& data)
void
InternalFace::close()
{
throw Error("Internal face cannot be closed");
BOOST_THROW_EXCEPTION(Error("Internal face cannot be closed"));
}
void
+20 -16
View File
@@ -84,9 +84,9 @@ TablesConfigSection::onConfig(const ConfigSection& configSection,
// strategy_choice
// {
// / /localhost/nfd/strategy/best-route
// /localhost /localhost/nfd/strategy/broadcast
// /localhost /localhost/nfd/strategy/multicast
// /localhost/nfd /localhost/nfd/strategy/best-route
// /ndn/broadcast /localhost/nfd/strategy/broadcast
// /ndn/broadcast /localhost/nfd/strategy/multicast
// }
// }
@@ -102,8 +102,8 @@ TablesConfigSection::onConfig(const ConfigSection& configSection,
if (!valCsMaxPackets)
{
throw ConfigFile::Error("Invalid value for option \"cs_max_packets\""
" in \"tables\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"cs_max_packets\""
" in \"tables\" section"));
}
nCsMaxPackets = *valCsMaxPackets;
@@ -133,9 +133,9 @@ TablesConfigSection::processSectionStrategyChoice(const ConfigSection& configSec
// strategy_choice
// {
// / /localhost/nfd/strategy/best-route
// /localhost /localhost/nfd/strategy/broadcast
// /localhost /localhost/nfd/strategy/multicast
// /localhost/nfd /localhost/nfd/strategy/best-route
// /ndn/broadcast /localhost/nfd/strategy/broadcast
// /ndn/broadcast /localhost/nfd/strategy/multicast
// }
std::map<Name, Name> choices;
@@ -145,23 +145,26 @@ TablesConfigSection::processSectionStrategyChoice(const ConfigSection& configSec
const Name prefix(prefixAndStrategy.first);
if (choices.find(prefix) != choices.end())
{
throw ConfigFile::Error("Duplicate strategy choice for prefix \"" +
prefix.toUri() + "\" in \"strategy_choice\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Duplicate strategy choice for prefix \"" +
prefix.toUri() + "\" in \"strategy_choice\" "
"section"));
}
const std::string strategyString(prefixAndStrategy.second.get_value<std::string>());
if (strategyString.empty())
{
throw ConfigFile::Error("Invalid strategy choice \"\" for prefix \"" +
prefix.toUri() + "\" in \"strategy_choice\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid strategy choice \"\" for prefix \"" +
prefix.toUri() + "\" in \"strategy_choice\" "
"section"));
}
const Name strategyName(strategyString);
if (!m_strategyChoice.hasStrategy(strategyName))
{
throw ConfigFile::Error("Invalid strategy choice \"" +
strategyName.toUri() + "\" for prefix \"" +
prefix.toUri() + "\" in \"strategy_choice\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid strategy choice \"" +
strategyName.toUri() + "\" for prefix \"" +
prefix.toUri() + "\" in \"strategy_choice\" "
"section"));
}
choices[prefix] = strategyName;
@@ -172,9 +175,10 @@ TablesConfigSection::processSectionStrategyChoice(const ConfigSection& configSec
{
if (!isDryRun && !m_strategyChoice.insert(prefixAndStrategy.first, prefixAndStrategy.second))
{
throw ConfigFile::Error("Failed to set strategy \"" +
prefixAndStrategy.second.toUri() + "\" for prefix \"" +
prefixAndStrategy.first.toUri() + "\" in \"strategy_choicev\"");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Failed to set strategy \"" +
prefixAndStrategy.second.toUri() + "\" for "
"prefix \"" + prefixAndStrategy.first.toUri() +
"\" in \"strategy_choicev\""));
}
}
}
+31 -1
View File
@@ -25,8 +25,10 @@
#include "nfd.hpp"
#include "core/global-io.hpp"
#include "core/logger-factory.hpp"
#include "core/privilege-helper.hpp"
#include "core/config-file.hpp"
#include "fw/forwarder.hpp"
#include "face/null-face.hpp"
#include "mgmt/internal-face.hpp"
@@ -34,23 +36,26 @@
#include "mgmt/face-manager.hpp"
#include "mgmt/strategy-choice-manager.hpp"
#include "mgmt/status-server.hpp"
#include "core/config-file.hpp"
#include "mgmt/general-config-section.hpp"
#include "mgmt/tables-config-section.hpp"
namespace nfd {
NFD_LOG_INIT("Nfd");
static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
Nfd::Nfd(const std::string& configFile, ndn::KeyChain& keyChain)
: m_configFile(configFile)
, m_keyChain(keyChain)
, m_networkMonitor(getGlobalIoService())
{
}
Nfd::Nfd(const ConfigSection& config, ndn::KeyChain& keyChain)
: m_configSection(config)
, m_keyChain(keyChain)
, m_networkMonitor(getGlobalIoService())
{
}
@@ -75,6 +80,16 @@ Nfd::initialize()
FACEID_CONTENT_STORE);
PrivilegeHelper::drop();
m_networkMonitor.onNetworkStateChanged.connect([this] {
// delay stages, so if multiple events are triggered in short sequence,
// only one auto-detection procedure is triggered
m_reloadConfigEvent = scheduler::schedule(time::seconds(5),
[this] {
NFD_LOG_INFO("Network change detected, reloading face section of the config file...");
this->reloadConfigFileFaceSection();
});
});
}
void
@@ -189,4 +204,19 @@ Nfd::reloadConfigFile()
}
}
void
Nfd::reloadConfigFileFaceSection()
{
// reload only face_system section of the config file to re-initialize multicast faces
ConfigFile config(&ConfigFile::ignoreUnknownSection);
m_faceManager->setConfigFile(config);
if (!m_configFile.empty()) {
config.parse(m_configFile, false);
}
else {
config.parse(m_configSection, false, INTERNAL_CONFIG);
}
}
} // namespace nfd
+8
View File
@@ -28,8 +28,10 @@
#include "common.hpp"
#include "core/config-file.hpp"
#include "core/scheduler.hpp"
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/network-monitor.hpp>
namespace nfd {
@@ -86,6 +88,9 @@ private:
void
initializeManagement();
void
reloadConfigFileFaceSection();
private:
std::string m_configFile;
ConfigSection m_configSection;
@@ -99,6 +104,9 @@ private:
unique_ptr<StatusServer> m_statusServer;
ndn::KeyChain& m_keyChain;
ndn::util::NetworkMonitor m_networkMonitor;
scheduler::ScopedEventId m_reloadConfigEvent;
};
} // namespace nfd
-1
View File
@@ -35,7 +35,6 @@ EntryImpl::EntryImpl(const Name& name)
}
EntryImpl::EntryImpl(shared_ptr<const Data> data, bool isUnsolicited)
: queueType(QUEUE_NONE)
{
this->setData(data, isUnsolicited);
BOOST_ASSERT(!this->isQuery());
-7
View File
@@ -26,9 +26,7 @@
#ifndef NFD_DAEMON_TABLE_CS_ENTRY_IMPL_HPP
#define NFD_DAEMON_TABLE_CS_ENTRY_IMPL_HPP
#include "cs-internal.hpp"
#include "cs-entry.hpp"
#include "core/scheduler.hpp"
namespace nfd {
namespace cs {
@@ -69,11 +67,6 @@ private:
bool
isQuery() const;
public:
QueueType queueType;
QueueIt queueIt;
scheduler::EventId moveStaleEvent;
private:
Name m_queryName;
};
+1 -12
View File
@@ -38,18 +38,7 @@ namespace cs {
class EntryImpl;
typedef std::set<EntryImpl> Table;
typedef Table::const_iterator TableIt;
typedef std::list<TableIt> Queue;
typedef Queue::iterator QueueIt;
enum QueueType {
QUEUE_UNSOLICITED,
QUEUE_STALE,
QUEUE_FIFO,
QUEUE_MAX,
QUEUE_NONE = QUEUE_MAX
};
typedef Table::const_iterator iterator;
} // namespace cs
} // namespace nfd
+94
View File
@@ -0,0 +1,94 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cs-policy-lru.hpp"
#include "cs.hpp"
#include <ndn-cxx/util/signal.hpp>
namespace nfd {
namespace cs {
namespace lru {
const std::string LruPolicy::POLICY_NAME = "lru";
LruPolicy::LruPolicy()
: Policy(POLICY_NAME)
{
}
void
LruPolicy::doAfterInsert(iterator i)
{
this->insertToQueue(i, true);
this->evictEntries();
}
void
LruPolicy::doAfterRefresh(iterator i)
{
this->insertToQueue(i, false);
}
void
LruPolicy::doBeforeErase(iterator i)
{
m_queue.get<1>().erase(i);
}
void
LruPolicy::doBeforeUse(iterator i)
{
this->insertToQueue(i, false);
}
void
LruPolicy::evictEntries()
{
BOOST_ASSERT(this->getCs() != nullptr);
while (this->getCs()->size() > this->getLimit()) {
BOOST_ASSERT(!m_queue.empty());
iterator i = m_queue.front();
m_queue.pop_front();
this->emitSignal(beforeEvict, i);
}
}
void
LruPolicy::insertToQueue(iterator i, bool isNewEntry)
{
Queue::iterator it;
bool isNew = false;
// push_back only if iterator i does not exist
std::tie(it, isNew) = m_queue.push_back(i);
BOOST_ASSERT(isNew == isNewEntry);
if (!isNewEntry) {
m_queue.relocate(m_queue.end(), it);
}
}
} // namespace lru
} // namespace cs
} // namespace nfd
+106
View File
@@ -0,0 +1,106 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_TABLE_CS_POLICY_LRU_HPP
#define NFD_DAEMON_TABLE_CS_POLICY_LRU_HPP
#include "cs-policy.hpp"
#include "common.hpp"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
namespace nfd {
namespace cs {
namespace lru {
struct EntryItComparator
{
bool
operator()(const iterator& a, const iterator& b) const
{
return *a < *b;
}
};
typedef boost::multi_index_container<
iterator,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>,
boost::multi_index::ordered_unique<
boost::multi_index::identity<iterator>, EntryItComparator
>
>
> Queue;
/** \brief LRU cs replacement policy
*
* The least recently used entries get removed first.
* Everytime when any entry is used or refreshed, Policy should witness the usage
* of it.
*/
class LruPolicy : public Policy
{
public:
LruPolicy();
public:
static const std::string POLICY_NAME;
private:
virtual void
doAfterInsert(iterator i) DECL_OVERRIDE;
virtual void
doAfterRefresh(iterator i) DECL_OVERRIDE;
virtual void
doBeforeErase(iterator i) DECL_OVERRIDE;
virtual void
doBeforeUse(iterator i) DECL_OVERRIDE;
virtual void
evictEntries() DECL_OVERRIDE;
private:
/** \brief moves an entry to the end of queue
*/
void
insertToQueue(iterator i, bool isNewEntry);
private:
Queue m_queue;
};
} // namespace lru
using lru::LruPolicy;
} // namespace cs
} // namespace nfd
#endif // NFD_DAEMON_TABLE_CS_POLICY_LRU_HPP
+157
View File
@@ -0,0 +1,157 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cs-policy-priority-fifo.hpp"
#include "cs.hpp"
#include <ndn-cxx/util/signal.hpp>
namespace nfd {
namespace cs {
namespace priority_fifo {
const std::string PriorityFifoPolicy::POLICY_NAME = "fifo";
PriorityFifoPolicy::PriorityFifoPolicy()
: Policy(POLICY_NAME)
{
}
void
PriorityFifoPolicy::doAfterInsert(iterator i)
{
this->attachQueue(i);
this->evictEntries();
}
void
PriorityFifoPolicy::doAfterRefresh(iterator i)
{
this->detachQueue(i);
this->attachQueue(i);
}
void
PriorityFifoPolicy::doBeforeErase(iterator i)
{
this->detachQueue(i);
}
void
PriorityFifoPolicy::doBeforeUse(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
}
void
PriorityFifoPolicy::evictEntries()
{
BOOST_ASSERT(this->getCs() != nullptr);
while (this->getCs()->size() > this->getLimit()) {
this->evictOne();
}
}
void
PriorityFifoPolicy::evictOne()
{
BOOST_ASSERT(!m_queues[QUEUE_UNSOLICITED].empty() ||
!m_queues[QUEUE_STALE].empty() ||
!m_queues[QUEUE_FIFO].empty());
iterator i;
if (!m_queues[QUEUE_UNSOLICITED].empty()) {
i = m_queues[QUEUE_UNSOLICITED].front();
}
else if (!m_queues[QUEUE_STALE].empty()) {
i = m_queues[QUEUE_STALE].front();
}
else if (!m_queues[QUEUE_FIFO].empty()) {
i = m_queues[QUEUE_FIFO].front();
}
this->detachQueue(i);
this->emitSignal(beforeEvict, i);
}
void
PriorityFifoPolicy::attachQueue(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) == m_entryInfoMap.end());
EntryInfo* entryInfo = new EntryInfo();
if (i->isUnsolicited()) {
entryInfo->queueType = QUEUE_UNSOLICITED;
}
else if (i->isStale()) {
entryInfo->queueType = QUEUE_STALE;
}
else {
entryInfo->queueType = QUEUE_FIFO;
if (i->canStale()) {
entryInfo->moveStaleEventId = scheduler::schedule(i->getData().getFreshnessPeriod(),
bind(&PriorityFifoPolicy::moveToStaleQueue, this, i));
}
}
Queue& queue = m_queues[entryInfo->queueType];
entryInfo->queueIt = queue.insert(queue.end(), i);
m_entryInfoMap[i] = entryInfo;
}
void
PriorityFifoPolicy::detachQueue(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
EntryInfo* entryInfo = m_entryInfoMap[i];
if (entryInfo->queueType == QUEUE_FIFO) {
scheduler::cancel(entryInfo->moveStaleEventId);
}
m_queues[entryInfo->queueType].erase(entryInfo->queueIt);
m_entryInfoMap.erase(i);
}
void
PriorityFifoPolicy::moveToStaleQueue(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
EntryInfo* entryInfo = m_entryInfoMap[i];
BOOST_ASSERT(entryInfo->queueType == QUEUE_FIFO);
m_queues[QUEUE_FIFO].erase(entryInfo->queueIt);
entryInfo->queueType = QUEUE_STALE;
Queue& queue = m_queues[QUEUE_STALE];
entryInfo->queueIt = queue.insert(queue.end(), i);
m_entryInfoMap[i] = entryInfo;
}
} // namespace priorityfifo
} // namespace cs
} // namespace nfd
+133
View File
@@ -0,0 +1,133 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
#define NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
#include "cs-policy.hpp"
#include "common.hpp"
#include "core/scheduler.hpp"
namespace nfd {
namespace cs {
namespace priority_fifo {
typedef std::list<iterator> Queue;
typedef Queue::iterator QueueIt;
enum QueueType {
QUEUE_UNSOLICITED,
QUEUE_STALE,
QUEUE_FIFO,
QUEUE_MAX
};
struct EntryInfo
{
QueueType queueType;
QueueIt queueIt;
scheduler::EventId moveStaleEventId;
};
struct EntryItComparator
{
bool
operator()(const iterator& a, const iterator& b) const
{
return *a < *b;
}
};
typedef std::map<iterator, EntryInfo*, EntryItComparator> EntryInfoMapFifo;
/** \brief Priority Fifo cs replacement policy
*
* The entries that get removed first are unsolicited Data packets,
* which are the Data packets that got cached opportunistically without preceding
* forwarding of the corresponding Interest packet.
* Next, the Data packets with expired freshness are removed.
* Last, the Data packets are removed from the Content Store on a pure FIFO basis.
*/
class PriorityFifoPolicy : public Policy
{
public:
PriorityFifoPolicy();
public:
static const std::string POLICY_NAME;
private:
virtual void
doAfterInsert(iterator i) DECL_OVERRIDE;
virtual void
doAfterRefresh(iterator i) DECL_OVERRIDE;
virtual void
doBeforeErase(iterator i) DECL_OVERRIDE;
virtual void
doBeforeUse(iterator i) DECL_OVERRIDE;
virtual void
evictEntries() DECL_OVERRIDE;
private:
/** \brief evicts one entry
* \pre CS is not empty
*/
void
evictOne();
/** \brief attaches the entry to an appropriate queue
* \pre the entry is not in any queue
*/
void
attachQueue(iterator i);
/** \brief detaches the entry from its current queue
* \post the entry is not in any queue
*/
void
detachQueue(iterator i);
/** \brief moves an entry from FIFO queue to STALE queue
*/
void
moveToStaleQueue(iterator i);
private:
Queue m_queues[QUEUE_MAX];
EntryInfoMapFifo m_entryInfoMap;
};
} // namespace priorityfifo
using priority_fifo::PriorityFifoPolicy;
} // namespace cs
} // namespace nfd
#endif // NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
+79
View File
@@ -0,0 +1,79 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cs-policy.hpp"
#include "cs.hpp"
namespace nfd {
namespace cs {
Policy::Policy(const std::string& policyName)
: m_policyName(policyName)
{
}
Policy::~Policy()
{
}
void
Policy::setLimit(size_t nMaxEntries)
{
BOOST_ASSERT(nMaxEntries > 0);
m_limit = nMaxEntries;
this->evictEntries();
}
void
Policy::afterInsert(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doAfterInsert(i);
}
void
Policy::afterRefresh(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doAfterRefresh(i);
}
void
Policy::beforeErase(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doBeforeErase(i);
}
void
Policy::beforeUse(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doBeforeUse(i);
}
} // namespace cs
} // namespace nfd
+191
View File
@@ -0,0 +1,191 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_TABLE_CS_POLICY_HPP
#define NFD_DAEMON_TABLE_CS_POLICY_HPP
#include "cs-internal.hpp"
#include "cs-entry-impl.hpp"
namespace nfd {
namespace cs {
class Cs;
/** \brief represents a CS replacement policy
*/
class Policy : noncopyable
{
public:
explicit
Policy(const std::string& policyName);
virtual
~Policy();
const std::string&
getName() const;
public:
/** \brief gets cs
*/
Cs*
getCs() const;
/** \brief sets cs
*/
void
setCs(Cs *cs);
/** \brief gets hard limit (in number of entries)
*/
size_t
getLimit() const;
/** \brief sets hard limit (in number of entries)
* \post getLimit() == nMaxEntries
* \post cs.size() <= getLimit()
*
* The policy may evict entries if necessary.
*/
void
setLimit(size_t nMaxEntries);
/** \brief emits when an entry is being evicted
*
* A policy implementation should emit this signal to cause CS to erase the entry from its index.
* CS should connect to this signal and erase the entry upon signal emission.
*/
signal::Signal<Policy, iterator> beforeEvict;
/** \brief invoked by CS after a new entry is inserted
* \post cs.size() <= getLimit()
*
* The policy may evict entries if necessary.
* During this process, \p i might be evicted.
*/
void
afterInsert(iterator i);
/** \brief invoked by CS after an existing entry is refreshed by same Data
*
* The policy may witness this refresh to make better eviction decisions in the future.
*/
void
afterRefresh(iterator i);
/** \brief invoked by CS before an entry is erased due to management command
* \warning CS must not invoke this method if an entry is erased due to eviction.
*/
void
beforeErase(iterator i);
/** \brief invoked by CS before an entry is used to match a lookup
*
* The policy may witness this usage to make better eviction decisions in the future.
*/
void
beforeUse(iterator i);
protected:
/** \brief invoked after a new entry is created in CS
*
* When overridden in a subclass, a policy implementation should decide whether to accept \p i.
* If \p i is accepted, it should be inserted into a cleanup index.
* Otherwise, \p beforeEvict signal should be emitted with \p i to inform CS to erase the entry.
* A policy implementation may decide to evict other entries by emitting \p beforeEvict signal,
* in order to keep CS size under limit.
*/
virtual void
doAfterInsert(iterator i) = 0;
/** \brief invoked after an existing entry is refreshed by same Data
*
* When overridden in a subclass, a policy implementation may witness this operation
* and adjust its cleanup index.
*/
virtual void
doAfterRefresh(iterator i) = 0;
/** \brief invoked before an entry is erased due to management command
* \note This will not be invoked for an entry being evicted by policy.
*
* When overridden in a subclass, a policy implementation should erase \p i
* from its cleanup index without emitted \p afterErase signal.
*/
virtual void
doBeforeErase(iterator i) = 0;
/** \brief invoked before an entry is used to match a lookup
*
* When overridden in a subclass, a policy implementation may witness this operation
* and adjust its cleanup index.
*/
virtual void
doBeforeUse(iterator i) = 0;
/** \brief evicts zero or more entries
* \post CS size does not exceed hard limit
*/
virtual void
evictEntries() = 0;
protected:
DECLARE_SIGNAL_EMIT(beforeEvict)
private:
std::string m_policyName;
size_t m_limit;
Cs* m_cs;
};
inline const std::string&
Policy::getName() const
{
return m_policyName;
}
inline Cs*
Policy::getCs() const
{
return m_cs;
}
inline void
Policy::setCs(Cs *cs)
{
m_cs = cs;
}
inline size_t
Policy::getLimit() const
{
return m_limit;
}
} // namespace cs
} // namespace nfd
#endif // NFD_DAEMON_TABLE_CS_POLICY_HPP
+58 -113
View File
@@ -24,9 +24,9 @@
*/
#include "cs.hpp"
#include "cs-policy-priority-fifo.hpp"
#include "core/logger.hpp"
#include "core/algorithm.hpp"
#include <numeric>
NFD_LOG_INIT("ContentStore");
@@ -44,18 +44,38 @@ static_assert(std::is_default_constructible<Cs::const_iterator>::value,
BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Cs::const_iterator>));
#endif // HAVE_IS_DEFAULT_CONSTRUCTIBLE
Cs::Cs(size_t nMaxPackets)
: m_limit(nMaxPackets)
unique_ptr<Policy>
makeDefaultPolicy()
{
BOOST_ASSERT(nMaxPackets > 0);
return unique_ptr<Policy>(new PriorityFifoPolicy());
}
Cs::Cs(size_t nMaxPackets, unique_ptr<Policy> policy)
{
this->setPolicyImpl(policy);
m_policy->setLimit(nMaxPackets);
}
void
Cs::setLimit(size_t nMaxPackets)
{
BOOST_ASSERT(nMaxPackets > 0);
m_limit = nMaxPackets;
this->evict();
m_policy->setLimit(nMaxPackets);
}
size_t
Cs::getLimit() const
{
return m_policy->getLimit();
}
void
Cs::setPolicy(unique_ptr<Policy> policy)
{
BOOST_ASSERT(policy != nullptr);
BOOST_ASSERT(m_policy != nullptr);
size_t limit = m_policy->getLimit();
this->setPolicyImpl(policy);
m_policy->setLimit(limit);
}
bool
@@ -73,26 +93,25 @@ Cs::insert(const Data& data, bool isUnsolicited)
}
}
bool isNewEntry = false; TableIt it;
bool isNewEntry = false;
iterator it;
// use .insert because gcc46 does not support .emplace
std::tie(it, isNewEntry) = m_table.insert(EntryImpl(data.shared_from_this(), isUnsolicited));
EntryImpl& entry = const_cast<EntryImpl&>(*it);
entry.updateStaleTime();
if (!isNewEntry) { // existing entry
this->detachQueue(it);
// XXX This doesn't forbid unsolicited Data from refreshing a solicited entry.
if (entry.isUnsolicited() && !isUnsolicited) {
entry.unsetUnsolicited();
}
m_policy->afterRefresh(it);
}
else {
m_policy->afterInsert(it);
}
entry.updateStaleTime();
this->attachQueue(it);
// check there are same amount of entries in the table and in queues
BOOST_ASSERT(m_table.size() == std::accumulate(m_queues, m_queues + QUEUE_MAX, 0U,
[] (size_t sum, const Queue queue) { return sum + queue.size(); }));
this->evict(); // XXX The new entry could be evicted, but it shouldn't matter.
return true;
}
@@ -109,13 +128,13 @@ Cs::find(const Interest& interest,
bool isRightmost = interest.getChildSelector() == 1;
NFD_LOG_DEBUG("find " << prefix << (isRightmost ? " R" : " L"));
TableIt first = m_table.lower_bound(prefix);
TableIt last = m_table.end();
iterator first = m_table.lower_bound(prefix);
iterator last = m_table.end();
if (prefix.size() > 0) {
last = m_table.lower_bound(prefix.getSuccessor());
}
TableIt match = last;
iterator match = last;
if (isRightmost) {
match = this->findRightmost(interest, first, last);
}
@@ -129,39 +148,40 @@ Cs::find(const Interest& interest,
return;
}
NFD_LOG_DEBUG(" matching " << match->getName());
m_policy->beforeUse(match);
hitCallback(interest, match->getData());
}
TableIt
Cs::findLeftmost(const Interest& interest, TableIt first, TableIt last) const
iterator
Cs::findLeftmost(const Interest& interest, iterator first, iterator last) const
{
return std::find_if(first, last, bind(&cs::EntryImpl::canSatisfy, _1, interest));
}
TableIt
Cs::findRightmost(const Interest& interest, TableIt first, TableIt last) const
iterator
Cs::findRightmost(const Interest& interest, iterator first, iterator last) const
{
// Each loop visits a sub-namespace under a prefix one component longer than Interest Name.
// If there is a match in that sub-namespace, the leftmost match is returned;
// otherwise, loop continues.
size_t interestNameLength = interest.getName().size();
for (TableIt right = last; right != first;) {
TableIt prev = std::prev(right);
for (iterator right = last; right != first;) {
iterator prev = std::prev(right);
// special case: [first,prev] have exact Names
if (prev->getName().size() == interestNameLength) {
NFD_LOG_TRACE(" find-among-exact " << prev->getName());
TableIt matchExact = this->findRightmostAmongExact(interest, first, right);
iterator matchExact = this->findRightmostAmongExact(interest, first, right);
return matchExact == right ? last : matchExact;
}
Name prefix = prev->getName().getPrefix(interestNameLength + 1);
TableIt left = m_table.lower_bound(prefix);
iterator left = m_table.lower_bound(prefix);
// normal case: [left,right) are under one-component-longer prefix
NFD_LOG_TRACE(" find-under-prefix " << prefix);
TableIt match = this->findLeftmost(interest, left, right);
iterator match = this->findLeftmost(interest, left, right);
if (match != right) {
return match;
}
@@ -170,97 +190,22 @@ Cs::findRightmost(const Interest& interest, TableIt first, TableIt last) const
return last;
}
TableIt
Cs::findRightmostAmongExact(const Interest& interest, TableIt first, TableIt last) const
iterator
Cs::findRightmostAmongExact(const Interest& interest, iterator first, iterator last) const
{
return find_last_if(first, last, bind(&EntryImpl::canSatisfy, _1, interest));
}
void
Cs::attachQueue(TableIt it)
Cs::setPolicyImpl(unique_ptr<Policy>& policy)
{
EntryImpl& entry = const_cast<EntryImpl&>(*it);
m_policy = std::move(policy);
m_beforeEvictConnection = m_policy->beforeEvict.connect([this] (iterator it) {
m_table.erase(it);
});
if (entry.queueType != QUEUE_NONE) {
this->detachQueue(it);
}
if (entry.isUnsolicited()) {
entry.queueType = QUEUE_UNSOLICITED;
}
else if (entry.isStale()) {
entry.queueType = QUEUE_STALE;
}
else {
entry.queueType = QUEUE_FIFO;
if (entry.canStale()) {
entry.moveStaleEvent = scheduler::schedule(entry.getData().getFreshnessPeriod(),
bind(&Cs::moveToStaleQueue, this, it));
}
}
Queue& queue = m_queues[entry.queueType];
entry.queueIt = queue.insert(queue.end(), it);
}
void
Cs::detachQueue(TableIt it)
{
EntryImpl& entry = const_cast<EntryImpl&>(*it);
BOOST_ASSERT(entry.queueType != QUEUE_NONE);
if (entry.queueType == QUEUE_FIFO) {
scheduler::cancel(entry.moveStaleEvent);
}
m_queues[entry.queueType].erase(entry.queueIt);
entry.queueType = QUEUE_NONE;
}
void
Cs::moveToStaleQueue(TableIt it)
{
EntryImpl& entry = const_cast<EntryImpl&>(*it);
BOOST_ASSERT(entry.queueType == QUEUE_FIFO);
m_queues[QUEUE_FIFO].erase(entry.queueIt);
entry.queueType = QUEUE_STALE;
Queue& queue = m_queues[QUEUE_STALE];
entry.queueIt = queue.insert(queue.end(), it);
}
std::tuple<TableIt, std::string>
Cs::evictPick()
{
if (!m_queues[QUEUE_UNSOLICITED].empty()) {
return std::make_tuple(m_queues[QUEUE_UNSOLICITED].front(), "unsolicited");
}
if (!m_queues[QUEUE_STALE].empty()) {
return std::make_tuple(m_queues[QUEUE_STALE].front(), "stale");
}
if (!m_queues[QUEUE_FIFO].empty()) {
return std::make_tuple(m_queues[QUEUE_FIFO].front(), "fifo");
}
BOOST_ASSERT(false);
return std::make_tuple(m_table.end(), "error");
}
void
Cs::evict()
{
while (this->size() > m_limit) {
TableIt it; std::string reason;
std::tie(it, reason) = this->evictPick();
NFD_LOG_DEBUG("evict " << it->getName() << " " << reason);
this->detachQueue(it);
m_table.erase(it);
}
m_policy->setCs(this);
BOOST_ASSERT(m_policy->getCs() == this);
}
void
+30 -39
View File
@@ -48,19 +48,25 @@
#ifndef NFD_DAEMON_TABLE_CS_HPP
#define NFD_DAEMON_TABLE_CS_HPP
#include "cs-policy.hpp"
#include "cs-internal.hpp"
#include "cs-entry-impl.hpp"
#include <ndn-cxx/util/signal.hpp>
#include <boost/iterator/transform_iterator.hpp>
namespace nfd {
namespace cs {
unique_ptr<Policy>
makeDefaultPolicy();
/** \brief represents the ContentStore
*/
class Cs : noncopyable
{
public:
explicit
Cs(size_t nMaxPackets = 10);
Cs(size_t nMaxPackets = 10, unique_ptr<Policy> policy = makeDefaultPolicy());
/** \brief inserts a Data packet
* \return true
@@ -97,9 +103,20 @@ public:
/** \return capacity (in number of packets)
*/
size_t
getLimit() const
getLimit() const;
/** \brief changes cs replacement policy
* \pre size() == 0
*/
void
setPolicy(unique_ptr<Policy> policy);
/** \return cs replacement policy
*/
Policy*
getPolicy() const
{
return m_limit;
return m_policy.get();
}
/** \return number of stored packets
@@ -128,7 +145,7 @@ public: // enumeration
/** \brief ContentStore iterator (public API)
*/
typedef boost::transform_iterator<EntryFromEntryImpl, TableIt, const Entry&> const_iterator;
typedef boost::transform_iterator<EntryFromEntryImpl, iterator, const Entry&> const_iterator;
const_iterator
begin() const
@@ -146,54 +163,28 @@ private: // find
/** \brief find leftmost match in [first,last)
* \return the leftmost match, or last if not found
*/
TableIt
findLeftmost(const Interest& interest, TableIt left, TableIt right) const;
iterator
findLeftmost(const Interest& interest, iterator left, iterator right) const;
/** \brief find rightmost match in [first,last)
* \return the rightmost match, or last if not found
*/
TableIt
findRightmost(const Interest& interest, TableIt first, TableIt last) const;
iterator
findRightmost(const Interest& interest, iterator first, iterator last) const;
/** \brief find rightmost match among entries with exact Names in [first,last)
* \return the rightmost match, or last if not found
*/
TableIt
findRightmostAmongExact(const Interest& interest, TableIt first, TableIt last) const;
iterator
findRightmostAmongExact(const Interest& interest, iterator first, iterator last) const;
private: // cleanup
/** \brief attaches an entry to a suitable cleanup queue
* \note if the entry is already attached to a queue, it's automatically detached
*/
void
attachQueue(TableIt it);
/** \brief detaches an entry from its current cleanup queue
* \warning if the entry is unattached, this will cause undefined behavior
*/
void
detachQueue(TableIt it);
/** \brief moves an entry from FIFO queue to STALE queue
*/
void
moveToStaleQueue(TableIt it);
/** \brief picks an entry for eviction
*/
std::tuple<TableIt, std::string/*reason*/>
evictPick();
/** \brief evicts zero or more entries so that number of stored entries
* is not greater than capacity
*/
void
evict();
setPolicyImpl(unique_ptr<Policy>& policy);
private:
size_t m_limit;
Table m_table;
Queue m_queues[QUEUE_MAX];
unique_ptr<Policy> m_policy;
ndn::util::signal::ScopedConnection m_beforeEvictConnection;
};
} // namespace cs
+1 -1
View File
@@ -51,7 +51,7 @@ DeadNonceList::DeadNonceList(const time::nanoseconds& lifetime)
, m_adjustCapacityInterval(m_lifetime)
{
if (m_lifetime < MIN_LIFETIME) {
throw std::invalid_argument("lifetime is less than MIN_LIFETIME");
BOOST_THROW_EXCEPTION(std::invalid_argument("lifetime is less than MIN_LIFETIME"));
}
for (size_t i = 0; i < EXPECTED_MARK_COUNT; ++i) {
+2 -5
View File
@@ -614,14 +614,12 @@ NameTree::const_iterator::operator++()
if (m_type == FULL_ENUMERATE_TYPE) // fullEnumerate
{
bool isFound = false;
// process the entries in the same bucket first
while (m_entry->m_node->m_next != 0)
{
m_entry = m_entry->m_node->m_next->m_entry;
if ((*m_entrySelector)(*m_entry))
{
isFound = true;
return *this;
}
}
@@ -639,14 +637,13 @@ NameTree::const_iterator::operator++()
m_entry = node->m_entry;
if ((*m_entrySelector)(*m_entry))
{
isFound = true;
return *this;
}
node = node->m_next;
}
}
BOOST_VERIFY(isFound == false);
// Reach to the end()
// Reach the end()
m_entry = m_nameTree->m_end;
return *this;
}
+104
View File
@@ -3,6 +3,110 @@
NFD Release Notes
=================
NFD version 0.3.4 (changes since version 0.3.3)
+++++++++++++++++++++++++++++++++++++++++++++++
Release date: August 31, 2015
New features:
^^^^^^^^^^^^^
- Boolean Face property IsOnDemand has been replaced with multistate FacePersistency
property (:issue:`2989`, :issue:`3018`): persistent (Face exists as long as there are no
system or socket errors), on-demand (Face is removed after inactivity period), and
permanent (Face exists unless explicitly destroyed by the management).
Currently, only UDP faces are allowed to be permanent. However, management interface to
create UDP permanent faces or switch UDP to permanent state will be available in the
next release (:issue:`2991`).
- Least Recently Used policy for Content Store (:issue:`2219`)
Currently, changing the policy requires a minor change in NFD source code.
Configuration interface is coming in the next release (:issue:`3148`)
Updates and bug fixes:
^^^^^^^^^^^^^^^^^^^^^^
- Update of NDN Essential Tools to version 0.2 `<https://github.com/named-data/ndn-tools>`__
with code improvements and the following new tools:
* PIB service to manage the public information of keys and publish certificates
(:issue:`3018`)
* A Wireshark dissector for NDN packets (:issue:`3092`)
- RibManager constructor now accepts KeyChain as a parameter, preparing it for simplifying
implementation with the new ``ndn::Dispatcher`` class (:issue:`2390`)
- Fix HTML rendering of nfd-status-http-server output in some browsers (:issue:`3019`)
- Enable automatic re-creation of multicast faces when network connectivity changes
(:issue:`2460`)
- Enhance exception throwing with Boost Exception library (:issue:`2541`)
Deprecated:
^^^^^^^^^^^
- BroadcastStrategy (``/localhost/nfd/strategy/broadcast``) renamed as MulticastStrategy
(``/localhost/nfd/strategy/multicast``) (:issue:`3011`)
Upcoming features (partially finished in development branches):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- NDNLPv2 (http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2, :issue:`2520`,
:issue:`2879`, :issue:`2763`, :issue:`2883`, :issue:`2841`, :issue:`2866`)
- Refactored implementation of NFD management (:issue:`2200`, :issue:`2107`)
****************************************************************************
NFD version 0.3.3 (changes since version 0.3.2)
+++++++++++++++++++++++++++++++++++++++++++++++
Release date: July 1, 2015
New features:
^^^^^^^^^^^^^
- Content Store replacement policy interface (:issue:`1207`)
- Add unit file and instructions for systemd (:issue:`1586`)
- NDN Essential Tools version 0.1 `<https://github.com/named-data/ndn-tools>`__ featuring:
* ``ndnpeek``, ``ndnpoke``: a pair of programs to request and make available for retrieval of
a single Data packet
* ``ndnping``, ``ndnpingserver``: reachability testing tools for Named Data Networking
* ``ndndump``: a traffic analysis tool that captures Interest and Data packets on the wire
* ``ndn-dissect``: an NDN packet format inspector. It reads zero or more NDN packets from
either an input file or the standard input, and displays the Type-Length-Value (TLV)
structure of those packets on the standard output.
Updates and bug fixes:
^^^^^^^^^^^^^^^^^^^^^^
- Avoid loopback new Interest in AccessStrategy (:issue:`2831`)
- Simplified implementation of ``nfd-status`` using SegmentFetcher utility class (:issue:`2456`)
Deprecated:
^^^^^^^^^^^
- ``ndn-tlv-peek`` and ``ndn-tlv-poke`` command-line tools: use ``ndnpeek`` and ``ndnpoke``
programs from NDN Essential Tools repository `<https://github.com/named-data/ndn-tools>`__.
Upcoming features:
^^^^^^^^^^^^^^^^^^
- NDNLPv2 (http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2, :issue:`2520`,
:issue:`2879`, :issue:`2763`, :issue:`2883`, :issue:`2841`, :issue:`2866`)
- Refactored implementation of NFD management (:issue:`2200`, :issue:`2107`)
****************************************************************************
NFD version 0.3.2 (changes since version 0.3.1)
+++++++++++++++++++++++++++++++++++++++++++++++
-1
View File
@@ -241,7 +241,6 @@ latex_documents = [
# (source start file, name, description, authors, manual section).
man_pages = [
('manpages/nfd', 'nfd', u'Named Data Networking Forwarding Daemon', None, 1),
('manpages/nrd', 'nrd', u'NFD RIB Daemon', None, 1),
('manpages/ndn-autoconfig-server', 'ndn-autoconfig-server',
u'NFD Auto-configuration Server', None, 1),
('manpages/ndn-autoconfig', 'ndn-autoconfig',
+5
View File
@@ -38,6 +38,11 @@ This procedure contains three methods to discover a NDN router:
3. Connect to the home NDN router according to user certificate.
This ensures connectivity from anywhere.
After connecting to an NDN router, two prefixes will be automatically registered:
- /ndn
- /localhop/nfd --- this to inform RIB manager that there is connectivity to the hub
Stage 1: multicast discovery
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+6
View File
@@ -1,6 +1,12 @@
ndn-tlv-peek
============
Deprecated
----------
ndn-tlv-peek is deprecated and will be removed in a future release of NFD.
Please use ``ndnpeek`` program from ndn-tools repository `<https://github.com/named-data/ndn-tools>`__.
Usage
-----
+6
View File
@@ -1,6 +1,12 @@
ndn-tlv-poke
============
Deprecated
----------
ndn-tlv-poke is deprecated and will be removed in a future release of NFD.
Please use ``ndnpoke`` program from ndn-tools repository `<https://github.com/named-data/ndn-tools>`__.
Usage
-----
+5 -4
View File
@@ -42,7 +42,7 @@ Options
Expiration time of the RIB entry in milliseconds. If not specified, the entry remains in FIB
for the lifetime of the associated face.
``-o <origin>``
``-o <origin>``
Origin of the registration request (default is 255).
0 for Local producer applications, 128 for NLSR, 255 for static routes.
@@ -62,10 +62,10 @@ Options
``unregister [-o origin] <prefix> <faceId>``
``-o <origin>``
``-o <origin>``
Origin of the unregistration request (default is 255).
``prefix``
``prefix``
A prefix of an existing RIB entry, from which routing entry is requested to be
removed.
@@ -119,9 +119,10 @@ Options
Currently, NFD supports the following strategies::
ndn:/localhost/nfd/strategy/best-route
ndn:/localhost/nfd/strategy/broadcast
ndn:/localhost/nfd/strategy/multicast
ndn:/localhost/nfd/strategy/client-control
ndn:/localhost/nfd/strategy/ncc
ndn:/localhost/nfd/strategy/access
``unset-strategy``
Unset the strategy for a given ``namespace``.
-34
View File
@@ -1,34 +0,0 @@
NRD (NFD RIB Daemon)
====================
Usage
-----
::
nrd [options]
Description
-----------
NRD is a complementary daemon designed to work in parallel with NFD and to provide
services for Routing Information Base management and constructing NFD's FIB:
* prefix registration from applications;
* manual prefix registration;
* prefix registrations from multiple dynamic routing protocols.
NRD's runtime settings may be modified via `rib_*` sections in NFD's configuration file.
Options:
--------
``--help``
Print this help message.
``--modules``
List available logging modules
``--config <path/to/nfd.conf>``
Specify the path to nfd configuration file (default: ``${SYSCONFDIR}/ndn/nfd.conf``).
+2 -2
View File
@@ -54,9 +54,9 @@ tables
strategy_choice
{
/ /localhost/nfd/strategy/best-route
/localhost /localhost/nfd/strategy/broadcast
/localhost /localhost/nfd/strategy/multicast
/localhost/nfd /localhost/nfd/strategy/best-route
/ndn/broadcast /localhost/nfd/strategy/broadcast
/ndn/broadcast /localhost/nfd/strategy/multicast
}
}
+2 -1
View File
@@ -305,7 +305,8 @@ FibUpdater::onUpdateError(const FibUpdate update,
}
}
else {
throw Error("Non-recoverable error: " + error + " code: " + std::to_string(code));
BOOST_THROW_EXCEPTION(Error("Non-recoverable error: " + error + " code: " +
std::to_string(code)));
}
}
+2 -2
View File
@@ -66,7 +66,7 @@ Nrd::initialize()
initializeLogging();
m_ribManager.reset(new RibManager(*m_face));
m_ribManager.reset(new RibManager(*m_face, m_keyChain));
ConfigFile config([] (const std::string& filename, const std::string& sectionName,
const ConfigSection& section, bool isDryRun) {
@@ -143,7 +143,7 @@ Nrd::getLocalNfdTransport()
return make_shared<ndn::TcpTransport>("localhost", port);
}
else {
throw Error("No transport is available to communicate with NFD");
BOOST_THROW_EXCEPTION(Error("No transport is available to communicate with NFD"));
}
}
+6 -5
View File
@@ -26,6 +26,7 @@
#include "remote-registrator.hpp"
#include "core/logger.hpp"
#include "core/scheduler.hpp"
#include <ndn-cxx/security/signing-helpers.hpp>
namespace nfd {
namespace rib {
@@ -89,8 +90,8 @@ RemoteRegistrator::loadConfig(const ConfigSection& configSection)
}
else
{
throw ConfigFile::Error("Unrecognized option \"" + i.first +
"\" in \"remote-registrator\" section");
BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i.first +
"\" in \"remote-registrator\" section"));
}
}
@@ -196,7 +197,7 @@ RemoteRegistrator::registerPrefix(const Name& prefix)
CommandOptions options = m_commandOptions;
startRegistration(parameters.setName(prefixForRegistration),
options.setSigningIdentity(identity.first),
options.setSigningInfo(signingByIdentity(identity.first)),
m_nRetries);
}
@@ -268,7 +269,7 @@ RemoteRegistrator::unregisterPrefix(const Name& prefix)
CommandOptions options = m_commandOptions;
startUnregistration(parameters.setName(prefixForRegistration).unsetCost(),
options.setSigningIdentity(identity.first),
options.setSigningInfo(signingByIdentity(identity.first)),
m_nRetries);
}
@@ -427,7 +428,7 @@ RemoteRegistrator::redoRegistration()
ControlParameters parameters = m_controlParameters;
CommandOptions options = m_commandOptions;
startRegistration(parameters.setName(entry.first),
options.setSigningIdentity(entry.first),
options.setSigningInfo(signingByIdentity(entry.first)),
m_nRetries);
}
}
+5 -4
View File
@@ -73,8 +73,9 @@ const size_t RibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
const time::seconds RibManager::ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
RibManager::RibManager(ndn::Face& face)
RibManager::RibManager(ndn::Face& face, ndn::KeyChain& keyChain)
: m_face(face)
, m_keyChain(keyChain)
, m_nfdController(m_face, m_keyChain)
, m_localhostValidator(m_face)
, m_localhopValidator(m_face)
@@ -166,7 +167,7 @@ RibManager::onConfig(const ConfigSection& configSection,
m_remoteRegistrator.enable();
}
else {
throw Error("Unrecognized rib property: " + item.first);
BOOST_THROW_EXCEPTION(Error("Unrecognized rib property: " + item.first));
}
}
@@ -570,7 +571,7 @@ RibManager::onNrdCommandPrefixAddNextHopSuccess(const Name& prefix,
void
RibManager::onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg)
{
throw Error("Error in setting interest filter (" + name.toUri() + "): " + msg);
BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() + "): " + msg));
}
void
@@ -585,7 +586,7 @@ RibManager::onControlHeaderError(uint32_t code, const std::string& reason)
std::ostringstream os;
os << "Couldn't enable local control header "
<< "(code: " << code << ", info: " << reason << ")";
throw Error(os.str());
BOOST_THROW_EXCEPTION(Error(os.str()));
}
void
+2 -3
View File
@@ -61,8 +61,7 @@ public:
}
};
explicit
RibManager(ndn::Face& face);
RibManager(ndn::Face& face, ndn::KeyChain& keyChain);
~RibManager();
@@ -202,8 +201,8 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
private:
ndn::Face& m_face;
ndn::KeyChain& m_keyChain;
ndn::nfd::Controller m_nfdController;
ndn::KeyChain m_keyChain;
ndn::ValidatorConfig m_localhostValidator;
ndn::ValidatorConfig m_localhopValidator;
ndn::nfd::FaceMonitor m_faceMonitor;
+1 -1
View File
@@ -73,7 +73,7 @@ protected:
size_t totalLength = 0;
for (int64_t i = 0; i < N; i++)
{
totalLength += ndn::prependNonNegativeIntegerBlock(outBuffer, tlv::Content, i);
totalLength += prependNonNegativeIntegerBlock(outBuffer, tlv::Content, i);
}
m_totalPayloadLength += totalLength;
return totalLength;
+2 -5
View File
@@ -53,10 +53,7 @@ public:
wireEncode() const
{
ndn::EncodingBuffer buffer;
ndn::prependByteArrayBlock(buffer,
0x8888,
reinterpret_cast<const uint8_t*>(m_message.c_str()),
m_message.size());
prependStringBlock(buffer, 0x8888, m_message);
return buffer.block();
}
@@ -68,7 +65,7 @@ public:
// error for testing
if (!m_message.empty() && m_message[0] == '\x07')
throw tlv::Error("0x07 error");
BOOST_THROW_EXCEPTION(tlv::Error("0x07 error"));
}
public:
+2 -2
View File
@@ -67,7 +67,7 @@ public:
{
if (error)
{
throw Error("Connection aborted");
BOOST_THROW_EXCEPTION(Error("Connection aborted"));
}
// This value may need to be adjusted if some dataset exceeds 100k
@@ -88,7 +88,7 @@ public:
onSendFinished(const boost::system::error_code& error, bool isFinal)
{
if (error) {
throw Error("Connection aborted");
BOOST_THROW_EXCEPTION(Error("Connection aborted"));
}
if (isFinal) {
+24 -1
View File
@@ -99,6 +99,29 @@ BOOST_AUTO_TEST_CASE(MulticastFacesMap)
BOOST_CHECK_NE(face1, face3);
}
BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
{
EthernetFactory factory;
BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
ndn::nfd::FACE_PERSISTENCY_PERMANENT,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
BOOST_CHECK_THROW(factory.createFace(FaceUri("ether://[08:00:27:01:01:01]"),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
}
BOOST_AUTO_TEST_CASE(SendPacket)
{
if (m_interfaces.empty()) {
@@ -113,7 +136,7 @@ BOOST_AUTO_TEST_CASE(SendPacket)
BOOST_REQUIRE(static_cast<bool>(face));
BOOST_CHECK_EQUAL(face->isLocal(), false);
BOOST_CHECK_EQUAL(face->isOnDemand(), false);
BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
BOOST_CHECK_EQUAL(face->isMultiAccess(), true);
BOOST_CHECK_EQUAL(face->getRemoteUri().toString(),
"ether://[" + ethernet::getDefaultMulticastAddress().toString() + "]");
+32 -11
View File
@@ -78,11 +78,6 @@ BOOST_AUTO_TEST_CASE(GetChannels)
class FaceCreateFixture : protected BaseFixture
{
public:
void
ignore()
{
}
void
checkError(const std::string& errorActual, const std::string& errorExpected)
{
@@ -98,20 +93,42 @@ public:
BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
{
TcpFactory factory = TcpFactory();
TcpFactory factory;
factory.createFace(FaceUri("tcp4://127.0.0.1:6363"),
bind(&FaceCreateFixture::ignore, this),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind(&FaceCreateFixture::checkError, this, _1,
"No channels available to connect to 127.0.0.1:6363"));
factory.createChannel("127.0.0.1", "20071");
factory.createFace(FaceUri("tcp4://127.0.0.1:20070"),
bind(&FaceCreateFixture::ignore, this),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind(&FaceCreateFixture::failIfError, this, _1));
}
BOOST_FIXTURE_TEST_CASE(UnsupportedFaceCreate, FaceCreateFixture)
{
TcpFactory factory;
factory.createChannel("127.0.0.1", "20070");
factory.createChannel("127.0.0.1", "20071");
BOOST_CHECK_THROW(factory.createFace(FaceUri("tcp4://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_PERMANENT,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
BOOST_CHECK_THROW(factory.createFace(FaceUri("tcp4://127.0.0.1:20071"),
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
}
class EndToEndFixture : protected BaseFixture
{
public:
@@ -266,6 +283,7 @@ BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
factory2.createChannel("127.0.0.2", "20071");
factory2.createFace(FaceUri("tcp4://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
@@ -275,8 +293,8 @@ BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
BOOST_REQUIRE(static_cast<bool>(face1));
BOOST_REQUIRE(static_cast<bool>(face2));
BOOST_CHECK_EQUAL(face1->isOnDemand(), true);
BOOST_CHECK_EQUAL(face2->isOnDemand(), false);
BOOST_CHECK_EQUAL(face1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
BOOST_CHECK_EQUAL(face2->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
BOOST_CHECK_EQUAL(face1->isMultiAccess(), false);
BOOST_CHECK_EQUAL(face2->isMultiAccess(), false);
@@ -353,6 +371,7 @@ BOOST_FIXTURE_TEST_CASE(EndToEnd6, EndToEndFixture)
factory2.createChannel("::2", "20070");
factory2.createFace(FaceUri("tcp6://[::1]:20070"),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
@@ -630,6 +649,7 @@ BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
shared_ptr<TcpChannel> channel = factory.createChannel("0.0.0.0", "20070");
factory.createFace(FaceUri("tcp4://192.0.2.1:20070"),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _1));
@@ -659,6 +679,7 @@ BOOST_FIXTURE_TEST_CASE(Bug1856, EndToEndFixture)
factory2.createChannel("127.0.0.2", "20071");
factory2.createFace(FaceUri("tcp4://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+35 -10
View File
@@ -126,7 +126,7 @@ BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
auto multicastFace1a = factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
BOOST_CHECK_EQUAL(multicastFace1->isLocal(), false);
BOOST_CHECK_EQUAL(multicastFace1->isOnDemand(), false);
BOOST_CHECK_EQUAL(multicastFace1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
BOOST_CHECK_EQUAL(multicastFace1->isMultiAccess(), true);
//same endpoint of a multicast face
@@ -199,11 +199,6 @@ BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
class FaceCreateFixture : protected BaseFixture
{
public:
void
ignore()
{
}
void
checkError(const std::string& errorActual, const std::string& errorExpected)
{
@@ -222,15 +217,40 @@ BOOST_FIXTURE_TEST_CASE(FaceCreate, FaceCreateFixture)
UdpFactory factory = UdpFactory();
factory.createFace(FaceUri("udp4://127.0.0.1:6363"),
bind(&FaceCreateFixture::ignore, this),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind(&FaceCreateFixture::checkError, this, _1,
"No channels available to connect to 127.0.0.1:6363"));
factory.createChannel("127.0.0.1", "20071");
factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
bind(&FaceCreateFixture::ignore, this),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind(&FaceCreateFixture::failIfError, this, _1));
//test the upgrade
factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_PERMANENT,
bind([]{}),
bind(&FaceCreateFixture::failIfError, this, _1));
factory.createFace(FaceUri("udp4://127.0.0.1:20072"),
ndn::nfd::FACE_PERSISTENCY_PERMANENT,
bind([]{}),
bind(&FaceCreateFixture::failIfError, this, _1));
}
BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
{
UdpFactory factory;
factory.createChannel("127.0.0.1", "20070");
BOOST_CHECK_THROW(factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
}
class EndToEndIpv4
@@ -351,6 +371,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(EndToEnd, A, EndToEndAddresses)
shared_ptr<Face> face1;
unique_ptr<FaceHistory> history1;
factory.createFace(A::getFaceUri2(),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face1 = newFace;
history1.reset(new FaceHistory(*face1, limitedIo));
@@ -462,6 +483,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, EndToEndAddresses)
boost::asio::ip::address ipAddress2 = boost::asio::ip::address::from_string(A::getLocalIp());
udp::Endpoint endpoint2(ipAddress2, boost::lexical_cast<uint16_t>(A::getPort1()));
channel2->connect(endpoint2,
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face2 = newFace;
limitedIo.afterOp();
@@ -479,6 +501,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, EndToEndAddresses)
boost::asio::ip::address ipAddress3 = boost::asio::ip::address::from_string(A::getLocalIp());
udp::Endpoint endpoint3(ipAddress3, boost::lexical_cast<uint16_t>(A::getPort1()));
channel3->connect(endpoint3,
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face3 = newFace;
limitedIo.afterOp();
@@ -516,6 +539,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(ManualClose, A, EndToEndAddresses)
shared_ptr<Face> face1;
unique_ptr<FaceHistory> history1;
factory.createFace(A::getFaceUri2(),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face1 = newFace;
history1.reset(new FaceHistory(*face1, limitedIo));
@@ -560,6 +584,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(IdleClose, A, EndToEndAddresses)
boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(A::getLocalIp());
udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(A::getPort1()));
channel2->connect(endpoint,
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
[&] (shared_ptr<Face> newFace) {
face2 = newFace;
history2.reset(new FaceHistory(*face2, limitedIo));
@@ -569,7 +594,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(IdleClose, A, EndToEndAddresses)
limitedIo.run(1, time::milliseconds(100)); // 1 create (on channel2)
BOOST_REQUIRE(face2 != nullptr);
BOOST_CHECK_EQUAL(face2->isOnDemand(), false);
BOOST_CHECK_EQUAL(face2->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
BOOST_CHECK_EQUAL(face2->isMultiAccess(), false);
// face2 sends to channel1, creates face1
@@ -579,7 +604,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(IdleClose, A, EndToEndAddresses)
limitedIo.run(2, time::seconds(1)); // 1 accept (on channel1), 1 receive (on face1)
BOOST_CHECK_EQUAL(channel1->size(), 1);
BOOST_REQUIRE(face1 != nullptr);
BOOST_CHECK_EQUAL(face1->isOnDemand(), true);
BOOST_CHECK_EQUAL(face1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
BOOST_CHECK_EQUAL(face1->isMultiAccess(), false);
limitedIo.defer(time::seconds(1));
+24 -1
View File
@@ -74,6 +74,29 @@ BOOST_AUTO_TEST_CASE(GetChannels)
BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
}
BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
{
UnixStreamFactory factory;
BOOST_CHECK_THROW(factory.createFace(FaceUri("unix:///var/run/nfd.sock"),
ndn::nfd::FACE_PERSISTENCY_PERMANENT,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
BOOST_CHECK_THROW(factory.createFace(FaceUri("unix:///var/run/nfd.sock"),
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
BOOST_CHECK_THROW(factory.createFace(FaceUri("unix:///var/run/nfd.sock"),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
}
class EndToEndFixture : protected BaseFixture
{
public:
@@ -190,7 +213,7 @@ BOOST_FIXTURE_TEST_CASE(EndToEnd, EndToEndFixture)
BOOST_REQUIRE(static_cast<bool>(face1));
BOOST_CHECK_EQUAL(face1->isLocal(), true);
BOOST_CHECK_EQUAL(face1->isOnDemand(), true);
BOOST_CHECK_EQUAL(face1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
BOOST_CHECK_EQUAL(face1->isMultiAccess(), false);
BOOST_CHECK_EQUAL(face1->getRemoteUri().getScheme(), "fd");
BOOST_CHECK_NO_THROW(std::stoi(face1->getRemoteUri().getHost()));
+24 -1
View File
@@ -65,6 +65,29 @@ BOOST_AUTO_TEST_CASE(GetChannels)
BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
}
BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
{
WebSocketFactory factory("19596");
BOOST_CHECK_THROW(factory.createFace(FaceUri("ws://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_PERMANENT,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
BOOST_CHECK_THROW(factory.createFace(FaceUri("ws://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
BOOST_CHECK_THROW(factory.createFace(FaceUri("ws://127.0.0.1:20070"),
ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
bind([]{}),
bind([]{})),
ProtocolFactory::Error);
}
class EndToEndFixture : protected BaseFixture
{
public:
@@ -236,7 +259,7 @@ BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
BOOST_REQUIRE(static_cast<bool>(face1));
BOOST_CHECK_EQUAL(face1->isLocal(), false);
BOOST_CHECK_EQUAL(face1->isOnDemand(), true);
BOOST_CHECK_EQUAL(face1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
BOOST_CHECK_EQUAL(face1->isMultiAccess(), false);
BOOST_CHECK_EQUAL(face1->getLocalUri().toString(), "ws://127.0.0.1:20070");
+17
View File
@@ -350,6 +350,23 @@ BOOST_FIXTURE_TEST_CASE(PacketLoss, TwoLaptopsFixture)
BOOST_CHECK_EQUAL(hasData2c, true);
}
BOOST_FIXTURE_TEST_CASE(Bug2831, TwoLaptopsFixture)
{
// make a two-node loop
topo.registerPrefix(laptopA, linkA->getFace(laptopA), "ndn:/net");
topo.registerPrefix(router, linkA->getFace(router), "ndn:/net");
// send Interests from laptopA to router
shared_ptr<TopologyAppLink> consumer = topo.addAppFace(laptopA);
topo.addIntervalConsumer(*consumer->getClientFace(), "ndn:/net",
time::milliseconds(100), 10);
this->advanceClocks(time::milliseconds(5), time::seconds(2));
// Interest shouldn't loop back from router
BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 0);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
+7 -83
View File
@@ -24,8 +24,6 @@
*/
#include "fw/broadcast-strategy.hpp"
#include "strategy-tester.hpp"
#include "tests/daemon/face/dummy-face.hpp"
#include "tests/test-common.hpp"
@@ -37,94 +35,20 @@ using namespace nfd::tests;
BOOST_FIXTURE_TEST_SUITE(FwBroadcastStrategy, BaseFixture)
BOOST_AUTO_TEST_CASE(Forward2)
BOOST_AUTO_TEST_CASE(Registry)
{
Forwarder forwarder;
typedef StrategyTester<fw::BroadcastStrategy> BroadcastStrategyTester;
BroadcastStrategyTester strategy(forwarder);
StrategyChoice& sc = forwarder.getStrategyChoice();
shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
forwarder.addFace(face1);
forwarder.addFace(face2);
forwarder.addFace(face3);
Fib& fib = forwarder.getFib();
shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
fibEntry->addNextHop(face1, 0);
fibEntry->addNextHop(face2, 0);
fibEntry->addNextHop(face3, 0);
shared_ptr<Interest> interest = makeInterest("ndn:/H0D6i5fc");
Pit& pit = forwarder.getPit();
shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
pitEntry->insertOrUpdateInRecord(face3, *interest);
strategy.afterReceiveInterest(*face3, *interest, fibEntry, pitEntry);
BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 0);
BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 2);
bool hasFace1 = false;
bool hasFace2 = false;
for (std::vector<BroadcastStrategyTester::SendInterestArgs>::iterator it =
strategy.m_sendInterestHistory.begin();
it != strategy.m_sendInterestHistory.end(); ++it) {
if (it->get<1>() == face1) {
hasFace1 = true;
}
if (it->get<1>() == face2) {
hasFace2 = true;
}
}
BOOST_CHECK(hasFace1 && hasFace2);
BOOST_CHECK(sc.hasStrategy("ndn:/localhost/nfd/strategy/broadcast"));
BOOST_CHECK(sc.hasStrategy("ndn:/localhost/nfd/strategy/multicast"));
}
BOOST_AUTO_TEST_CASE(RejectScope)
BOOST_AUTO_TEST_CASE(StrategyName)
{
Forwarder forwarder;
typedef StrategyTester<fw::BroadcastStrategy> BroadcastStrategyTester;
BroadcastStrategyTester strategy(forwarder);
shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
forwarder.addFace(face1);
forwarder.addFace(face2);
Fib& fib = forwarder.getFib();
shared_ptr<fib::Entry> fibEntry = fib.insert("ndn:/localhop/uS09bub6tm").first;
fibEntry->addNextHop(face2, 0);
shared_ptr<Interest> interest = makeInterest("ndn:/localhop/uS09bub6tm/eG3MMoP6z");
Pit& pit = forwarder.getPit();
shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
pitEntry->insertOrUpdateInRecord(face1, *interest);
strategy.afterReceiveInterest(*face1, *interest, fibEntry, pitEntry);
BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 1);
BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 0);
}
BOOST_AUTO_TEST_CASE(RejectLoopback)
{
Forwarder forwarder;
typedef StrategyTester<fw::BroadcastStrategy> BroadcastStrategyTester;
BroadcastStrategyTester strategy(forwarder);
shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
forwarder.addFace(face1);
Fib& fib = forwarder.getFib();
shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
fibEntry->addNextHop(face1, 0);
shared_ptr<Interest> interest = makeInterest("ndn:/H0D6i5fc");
Pit& pit = forwarder.getPit();
shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
pitEntry->insertOrUpdateInRecord(face1, *interest);
strategy.afterReceiveInterest(*face1, *interest, fibEntry, pitEntry);
BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 1);
BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 0);
fw::BroadcastStrategy strategy(forwarder);
BOOST_CHECK_EQUAL(strategy.getName(), fw::BroadcastStrategy::STRATEGY_NAME);
}
BOOST_AUTO_TEST_SUITE_END()
+134
View File
@@ -0,0 +1,134 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fw/multicast-strategy.hpp"
#include "strategy-tester.hpp"
#include "tests/daemon/face/dummy-face.hpp"
#include "tests/test-common.hpp"
namespace nfd {
namespace fw {
namespace tests {
using namespace nfd::tests;
BOOST_FIXTURE_TEST_SUITE(FwMulticastStrategy, BaseFixture)
BOOST_AUTO_TEST_CASE(Forward2)
{
Forwarder forwarder;
typedef StrategyTester<fw::MulticastStrategy> MulticastStrategyTester;
MulticastStrategyTester strategy(forwarder);
shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
forwarder.addFace(face1);
forwarder.addFace(face2);
forwarder.addFace(face3);
Fib& fib = forwarder.getFib();
shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
fibEntry->addNextHop(face1, 0);
fibEntry->addNextHop(face2, 0);
fibEntry->addNextHop(face3, 0);
shared_ptr<Interest> interest = makeInterest("ndn:/H0D6i5fc");
Pit& pit = forwarder.getPit();
shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
pitEntry->insertOrUpdateInRecord(face3, *interest);
strategy.afterReceiveInterest(*face3, *interest, fibEntry, pitEntry);
BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 0);
BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 2);
bool hasFace1 = false;
bool hasFace2 = false;
for (std::vector<MulticastStrategyTester::SendInterestArgs>::iterator it =
strategy.m_sendInterestHistory.begin();
it != strategy.m_sendInterestHistory.end(); ++it) {
if (it->get<1>() == face1) {
hasFace1 = true;
}
if (it->get<1>() == face2) {
hasFace2 = true;
}
}
BOOST_CHECK(hasFace1 && hasFace2);
}
BOOST_AUTO_TEST_CASE(RejectScope)
{
Forwarder forwarder;
typedef StrategyTester<fw::MulticastStrategy> MulticastStrategyTester;
MulticastStrategyTester strategy(forwarder);
shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
forwarder.addFace(face1);
forwarder.addFace(face2);
Fib& fib = forwarder.getFib();
shared_ptr<fib::Entry> fibEntry = fib.insert("ndn:/localhop/uS09bub6tm").first;
fibEntry->addNextHop(face2, 0);
shared_ptr<Interest> interest = makeInterest("ndn:/localhop/uS09bub6tm/eG3MMoP6z");
Pit& pit = forwarder.getPit();
shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
pitEntry->insertOrUpdateInRecord(face1, *interest);
strategy.afterReceiveInterest(*face1, *interest, fibEntry, pitEntry);
BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 1);
BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 0);
}
BOOST_AUTO_TEST_CASE(RejectLoopback)
{
Forwarder forwarder;
typedef StrategyTester<fw::MulticastStrategy> MulticastStrategyTester;
MulticastStrategyTester strategy(forwarder);
shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
forwarder.addFace(face1);
Fib& fib = forwarder.getFib();
shared_ptr<fib::Entry> fibEntry = fib.insert(Name()).first;
fibEntry->addNextHop(face1, 0);
shared_ptr<Interest> interest = makeInterest("ndn:/H0D6i5fc");
Pit& pit = forwarder.getPit();
shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
pitEntry->insertOrUpdateInRecord(face1, *interest);
strategy.afterReceiveInterest(*face1, *interest, fibEntry, pitEntry);
BOOST_CHECK_EQUAL(strategy.m_rejectPendingInterestHistory.size(), 1);
BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.size(), 0);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace fw
} // namespace nfd
@@ -64,6 +64,7 @@ public:
virtual void
createFace(const FaceUri& uri,
ndn::nfd::FacePersistency persistency,
const FaceCreatedCallback& onCreated,
const FaceConnectFailedCallback& onConnectFailed)
{
@@ -83,12 +83,7 @@ public:
BOOST_CHECK_EQUAL(status.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
}
if (reference->isOnDemand()) {
BOOST_CHECK_EQUAL(status.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
}
else {
BOOST_CHECK_EQUAL(status.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
}
BOOST_CHECK_EQUAL(status.getFacePersistency(), reference->getPersistency());
if (reference->isMultiAccess()) {
BOOST_CHECK_EQUAL(status.getLinkType(), ndn::nfd::LINK_TYPE_MULTI_ACCESS);
@@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(PersistencyFilter)
"/localhost/nfd/FaceStatusPublisherFixture",
filter, m_keyChain);
BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(m_dummyFace), false);
multicastFace->setOnDemand(true);
multicastFace->setPersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
BOOST_CHECK_EQUAL(faceQueryStatusPublisher.doesMatchFilter(multicastFace), true);
}
@@ -82,7 +82,7 @@ readNonNegativeIntegerType(const Block& block,
}
std::stringstream error;
error << "expected type " << type << " got " << block.type();
throw tlv::Error(error.str());
BOOST_THROW_EXCEPTION(tlv::Error(error.str()));
}
static inline uint64_t
@@ -96,7 +96,7 @@ checkedReadNonNegativeIntegerType(Block::element_const_iterator& i,
++i;
return readNonNegativeIntegerType(block, type);
}
throw tlv::Error("Unexpected end of FaceStatus");
BOOST_THROW_EXCEPTION(tlv::Error("Unexpected end of FaceStatus"));
}
class FaceStatusPublisherFixture : public BaseFixture
@@ -142,12 +142,7 @@ public:
BOOST_CHECK_EQUAL(status.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
}
if (reference->isOnDemand()) {
BOOST_CHECK_EQUAL(status.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
}
else {
BOOST_CHECK_EQUAL(status.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
}
BOOST_CHECK_EQUAL(status.getFacePersistency(), reference->getPersistency());
if (reference->isMultiAccess()) {
BOOST_CHECK_EQUAL(status.getLinkType(), ndn::nfd::LINK_TYPE_MULTI_ACCESS);
@@ -51,7 +51,7 @@ readNonNegativeIntegerType(const Block& block,
}
std::stringstream error;
error << "Expected type " << type << " got " << block.type();
throw tlv::Error(error.str());
BOOST_THROW_EXCEPTION(tlv::Error(error.str()));
}
static inline uint64_t
@@ -68,7 +68,7 @@ checkedReadNonNegativeIntegerType(Block::element_const_iterator& i,
std::stringstream error;
error << "Unexpected end of Block while attempting to read type #"
<< type;
throw tlv::Error(error.str());
BOOST_THROW_EXCEPTION(tlv::Error(error.str()));
}
class FibEnumerationPublisherFixture : public BaseFixture
+19 -14
View File
@@ -39,14 +39,31 @@ class GeneralConfigSectionFixture : public BaseFixture
public:
~GeneralConfigSectionFixture()
{
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
// revert changes to s_normalUid/s_normalGid, if any
PrivilegeHelper::s_normalUid = ::geteuid();
PrivilegeHelper::s_normalGid = ::getegid();
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
}
};
BOOST_FIXTURE_TEST_SUITE(MgmtGeneralConfigSection, GeneralConfigSectionFixture)
BOOST_AUTO_TEST_CASE(DefaultConfig)
{
const std::string CONFIG =
"general\n"
"{\n"
"}\n";
ConfigFile configFile;
general::setConfigFile(configFile);
BOOST_CHECK_NO_THROW(configFile.parse(CONFIG, true, "test-general-config-section"));
}
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
BOOST_AUTO_TEST_CASE(UserAndGroupConfig)
{
const std::string CONFIG =
@@ -58,20 +75,6 @@ BOOST_AUTO_TEST_CASE(UserAndGroupConfig)
ConfigFile configFile;
general::setConfigFile(configFile);
BOOST_CHECK_NO_THROW(configFile.parse(CONFIG, true, "test-general-config-section"));
}
BOOST_AUTO_TEST_CASE(DefaultConfig)
{
const std::string CONFIG =
"general\n"
"{\n"
"}\n";
ConfigFile configFile;
general::setConfigFile(configFile);
BOOST_CHECK_NO_THROW(configFile.parse(CONFIG, true, "test-general-config-section"));
}
@@ -104,6 +107,8 @@ BOOST_AUTO_TEST_CASE(NoGroupConfig)
BOOST_CHECK_NO_THROW(configFile.parse(CONFIG, true, "test-general-config-section"));
}
#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
static bool
checkExceptionMessage(const ConfigFile::Error& error, const std::string& expected)
{
+92
View File
@@ -0,0 +1,92 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "table/cs.hpp"
#include "table/cs-policy-lru.hpp"
#include <ndn-cxx/util/crypto.hpp>
#include "tests/test-common.hpp"
namespace nfd {
namespace cs {
namespace tests {
using namespace nfd::tests;
using ndn::nfd::LocalControlHeader;
BOOST_AUTO_TEST_SUITE(CsLru)
BOOST_FIXTURE_TEST_CASE(EvictOneLRU, UnitTestTimeFixture)
{
Cs cs(3);
cs.setPolicy(unique_ptr<Policy>(new LruPolicy()));
cs.insert(*makeData("ndn:/A"));
cs.insert(*makeData("ndn:/B"));
cs.insert(*makeData("ndn:/C"));
BOOST_CHECK_EQUAL(cs.size(), 3);
// evict A
cs.insert(*makeData("ndn:/D"));
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// use C then B
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
// evict D then C
cs.insert(*makeData("ndn:/E"));
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/D"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
cs.insert(*makeData("ndn:/F"));
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// refresh B
cs.insert(*makeData("ndn:/B"));
// evict E
cs.insert(*makeData("ndn:/G"));
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/E"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace cs
} // namespace nfd
@@ -0,0 +1,148 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "table/cs.hpp"
#include "table/cs-policy-priority-fifo.hpp"
#include <ndn-cxx/util/crypto.hpp>
#include "tests/test-common.hpp"
namespace nfd {
namespace cs {
namespace tests {
using namespace nfd::tests;
using ndn::nfd::LocalControlHeader;
BOOST_AUTO_TEST_SUITE(CsPriorityFifo)
BOOST_FIXTURE_TEST_CASE(EvictOne, UnitTestTimeFixture)
{
Cs cs(3);
cs.setPolicy(unique_ptr<Policy>(new PriorityFifoPolicy()));
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(99999));
dataC->wireEncode();
cs.insert(*dataC, true);
this->advanceClocks(time::milliseconds(11));
// evict unsolicited
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict stale
shared_ptr<Data> dataE = makeData("ndn:/E");
dataE->setFreshnessPeriod(time::milliseconds(99999));
dataE->wireEncode();
cs.insert(*dataE);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict fifo
shared_ptr<Data> dataF = makeData("ndn:/F");
dataF->setFreshnessPeriod(time::milliseconds(99999));
dataF->wireEncode();
cs.insert(*dataF);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_FIXTURE_TEST_CASE(Refresh, UnitTestTimeFixture)
{
Cs cs(3);
cs.setPolicy(unique_ptr<Policy>(new PriorityFifoPolicy()));
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(10));
dataC->wireEncode();
cs.insert(*dataC);
this->advanceClocks(time::milliseconds(11));
// refresh dataB
shared_ptr<Data> dataB2 = make_shared<Data>(*dataB);
dataB2->wireEncode();
cs.insert(*dataB2);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
// evict dataC stale
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace cs
} // namespace nfd
-101
View File
@@ -330,107 +330,6 @@ BOOST_AUTO_TEST_CASE(CachingPolicyNoCache)
bind([] { BOOST_CHECK(true); }));
}
BOOST_FIXTURE_TEST_CASE(Evict, UnitTestTimeFixture)
{
Cs cs(3);
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(99999));
dataC->wireEncode();
cs.insert(*dataC, true);
this->advanceClocks(time::milliseconds(11));
// evict unsolicited
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict stale
shared_ptr<Data> dataE = makeData("ndn:/E");
dataE->setFreshnessPeriod(time::milliseconds(99999));
dataE->wireEncode();
cs.insert(*dataE);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict fifo
shared_ptr<Data> dataF = makeData("ndn:/F");
dataF->setFreshnessPeriod(time::milliseconds(99999));
dataF->wireEncode();
cs.insert(*dataF);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_FIXTURE_TEST_CASE(Refresh, UnitTestTimeFixture)
{
Cs cs(3);
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(10));
dataC->wireEncode();
cs.insert(*dataC);
this->advanceClocks(time::milliseconds(11));
// refresh dataB
shared_ptr<Data> dataB2 = make_shared<Data>(*dataB);
dataB2->wireEncode();
cs.insert(*dataB2);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
// evict dataC stale
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_AUTO_TEST_CASE(Enumeration)
{
Cs cs;
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff. Show more