Compare commits

...
9 Commits
Author SHA1 Message Date
Alexander Afanasyev 2666473042 docs+build: Prepare release of version 0.3.3
Change-Id: Ia53f820fb60e8a9ed5da0ac1667b8d10ef79c414
Refs: #2812
2015-07-01 11:23:12 -07:00
Joao Pereira 5b6deaea18 docs: Fix indentation in nfdc manpage
refs #2995

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

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

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

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

Change-Id: I06b91804fc8b8613560ef98687307f56262689fb
2015-05-15 14:43:31 -07:00
27 changed files with 1135 additions and 374 deletions

No files matched your search

+4
View File
@@ -73,3 +73,7 @@ in the library:
* Tai-Lin Chu <https://www.linkedin.com/pub/tai-lin-chu/55/5b2/669>
* Spyridon Mastorakis <http://cs.ucla.edu/~mastorakis/>
* Eric Newberry <http://ericnewberry.com>
* Yukai Tu <tuyukai1994@gmail.com>
* João Pereira <http://website.jpereira.co.uk>
* Mathias Gibbens <gibmat@cs.arizona.edu>
+130
View File
@@ -0,0 +1,130 @@
Starting NFD on Linux with systemd
==================================
Newer versions of Ubuntu (starting with 15.04) and some other Linux distributions, including Debian
use systemd to start system daemons, monitor their health, and restart them when they die.
Initial setup
-------------
* Edit `nfd.service`, correcting the paths to the `nfd` executable, configuration, and
``HOME`` directories.
* Copy the systemd config file for NFD to the proper directory
sudo cp nfd.service /etc/systemd/system
* Reload the systemd manager configuration
sudo systemctl daemon-reload
### Assumptions in the default scripts
* `nfd` is installed into `/usr/local/bin`
* Configuraton file is `/usr/local/etc/ndn/nfd.conf`
* `nfd` will be run as root
* Log files will be written to `/usr/local/var/log/ndn` folder, which is owned by user `ndn`
### Creating users
If the `ndn` user and group do not exist, they need to be manually created.
# Create group `ndn`
sudo addgroup --system ndn
# Create user `ndn`
sudo adduser --system \
--disabled-login \
--ingroup ndn \
--home /nonexistent \
--gecos "NDN User" \
--shell /bin/false \
ndn
### Creating folders
Folder `/usr/local/var/log/ndn` should be created and assigned proper user and group:
sudo mkdir -p /usr/local/var/log/ndn
sudo chown -R ndn:ndn /usr/local/var/log/ndn
`HOME` directory for `nfd` should be created prior to starting. This is necessary to manage
unique security credentials for the daemon.
# Create HOME and generate self-signed NDN certificate for nfd
sudo sh -c ' \
mkdir -p /usr/local/var/lib/ndn/nfd/.ndn; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-keygen /localhost/daemons/nfd | ndnsec-install-cert -; \
'
### Configuring NFD's security
NFD sample configuration allows anybody to create faces, add nexthops to FIB, and set
strategy choice for namespaces. While such settings could be a good start, it is
generally not a good idea to run NFD in this mode.
While thorough discussion about the security configuration of NFD is outside the scope of
this document, at least the following change should be done in ``nfd.conf`` in the
authorize section:
authorizations
{
authorize
{
certfile certs/localhost_daemons_nfd.ndncert
privileges
{
faces
fib
strategy-choice
}
}
authorize
{
certfile any
privileges
{
faces
strategy-choice
}
}
}
While this configuration still allows the management of faces and updating strategy choice by
anyone, only NFD's RIB Manager (i.e., NFD itself) is allowed to manage FIB.
As the final step to make this configuration work, nfd's self-signed certificate needs to
be exported into the `localhost_daemons_nfd.ndncert` file:
sudo sh -c '\
mkdir -p /usr/local/etc/ndn/certs || true; \
export HOME=/usr/local/var/lib/ndn/nfd; \
ndnsec-dump-certificate -i /localhost/daemons/nfd > \
/usr/local/etc/ndn/certs/localhost_daemons_nfd.ndncert; \
'
Enable auto-start
-----------------
After copying the provided upstart script, auto-start of the `nfd` daemon can be enabled with:
sudo systemctl enable nfd
To manually start it, use the following command:
sudo systemctl start nfd
Disable auto-start
------------------
To stop the `nfd` daemon, use the following command:
sudo systemctl stop nfd
To permanently stop the `nfd` daemon and disable it from being automatically started on reboot,
disable the service:
sudo systemctl disable nfd
+42
View File
@@ -0,0 +1,42 @@
# Copyright (c) 2015, Regents of the University of California,
# Arizona Board of Regents,
# Colorado State University,
# University Pierre & Marie Curie, Sorbonne University,
# Washington University in St. Louis,
# Beijing Institute of Technology,
# The University of Memphis.
#
# This file is part of NFD (Named Data Networking Forwarding Daemon).
# See AUTHORS.md for complete list of NFD authors and contributors.
#
# NFD is free software: you can redistribute it and/or modify it under the terms
# of the GNU General Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version.
#
# NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
#
# Author: Eric Newberry <enewberry@email.arizona.edu>
[Unit]
Description=NDN Forwarding Daemon
Documentation=man:nfd man:nfdc man:nfd-status
Wants=network-online.target
After=network-online.target
[Service]
Environment=HOME=/usr/local/var/lib/ndn/nfd
ExecStart=/usr/local/bin/nfd --config /usr/local/etc/ndn/nfd.conf
ExecStartPost=/bin/sh -ec 'sleep 2; if [ -f /usr/local/etc/ndn/nfd-init.sh ]; then . /usr/local/etc/ndn/nfd-init.sh; fi'
Restart=on-failure
ProtectSystem=full
PrivateTmp=yes
PrivateDevices=yes
ProtectHome=yes
[Install]
WantedBy=multi-user.target
+4 -4
View File
@@ -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
-1
View File
@@ -35,7 +35,6 @@ EntryImpl::EntryImpl(const Name& name)
}
EntryImpl::EntryImpl(shared_ptr<const Data> data, bool isUnsolicited)
: queueType(QUEUE_NONE)
{
this->setData(data, isUnsolicited);
BOOST_ASSERT(!this->isQuery());
-7
View File
@@ -26,9 +26,7 @@
#ifndef NFD_DAEMON_TABLE_CS_ENTRY_IMPL_HPP
#define NFD_DAEMON_TABLE_CS_ENTRY_IMPL_HPP
#include "cs-internal.hpp"
#include "cs-entry.hpp"
#include "core/scheduler.hpp"
namespace nfd {
namespace cs {
@@ -69,11 +67,6 @@ private:
bool
isQuery() const;
public:
QueueType queueType;
QueueIt queueIt;
scheduler::EventId moveStaleEvent;
private:
Name m_queryName;
};
+1 -12
View File
@@ -38,18 +38,7 @@ namespace cs {
class EntryImpl;
typedef std::set<EntryImpl> Table;
typedef Table::const_iterator TableIt;
typedef std::list<TableIt> Queue;
typedef Queue::iterator QueueIt;
enum QueueType {
QUEUE_UNSOLICITED,
QUEUE_STALE,
QUEUE_FIFO,
QUEUE_MAX,
QUEUE_NONE = QUEUE_MAX
};
typedef Table::const_iterator iterator;
} // namespace cs
} // namespace nfd
+157
View File
@@ -0,0 +1,157 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cs-policy-priority-fifo.hpp"
#include "cs.hpp"
#include <ndn-cxx/util/signal.hpp>
namespace nfd {
namespace cs {
namespace priority_fifo {
const std::string PriorityFifoPolicy::POLICY_NAME = "fifo";
PriorityFifoPolicy::PriorityFifoPolicy()
: Policy(POLICY_NAME)
{
}
void
PriorityFifoPolicy::doAfterInsert(iterator i)
{
this->attachQueue(i);
this->evictEntries();
}
void
PriorityFifoPolicy::doAfterRefresh(iterator i)
{
this->detachQueue(i);
this->attachQueue(i);
}
void
PriorityFifoPolicy::doBeforeErase(iterator i)
{
this->detachQueue(i);
}
void
PriorityFifoPolicy::doBeforeUse(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
}
void
PriorityFifoPolicy::evictEntries()
{
BOOST_ASSERT(this->getCs() != nullptr);
while (this->getCs()->size() > this->getLimit()) {
this->evictOne();
}
}
void
PriorityFifoPolicy::evictOne()
{
BOOST_ASSERT(!m_queues[QUEUE_UNSOLICITED].empty() ||
!m_queues[QUEUE_STALE].empty() ||
!m_queues[QUEUE_FIFO].empty());
iterator i;
if (!m_queues[QUEUE_UNSOLICITED].empty()) {
i = m_queues[QUEUE_UNSOLICITED].front();
}
else if (!m_queues[QUEUE_STALE].empty()) {
i = m_queues[QUEUE_STALE].front();
}
else if (!m_queues[QUEUE_FIFO].empty()) {
i = m_queues[QUEUE_FIFO].front();
}
this->detachQueue(i);
this->emitSignal(beforeEvict, i);
}
void
PriorityFifoPolicy::attachQueue(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) == m_entryInfoMap.end());
EntryInfo* entryInfo = new EntryInfo();
if (i->isUnsolicited()) {
entryInfo->queueType = QUEUE_UNSOLICITED;
}
else if (i->isStale()) {
entryInfo->queueType = QUEUE_STALE;
}
else {
entryInfo->queueType = QUEUE_FIFO;
if (i->canStale()) {
entryInfo->moveStaleEventId = scheduler::schedule(i->getData().getFreshnessPeriod(),
bind(&PriorityFifoPolicy::moveToStaleQueue, this, i));
}
}
Queue& queue = m_queues[entryInfo->queueType];
entryInfo->queueIt = queue.insert(queue.end(), i);
m_entryInfoMap[i] = entryInfo;
}
void
PriorityFifoPolicy::detachQueue(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
EntryInfo* entryInfo = m_entryInfoMap[i];
if (entryInfo->queueType == QUEUE_FIFO) {
scheduler::cancel(entryInfo->moveStaleEventId);
}
m_queues[entryInfo->queueType].erase(entryInfo->queueIt);
m_entryInfoMap.erase(i);
}
void
PriorityFifoPolicy::moveToStaleQueue(iterator i)
{
BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
EntryInfo* entryInfo = m_entryInfoMap[i];
BOOST_ASSERT(entryInfo->queueType == QUEUE_FIFO);
m_queues[QUEUE_FIFO].erase(entryInfo->queueIt);
entryInfo->queueType = QUEUE_STALE;
Queue& queue = m_queues[QUEUE_STALE];
entryInfo->queueIt = queue.insert(queue.end(), i);
m_entryInfoMap[i] = entryInfo;
}
} // namespace priorityfifo
} // namespace cs
} // namespace nfd
+133
View File
@@ -0,0 +1,133 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
#define NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
#include "cs-policy.hpp"
#include "common.hpp"
#include "core/scheduler.hpp"
namespace nfd {
namespace cs {
namespace priority_fifo {
typedef std::list<iterator> Queue;
typedef Queue::iterator QueueIt;
enum QueueType {
QUEUE_UNSOLICITED,
QUEUE_STALE,
QUEUE_FIFO,
QUEUE_MAX
};
struct EntryInfo
{
QueueType queueType;
QueueIt queueIt;
scheduler::EventId moveStaleEventId;
};
struct EntryItComparator
{
bool
operator()(const iterator& a, const iterator& b) const
{
return *a < *b;
}
};
typedef std::map<iterator, EntryInfo*, EntryItComparator> EntryInfoMapFifo;
/** \brief Priority Fifo cs replacement policy
*
* The entries that get removed first are unsolicited Data packets,
* which are the Data packets that got cached opportunistically without preceding
* forwarding of the corresponding Interest packet.
* Next, the Data packets with expired freshness are removed.
* Last, the Data packets are removed from the Content Store on a pure FIFO basis.
*/
class PriorityFifoPolicy : public Policy
{
public:
PriorityFifoPolicy();
public:
static const std::string POLICY_NAME;
private:
virtual void
doAfterInsert(iterator i) DECL_OVERRIDE;
virtual void
doAfterRefresh(iterator i) DECL_OVERRIDE;
virtual void
doBeforeErase(iterator i) DECL_OVERRIDE;
virtual void
doBeforeUse(iterator i) DECL_OVERRIDE;
virtual void
evictEntries() DECL_OVERRIDE;
private:
/** \brief evicts one entry
* \pre CS is not empty
*/
void
evictOne();
/** \brief attaches the entry to an appropriate queue
* \pre the entry is not in any queue
*/
void
attachQueue(iterator i);
/** \brief detaches the entry from its current queue
* \post the entry is not in any queue
*/
void
detachQueue(iterator i);
/** \brief moves an entry from FIFO queue to STALE queue
*/
void
moveToStaleQueue(iterator i);
private:
Queue m_queues[QUEUE_MAX];
EntryInfoMapFifo m_entryInfoMap;
};
} // namespace priorityfifo
using priority_fifo::PriorityFifoPolicy;
} // namespace cs
} // namespace nfd
#endif // NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
+79
View File
@@ -0,0 +1,79 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cs-policy.hpp"
#include "cs.hpp"
namespace nfd {
namespace cs {
Policy::Policy(const std::string& policyName)
: m_policyName(policyName)
{
}
Policy::~Policy()
{
}
void
Policy::setLimit(size_t nMaxEntries)
{
BOOST_ASSERT(nMaxEntries > 0);
m_limit = nMaxEntries;
this->evictEntries();
}
void
Policy::afterInsert(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doAfterInsert(i);
}
void
Policy::afterRefresh(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doAfterRefresh(i);
}
void
Policy::beforeErase(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doBeforeErase(i);
}
void
Policy::beforeUse(iterator i)
{
BOOST_ASSERT(m_cs != nullptr);
this->doBeforeUse(i);
}
} // namespace cs
} // namespace nfd
+191
View File
@@ -0,0 +1,191 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_TABLE_CS_POLICY_HPP
#define NFD_DAEMON_TABLE_CS_POLICY_HPP
#include "cs-internal.hpp"
#include "cs-entry-impl.hpp"
namespace nfd {
namespace cs {
class Cs;
/** \brief represents a CS replacement policy
*/
class Policy : noncopyable
{
public:
explicit
Policy(const std::string& policyName);
virtual
~Policy();
const std::string&
getName() const;
public:
/** \brief gets cs
*/
Cs*
getCs() const;
/** \brief sets cs
*/
void
setCs(Cs *cs);
/** \brief gets hard limit (in number of entries)
*/
size_t
getLimit() const;
/** \brief sets hard limit (in number of entries)
* \post getLimit() == nMaxEntries
* \post cs.size() <= getLimit()
*
* The policy may evict entries if necessary.
*/
void
setLimit(size_t nMaxEntries);
/** \brief emits when an entry is being evicted
*
* A policy implementation should emit this signal to cause CS to erase the entry from its index.
* CS should connect to this signal and erase the entry upon signal emission.
*/
signal::Signal<Policy, iterator> beforeEvict;
/** \brief invoked by CS after a new entry is inserted
* \post cs.size() <= getLimit()
*
* The policy may evict entries if necessary.
* During this process, \p i might be evicted.
*/
void
afterInsert(iterator i);
/** \brief invoked by CS after an existing entry is refreshed by same Data
*
* The policy may witness this refresh to make better eviction decisions in the future.
*/
void
afterRefresh(iterator i);
/** \brief invoked by CS before an entry is erased due to management command
* \warning CS must not invoke this method if an entry is erased due to eviction.
*/
void
beforeErase(iterator i);
/** \brief invoked by CS before an entry is used to match a lookup
*
* The policy may witness this usage to make better eviction decisions in the future.
*/
void
beforeUse(iterator i);
protected:
/** \brief invoked after a new entry is created in CS
*
* When overridden in a subclass, a policy implementation should decide whether to accept \p i.
* If \p i is accepted, it should be inserted into a cleanup index.
* Otherwise, \p beforeEvict signal should be emitted with \p i to inform CS to erase the entry.
* A policy implementation may decide to evict other entries by emitting \p beforeEvict signal,
* in order to keep CS size under limit.
*/
virtual void
doAfterInsert(iterator i) = 0;
/** \brief invoked after an existing entry is refreshed by same Data
*
* When overridden in a subclass, a policy implementation may witness this operation
* and adjust its cleanup index.
*/
virtual void
doAfterRefresh(iterator i) = 0;
/** \brief invoked before an entry is erased due to management command
* \note This will not be invoked for an entry being evicted by policy.
*
* When overridden in a subclass, a policy implementation should erase \p i
* from its cleanup index without emitted \p afterErase signal.
*/
virtual void
doBeforeErase(iterator i) = 0;
/** \brief invoked before an entry is used to match a lookup
*
* When overridden in a subclass, a policy implementation may witness this operation
* and adjust its cleanup index.
*/
virtual void
doBeforeUse(iterator i) = 0;
/** \brief evicts zero or more entries
* \post CS size does not exceed hard limit
*/
virtual void
evictEntries() = 0;
protected:
DECLARE_SIGNAL_EMIT(beforeEvict)
private:
std::string m_policyName;
size_t m_limit;
Cs* m_cs;
};
inline const std::string&
Policy::getName() const
{
return m_policyName;
}
inline Cs*
Policy::getCs() const
{
return m_cs;
}
inline void
Policy::setCs(Cs *cs)
{
m_cs = cs;
}
inline size_t
Policy::getLimit() const
{
return m_limit;
}
} // namespace cs
} // namespace nfd
#endif // NFD_DAEMON_TABLE_CS_POLICY_HPP
+58 -113
View File
@@ -24,9 +24,9 @@
*/
#include "cs.hpp"
#include "cs-policy-priority-fifo.hpp"
#include "core/logger.hpp"
#include "core/algorithm.hpp"
#include <numeric>
NFD_LOG_INIT("ContentStore");
@@ -44,18 +44,38 @@ static_assert(std::is_default_constructible<Cs::const_iterator>::value,
BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Cs::const_iterator>));
#endif // HAVE_IS_DEFAULT_CONSTRUCTIBLE
Cs::Cs(size_t nMaxPackets)
: m_limit(nMaxPackets)
unique_ptr<Policy>
makeDefaultPolicy()
{
BOOST_ASSERT(nMaxPackets > 0);
return unique_ptr<Policy>(new PriorityFifoPolicy());
}
Cs::Cs(size_t nMaxPackets, unique_ptr<Policy> policy)
{
this->setPolicyImpl(policy);
m_policy->setLimit(nMaxPackets);
}
void
Cs::setLimit(size_t nMaxPackets)
{
BOOST_ASSERT(nMaxPackets > 0);
m_limit = nMaxPackets;
this->evict();
m_policy->setLimit(nMaxPackets);
}
size_t
Cs::getLimit() const
{
return m_policy->getLimit();
}
void
Cs::setPolicy(unique_ptr<Policy> policy)
{
BOOST_ASSERT(policy != nullptr);
BOOST_ASSERT(m_policy != nullptr);
size_t limit = m_policy->getLimit();
this->setPolicyImpl(policy);
m_policy->setLimit(limit);
}
bool
@@ -73,26 +93,25 @@ Cs::insert(const Data& data, bool isUnsolicited)
}
}
bool isNewEntry = false; TableIt it;
bool isNewEntry = false;
iterator it;
// use .insert because gcc46 does not support .emplace
std::tie(it, isNewEntry) = m_table.insert(EntryImpl(data.shared_from_this(), isUnsolicited));
EntryImpl& entry = const_cast<EntryImpl&>(*it);
entry.updateStaleTime();
if (!isNewEntry) { // existing entry
this->detachQueue(it);
// XXX This doesn't forbid unsolicited Data from refreshing a solicited entry.
if (entry.isUnsolicited() && !isUnsolicited) {
entry.unsetUnsolicited();
}
m_policy->afterRefresh(it);
}
else {
m_policy->afterInsert(it);
}
entry.updateStaleTime();
this->attachQueue(it);
// check there are same amount of entries in the table and in queues
BOOST_ASSERT(m_table.size() == std::accumulate(m_queues, m_queues + QUEUE_MAX, 0U,
[] (size_t sum, const Queue queue) { return sum + queue.size(); }));
this->evict(); // XXX The new entry could be evicted, but it shouldn't matter.
return true;
}
@@ -109,13 +128,13 @@ Cs::find(const Interest& interest,
bool isRightmost = interest.getChildSelector() == 1;
NFD_LOG_DEBUG("find " << prefix << (isRightmost ? " R" : " L"));
TableIt first = m_table.lower_bound(prefix);
TableIt last = m_table.end();
iterator first = m_table.lower_bound(prefix);
iterator last = m_table.end();
if (prefix.size() > 0) {
last = m_table.lower_bound(prefix.getSuccessor());
}
TableIt match = last;
iterator match = last;
if (isRightmost) {
match = this->findRightmost(interest, first, last);
}
@@ -129,39 +148,40 @@ Cs::find(const Interest& interest,
return;
}
NFD_LOG_DEBUG(" matching " << match->getName());
m_policy->beforeUse(match);
hitCallback(interest, match->getData());
}
TableIt
Cs::findLeftmost(const Interest& interest, TableIt first, TableIt last) const
iterator
Cs::findLeftmost(const Interest& interest, iterator first, iterator last) const
{
return std::find_if(first, last, bind(&cs::EntryImpl::canSatisfy, _1, interest));
}
TableIt
Cs::findRightmost(const Interest& interest, TableIt first, TableIt last) const
iterator
Cs::findRightmost(const Interest& interest, iterator first, iterator last) const
{
// Each loop visits a sub-namespace under a prefix one component longer than Interest Name.
// If there is a match in that sub-namespace, the leftmost match is returned;
// otherwise, loop continues.
size_t interestNameLength = interest.getName().size();
for (TableIt right = last; right != first;) {
TableIt prev = std::prev(right);
for (iterator right = last; right != first;) {
iterator prev = std::prev(right);
// special case: [first,prev] have exact Names
if (prev->getName().size() == interestNameLength) {
NFD_LOG_TRACE(" find-among-exact " << prev->getName());
TableIt matchExact = this->findRightmostAmongExact(interest, first, right);
iterator matchExact = this->findRightmostAmongExact(interest, first, right);
return matchExact == right ? last : matchExact;
}
Name prefix = prev->getName().getPrefix(interestNameLength + 1);
TableIt left = m_table.lower_bound(prefix);
iterator left = m_table.lower_bound(prefix);
// normal case: [left,right) are under one-component-longer prefix
NFD_LOG_TRACE(" find-under-prefix " << prefix);
TableIt match = this->findLeftmost(interest, left, right);
iterator match = this->findLeftmost(interest, left, right);
if (match != right) {
return match;
}
@@ -170,97 +190,22 @@ Cs::findRightmost(const Interest& interest, TableIt first, TableIt last) const
return last;
}
TableIt
Cs::findRightmostAmongExact(const Interest& interest, TableIt first, TableIt last) const
iterator
Cs::findRightmostAmongExact(const Interest& interest, iterator first, iterator last) const
{
return find_last_if(first, last, bind(&EntryImpl::canSatisfy, _1, interest));
}
void
Cs::attachQueue(TableIt it)
Cs::setPolicyImpl(unique_ptr<Policy>& policy)
{
EntryImpl& entry = const_cast<EntryImpl&>(*it);
m_policy = std::move(policy);
m_beforeEvictConnection = m_policy->beforeEvict.connect([this] (iterator it) {
m_table.erase(it);
});
if (entry.queueType != QUEUE_NONE) {
this->detachQueue(it);
}
if (entry.isUnsolicited()) {
entry.queueType = QUEUE_UNSOLICITED;
}
else if (entry.isStale()) {
entry.queueType = QUEUE_STALE;
}
else {
entry.queueType = QUEUE_FIFO;
if (entry.canStale()) {
entry.moveStaleEvent = scheduler::schedule(entry.getData().getFreshnessPeriod(),
bind(&Cs::moveToStaleQueue, this, it));
}
}
Queue& queue = m_queues[entry.queueType];
entry.queueIt = queue.insert(queue.end(), it);
}
void
Cs::detachQueue(TableIt it)
{
EntryImpl& entry = const_cast<EntryImpl&>(*it);
BOOST_ASSERT(entry.queueType != QUEUE_NONE);
if (entry.queueType == QUEUE_FIFO) {
scheduler::cancel(entry.moveStaleEvent);
}
m_queues[entry.queueType].erase(entry.queueIt);
entry.queueType = QUEUE_NONE;
}
void
Cs::moveToStaleQueue(TableIt it)
{
EntryImpl& entry = const_cast<EntryImpl&>(*it);
BOOST_ASSERT(entry.queueType == QUEUE_FIFO);
m_queues[QUEUE_FIFO].erase(entry.queueIt);
entry.queueType = QUEUE_STALE;
Queue& queue = m_queues[QUEUE_STALE];
entry.queueIt = queue.insert(queue.end(), it);
}
std::tuple<TableIt, std::string>
Cs::evictPick()
{
if (!m_queues[QUEUE_UNSOLICITED].empty()) {
return std::make_tuple(m_queues[QUEUE_UNSOLICITED].front(), "unsolicited");
}
if (!m_queues[QUEUE_STALE].empty()) {
return std::make_tuple(m_queues[QUEUE_STALE].front(), "stale");
}
if (!m_queues[QUEUE_FIFO].empty()) {
return std::make_tuple(m_queues[QUEUE_FIFO].front(), "fifo");
}
BOOST_ASSERT(false);
return std::make_tuple(m_table.end(), "error");
}
void
Cs::evict()
{
while (this->size() > m_limit) {
TableIt it; std::string reason;
std::tie(it, reason) = this->evictPick();
NFD_LOG_DEBUG("evict " << it->getName() << " " << reason);
this->detachQueue(it);
m_table.erase(it);
}
m_policy->setCs(this);
BOOST_ASSERT(m_policy->getCs() == this);
}
void
+30 -39
View File
@@ -48,19 +48,25 @@
#ifndef NFD_DAEMON_TABLE_CS_HPP
#define NFD_DAEMON_TABLE_CS_HPP
#include "cs-policy.hpp"
#include "cs-internal.hpp"
#include "cs-entry-impl.hpp"
#include <ndn-cxx/util/signal.hpp>
#include <boost/iterator/transform_iterator.hpp>
namespace nfd {
namespace cs {
unique_ptr<Policy>
makeDefaultPolicy();
/** \brief represents the ContentStore
*/
class Cs : noncopyable
{
public:
explicit
Cs(size_t nMaxPackets = 10);
Cs(size_t nMaxPackets = 10, unique_ptr<Policy> policy = makeDefaultPolicy());
/** \brief inserts a Data packet
* \return true
@@ -97,9 +103,20 @@ public:
/** \return capacity (in number of packets)
*/
size_t
getLimit() const
getLimit() const;
/** \brief changes cs replacement policy
* \pre size() == 0
*/
void
setPolicy(unique_ptr<Policy> policy);
/** \return cs replacement policy
*/
Policy*
getPolicy() const
{
return m_limit;
return m_policy.get();
}
/** \return number of stored packets
@@ -128,7 +145,7 @@ public: // enumeration
/** \brief ContentStore iterator (public API)
*/
typedef boost::transform_iterator<EntryFromEntryImpl, TableIt, const Entry&> const_iterator;
typedef boost::transform_iterator<EntryFromEntryImpl, iterator, const Entry&> const_iterator;
const_iterator
begin() const
@@ -146,54 +163,28 @@ private: // find
/** \brief find leftmost match in [first,last)
* \return the leftmost match, or last if not found
*/
TableIt
findLeftmost(const Interest& interest, TableIt left, TableIt right) const;
iterator
findLeftmost(const Interest& interest, iterator left, iterator right) const;
/** \brief find rightmost match in [first,last)
* \return the rightmost match, or last if not found
*/
TableIt
findRightmost(const Interest& interest, TableIt first, TableIt last) const;
iterator
findRightmost(const Interest& interest, iterator first, iterator last) const;
/** \brief find rightmost match among entries with exact Names in [first,last)
* \return the rightmost match, or last if not found
*/
TableIt
findRightmostAmongExact(const Interest& interest, TableIt first, TableIt last) const;
iterator
findRightmostAmongExact(const Interest& interest, iterator first, iterator last) const;
private: // cleanup
/** \brief attaches an entry to a suitable cleanup queue
* \note if the entry is already attached to a queue, it's automatically detached
*/
void
attachQueue(TableIt it);
/** \brief detaches an entry from its current cleanup queue
* \warning if the entry is unattached, this will cause undefined behavior
*/
void
detachQueue(TableIt it);
/** \brief moves an entry from FIFO queue to STALE queue
*/
void
moveToStaleQueue(TableIt it);
/** \brief picks an entry for eviction
*/
std::tuple<TableIt, std::string/*reason*/>
evictPick();
/** \brief evicts zero or more entries so that number of stored entries
* is not greater than capacity
*/
void
evict();
setPolicyImpl(unique_ptr<Policy>& policy);
private:
size_t m_limit;
Table m_table;
Queue m_queues[QUEUE_MAX];
unique_ptr<Policy> m_policy;
ndn::util::signal::ScopedConnection m_beforeEvictConnection;
};
} // namespace cs
+45
View File
@@ -3,6 +3,51 @@
NFD Release Notes
=================
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)
+++++++++++++++++++++++++++++++++++++++++++++++
+6
View File
@@ -1,6 +1,12 @@
ndn-tlv-peek
============
Deprecated
----------
ndn-tlv-peek is deprecated and will be removed in a future release of NFD.
Please use ``ndnpeek`` program from ndn-tools repository `<https://github.com/named-data/ndn-tools>`__.
Usage
-----
+6
View File
@@ -1,6 +1,12 @@
ndn-tlv-poke
============
Deprecated
----------
ndn-tlv-poke is deprecated and will be removed in a future release of NFD.
Please use ``ndnpoke`` program from ndn-tools repository `<https://github.com/named-data/ndn-tools>`__.
Usage
-----
+3 -3
View File
@@ -42,7 +42,7 @@ Options
Expiration time of the RIB entry in milliseconds. If not specified, the entry remains in FIB
for the lifetime of the associated face.
``-o <origin>``
``-o <origin>``
Origin of the registration request (default is 255).
0 for Local producer applications, 128 for NLSR, 255 for static routes.
@@ -62,10 +62,10 @@ Options
``unregister [-o origin] <prefix> <faceId>``
``-o <origin>``
``-o <origin>``
Origin of the unregistration request (default is 255).
``prefix``
``prefix``
A prefix of an existing RIB entry, from which routing entry is requested to be
removed.
+4 -3
View File
@@ -26,6 +26,7 @@
#include "remote-registrator.hpp"
#include "core/logger.hpp"
#include "core/scheduler.hpp"
#include <ndn-cxx/security/signing-helpers.hpp>
namespace nfd {
namespace rib {
@@ -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);
}
}
+1 -1
View File
@@ -73,7 +73,7 @@ protected:
size_t totalLength = 0;
for (int64_t i = 0; i < N; i++)
{
totalLength += ndn::prependNonNegativeIntegerBlock(outBuffer, tlv::Content, i);
totalLength += prependNonNegativeIntegerBlock(outBuffer, tlv::Content, i);
}
m_totalPayloadLength += totalLength;
return totalLength;
+1 -4
View File
@@ -53,10 +53,7 @@ public:
wireEncode() const
{
ndn::EncodingBuffer buffer;
ndn::prependByteArrayBlock(buffer,
0x8888,
reinterpret_cast<const uint8_t*>(m_message.c_str()),
m_message.size());
prependStringBlock(buffer, 0x8888, m_message);
return buffer.block();
}
+17
View File
@@ -350,6 +350,23 @@ BOOST_FIXTURE_TEST_CASE(PacketLoss, TwoLaptopsFixture)
BOOST_CHECK_EQUAL(hasData2c, true);
}
BOOST_FIXTURE_TEST_CASE(Bug2831, TwoLaptopsFixture)
{
// make a two-node loop
topo.registerPrefix(laptopA, linkA->getFace(laptopA), "ndn:/net");
topo.registerPrefix(router, linkA->getFace(router), "ndn:/net");
// send Interests from laptopA to router
shared_ptr<TopologyAppLink> consumer = topo.addAppFace(laptopA);
topo.addIntervalConsumer(*consumer->getClientFace(), "ndn:/net",
time::milliseconds(100), 10);
this->advanceClocks(time::milliseconds(5), time::seconds(2));
// Interest shouldn't loop back from router
BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 0);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
@@ -0,0 +1,148 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "table/cs.hpp"
#include "table/cs-policy-priority-fifo.hpp"
#include <ndn-cxx/util/crypto.hpp>
#include "tests/test-common.hpp"
namespace nfd {
namespace cs {
namespace tests {
using namespace nfd::tests;
using ndn::nfd::LocalControlHeader;
BOOST_AUTO_TEST_SUITE(CsPriorityFifo)
BOOST_FIXTURE_TEST_CASE(EvictOne, UnitTestTimeFixture)
{
Cs cs(3);
cs.setPolicy(unique_ptr<Policy>(new PriorityFifoPolicy()));
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(99999));
dataC->wireEncode();
cs.insert(*dataC, true);
this->advanceClocks(time::milliseconds(11));
// evict unsolicited
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict stale
shared_ptr<Data> dataE = makeData("ndn:/E");
dataE->setFreshnessPeriod(time::milliseconds(99999));
dataE->wireEncode();
cs.insert(*dataE);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict fifo
shared_ptr<Data> dataF = makeData("ndn:/F");
dataF->setFreshnessPeriod(time::milliseconds(99999));
dataF->wireEncode();
cs.insert(*dataF);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_FIXTURE_TEST_CASE(Refresh, UnitTestTimeFixture)
{
Cs cs(3);
cs.setPolicy(unique_ptr<Policy>(new PriorityFifoPolicy()));
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(10));
dataC->wireEncode();
cs.insert(*dataC);
this->advanceClocks(time::milliseconds(11));
// refresh dataB
shared_ptr<Data> dataB2 = make_shared<Data>(*dataB);
dataB2->wireEncode();
cs.insert(*dataB2);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
// evict dataC stale
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace cs
} // namespace nfd
-101
View File
@@ -330,107 +330,6 @@ BOOST_AUTO_TEST_CASE(CachingPolicyNoCache)
bind([] { BOOST_CHECK(true); }));
}
BOOST_FIXTURE_TEST_CASE(Evict, UnitTestTimeFixture)
{
Cs cs(3);
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(99999));
dataC->wireEncode();
cs.insert(*dataC, true);
this->advanceClocks(time::milliseconds(11));
// evict unsolicited
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict stale
shared_ptr<Data> dataE = makeData("ndn:/E");
dataE->setFreshnessPeriod(time::milliseconds(99999));
dataE->wireEncode();
cs.insert(*dataE);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
// evict fifo
shared_ptr<Data> dataF = makeData("ndn:/F");
dataF->setFreshnessPeriod(time::milliseconds(99999));
dataF->wireEncode();
cs.insert(*dataF);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_FIXTURE_TEST_CASE(Refresh, UnitTestTimeFixture)
{
Cs cs(3);
shared_ptr<Data> dataA = makeData("ndn:/A");
dataA->setFreshnessPeriod(time::milliseconds(99999));
dataA->wireEncode();
cs.insert(*dataA);
shared_ptr<Data> dataB = makeData("ndn:/B");
dataB->setFreshnessPeriod(time::milliseconds(10));
dataB->wireEncode();
cs.insert(*dataB);
shared_ptr<Data> dataC = makeData("ndn:/C");
dataC->setFreshnessPeriod(time::milliseconds(10));
dataC->wireEncode();
cs.insert(*dataC);
this->advanceClocks(time::milliseconds(11));
// refresh dataB
shared_ptr<Data> dataB2 = make_shared<Data>(*dataB);
dataB2->wireEncode();
cs.insert(*dataB2);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/A"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/B"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(true); }),
bind([] { BOOST_CHECK(false); }));
// evict dataC stale
shared_ptr<Data> dataD = makeData("ndn:/D");
dataD->setFreshnessPeriod(time::milliseconds(99999));
dataD->wireEncode();
cs.insert(*dataD);
BOOST_CHECK_EQUAL(cs.size(), 3);
cs.find(Interest("ndn:/C"),
bind([] { BOOST_CHECK(false); }),
bind([] { BOOST_CHECK(true); }));
}
BOOST_AUTO_TEST_CASE(Enumeration)
{
Cs cs;
+10 -9
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -21,8 +21,6 @@
*
* 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 Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
*/
#include "version.hpp"
@@ -226,6 +224,9 @@ private:
int
main(int argc, char* argv[])
{
std::cerr << "ndn-tlv-peek is deprecated. Use ndnpeek program from ndn-tools repository.\n"
"See `man ndn-tlv-peek` for details." << std::endl;
ndntlvpeek::NdnTlvPeek ndnTlvPeek(argv[0]);
int option;
while ((option = getopt(argc, argv, "hfrm:M:l:pw:V")) != -1) {
+10 -9
View File
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis
* Copyright (c) 2014-2015, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -21,8 +21,6 @@
*
* 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 Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
*/
#include "version.hpp"
@@ -227,6 +225,9 @@ private:
int
main(int argc, char* argv[])
{
std::cerr << "ndn-tlv-poke is deprecated. Use ndnpoke program from ndn-tools repository.\n"
"See `man ndn-tlv-poke` for details." << std::endl;
int option;
ndntlvpoke::NdnTlvPoke ndnTlvPoke(argv[0]);
while ((option = getopt(argc, argv, "hfDi:Fx:w:V")) != -1) {
+54 -67
View File
@@ -38,12 +38,15 @@
#include <ndn-cxx/management/nfd-fib-entry.hpp>
#include <ndn-cxx/management/nfd-rib-entry.hpp>
#include <ndn-cxx/management/nfd-strategy-choice.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <list>
namespace ndn {
using util::SegmentFetcher;
class NfdStatus
{
public:
@@ -132,26 +135,13 @@ public:
runNextStep();
}
void
fetchSegments(const Data& data, void (NfdStatus::*onDone)())
onErrorFetch(uint32_t errorCode, const std::string& errorMsg)
{
m_buffer->write((const char*)data.getContent().value(),
data.getContent().value_size());
std::cerr << "Error code:" << errorCode << ", message:" << errorMsg << std::endl;
uint64_t currentSegment = data.getName().get(-1).toSegment();
const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
if (finalBlockId.empty() ||
finalBlockId.toSegment() > currentSegment)
{
m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
bind(&NfdStatus::fetchSegments, this, _2, onDone),
bind(&NfdStatus::onTimeout, this));
}
else
{
return (this->*onDone)();
}
runNextStep();
}
void
@@ -277,24 +267,23 @@ public:
interest.setChildSelector(1);
interest.setMustBeFresh(true);
m_face.expressInterest(interest,
bind(&NfdStatus::fetchSegments, this, _2,
&NfdStatus::afterFetchedChannelStatusInformation),
bind(&NfdStatus::onTimeout, this));
SegmentFetcher::fetch(m_face, interest,
util::DontVerifySegment(),
bind(&NfdStatus::afterFetchedChannelStatusInformation, this, _1),
bind(&NfdStatus::onErrorFetch, this, _1, _2));
}
void
afterFetchedChannelStatusInformation()
afterFetchedChannelStatusInformation(const ConstBufferPtr& dataset)
{
ConstBufferPtr buf = m_buffer->buf();
if (m_isOutputXml) {
std::cout << "<channels>";
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
break;
@@ -317,10 +306,10 @@ public:
std::cout << "Channels:" << std::endl;
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
break;
@@ -348,24 +337,23 @@ public:
interest.setChildSelector(1);
interest.setMustBeFresh(true);
m_face.expressInterest(interest,
bind(&NfdStatus::fetchSegments, this, _2,
&NfdStatus::afterFetchedFaceStatusInformation),
bind(&NfdStatus::onTimeout, this));
SegmentFetcher::fetch(m_face, interest,
util::DontVerifySegment(),
bind(&NfdStatus::afterFetchedFaceStatusInformation, this, _1),
bind(&NfdStatus::onErrorFetch, this, _1, _2));
}
void
afterFetchedFaceStatusInformation()
afterFetchedFaceStatusInformation(const ConstBufferPtr& dataset)
{
ConstBufferPtr buf = m_buffer->buf();
if (m_isOutputXml) {
std::cout << "<faces>";
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
break;
@@ -430,10 +418,10 @@ public:
std::cout << "Faces:" << std::endl;
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
break;
@@ -480,24 +468,24 @@ public:
Interest interest("/localhost/nfd/fib/list");
interest.setChildSelector(1);
interest.setMustBeFresh(true);
m_face.expressInterest(interest,
bind(&NfdStatus::fetchSegments, this, _2,
&NfdStatus::afterFetchedFibEnumerationInformation),
bind(&NfdStatus::onTimeout, this));
SegmentFetcher::fetch(m_face, interest,
util::DontVerifySegment(),
bind(&NfdStatus::afterFetchedFibEnumerationInformation, this, _1),
bind(&NfdStatus::onErrorFetch, this, _1, _2));
}
void
afterFetchedFibEnumerationInformation()
afterFetchedFibEnumerationInformation(const ConstBufferPtr& dataset)
{
ConstBufferPtr buf = m_buffer->buf();
if (m_isOutputXml) {
std::cout << "<fib>";
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode FibEntry TLV";
break;
@@ -527,10 +515,10 @@ public:
std::cout << "FIB:" << std::endl;
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
break;
@@ -568,24 +556,24 @@ public:
Interest interest("/localhost/nfd/strategy-choice/list");
interest.setChildSelector(1);
interest.setMustBeFresh(true);
m_face.expressInterest(interest,
bind(&NfdStatus::fetchSegments, this, _2,
&NfdStatus::afterFetchedStrategyChoiceInformationInformation),
bind(&NfdStatus::onTimeout, this));
SegmentFetcher::fetch(m_face, interest,
util::DontVerifySegment(),
bind(&NfdStatus::afterFetchedStrategyChoiceInformationInformation, this, _1),
bind(&NfdStatus::onErrorFetch, this, _1, _2));
}
void
afterFetchedStrategyChoiceInformationInformation()
afterFetchedStrategyChoiceInformationInformation(const ConstBufferPtr& dataset)
{
ConstBufferPtr buf = m_buffer->buf();
if (m_isOutputXml) {
std::cout << "<strategyChoices>";
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode StrategyChoice TLV";
break;
@@ -615,10 +603,10 @@ public:
std::cout << "Strategy choices:" << std::endl;
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode StrategyChoice TLV" << std::endl;
break;
@@ -644,24 +632,23 @@ public:
interest.setChildSelector(1);
interest.setMustBeFresh(true);
m_face.expressInterest(interest,
bind(&NfdStatus::fetchSegments, this, _2,
&NfdStatus::afterFetchedRibStatusInformation),
bind(&NfdStatus::onTimeout, this));
SegmentFetcher::fetch(m_face, interest,
util::DontVerifySegment(),
bind(&NfdStatus::afterFetchedRibStatusInformation, this, _1),
bind(&NfdStatus::onErrorFetch, this, _1, _2));
}
void
afterFetchedRibStatusInformation()
afterFetchedRibStatusInformation(const ConstBufferPtr& dataset)
{
ConstBufferPtr buf = m_buffer->buf();
if (m_isOutputXml) {
std::cout << "<rib>";
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode RibEntry TLV";
break;
@@ -706,10 +693,10 @@ public:
std::cout << "RIB:" << std::endl;
size_t offset = 0;
while (offset < buf->size()) {
while (offset < dataset->size()) {
bool isOk = false;
Block block;
std::tie(isOk, block) = Block::fromBuffer(buf, offset);
std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
if (!isOk) {
std::cerr << "ERROR: cannot decode RibEntry TLV" << std::endl;
break;
+1 -1
View File
@@ -24,7 +24,7 @@ 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/>.
"""
VERSION = "0.3.2"
VERSION = "0.3.3"
APPNAME = "nfd"
BUGREPORT = "http://redmine.named-data.net/projects/nfd"
URL = "http://named-data.net/doc/NFD/"