Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fc649bfc6 | ||
|
|
67ba8d28df | ||
|
|
375dcb0bd6 | ||
|
|
0e092aee5c | ||
|
|
faa5c0cd3c | ||
|
|
149e02cf7d | ||
|
|
a714792b03 | ||
|
|
66c569ddcc | ||
|
|
3f41ade02d | ||
|
|
0315269228 | ||
|
|
62b19a6c09 | ||
|
|
7c90e6dfea | ||
|
|
4e274ac915 | ||
|
|
ee7c8441c8 | ||
|
|
c1dfdb44da | ||
|
|
a4527cc837 | ||
|
|
8082993f7f | ||
|
|
b81cff966e | ||
|
|
731f0d70fa | ||
|
|
08f07016a3 | ||
|
|
2666473042 | ||
|
|
5b6deaea18 | ||
|
|
971d3c2b09 | ||
|
|
dbe4f9fefe | ||
|
|
692842d6ad | ||
|
|
cb6e05f2dd | ||
|
|
5620fb2ac9 | ||
|
|
965d3a4e72 | ||
|
|
187ade8566 |
No files matched your search
@@ -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
|
||||
Executable
+29
@@ -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
|
||||
Executable
+42
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,9 @@
|
||||
has() {
|
||||
local p=$1
|
||||
shift
|
||||
local x
|
||||
for x in "$@"; do
|
||||
[[ "${x}" == "${p}" ]] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
+4
-4
@@ -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
|
||||
@@ -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>
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> >
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> >
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -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
|
||||
-----
|
||||
|
||||
|
||||
@@ -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
|
||||
-----
|
||||
|
||||
|
||||
@@ -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``.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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));
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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
Reference in new issue
Block a user