Browse Source

Convert to v2::security and adapt to ndn-cxx changes

Change-Id: I54f1b758cfb8f3f6cbc66a1aec5120ae1640b0ec
refs: #3964
pull/14/head
Muktadir Chowdhury 8 years ago
parent
commit
f04f98943d
  1. 34
      .jenkins.d/01-ndn-cxx.sh
  2. 28
      .jenkins.d/02-chronosync.sh
  3. 6
      docs/redmine_issue.py
  4. 23
      nlsr.conf
  5. 4
      src/adjacency-list.cpp
  6. 4
      src/adjacency-list.hpp
  7. 2
      src/adjacent.cpp
  8. 14
      src/adjacent.hpp
  9. 10
      src/conf-file-processor.cpp
  10. 16
      src/hello-protocol.cpp
  11. 7
      src/hello-protocol.hpp
  12. 2
      src/lsa.cpp
  13. 7
      src/lsdb.cpp
  14. 288
      src/nlsr.cpp
  15. 96
      src/nlsr.hpp
  16. 12
      src/publisher/segment-publisher.hpp
  17. 12
      src/route/fib.cpp
  18. 8
      src/route/fib.hpp
  19. 19
      src/security/certificate-store.hpp
  20. 4
      src/tlv/coordinate-lsa.cpp
  21. 2
      src/update/manager-base.cpp
  22. 6
      src/update/manager-base.hpp
  23. 24
      src/update/prefix-update-processor.cpp
  24. 17
      src/update/prefix-update-processor.hpp
  25. 89
      src/validator.cpp
  26. 103
      src/validator.hpp
  27. 34
      tests-integrated/boost-test.hpp
  28. 24
      tests-integrated/main.cpp
  29. 273
      tests-integrated/test-validator.cpp
  30. 41
      tests-integrated/wscript
  31. 214
      tests/boost-multi-log-formatter.hpp
  32. 102
      tests/identity-fixture.cpp
  33. 143
      tests/identity-management-fixture.cpp
  34. 106
      tests/identity-management-fixture.hpp
  35. 104
      tests/main.cpp
  36. 17
      tests/publisher/publisher-fixture.hpp
  37. 25
      tests/publisher/test-segment-publisher.cpp
  38. 22
      tests/security/test-certificate-store.cpp
  39. 2
      tests/test-adjacency-list.cpp
  40. 4
      tests/test-adjacent.cpp
  41. 8
      tests/test-common.cpp
  42. 20
      tests/test-common.hpp
  43. 101
      tests/test-conf-file-processor.cpp
  44. 12
      tests/test-fib.cpp
  45. 132
      tests/test-home-fixture.hpp
  46. 12
      tests/test-hyperbolic-calculator.cpp
  47. 12
      tests/test-link-state-calculator.cpp
  48. 153
      tests/test-lsa-rule.cpp
  49. 6
      tests/test-lsa.cpp
  50. 43
      tests/test-lsdb.cpp
  51. 10
      tests/test-name-prefix-table.cpp
  52. 197
      tests/test-nlsr.cpp
  53. 4
      tests/test-routing-table.cpp
  54. 56
      tests/test-statistics.cpp
  55. 31
      tests/test-sync-logic-handler.cpp
  56. 14
      tests/update/test-advertise-crash.cpp
  57. 21
      tests/update/test-nfd-rib-command-processor.cpp
  58. 212
      tests/update/test-prefix-update-processor.cpp
  59. 44
      tests/wscript
  60. 16
      tools/nlsrc.cpp
  61. 2
      tools/nlsrc.hpp
  62. 1
      wscript

34
.jenkins.d/01-ndn-cxx.sh

@ -18,37 +18,29 @@ if has OSX $NODE_LABELS; then
fi
fi
## Uncomment when #3920 and #4119 merge.
# if [[ -z $INSTALLED_VERSION ]]; then
# INSTALLED_VERSION=$(git -C ndn-cxx rev-parse HEAD 2>/dev/null || echo NONE)
# fi
if [[ -z $INSTALLED_VERSION ]]; then
INSTALLED_VERSION=$(git -C ndn-cxx rev-parse HEAD 2>/dev/null || echo NONE)
fi
sudo rm -Rf ndn-cxx-latest
## Remove this when #3920 and #4119 merge
sudo rm -Rf ndn-cxx-hotfix
git clone git://github.com/named-data/ndn-cxx ndn-cxx-hotfix
## Uncomment when #3920 and #4119 merge.
# LATEST_VERSION=$(git -C ndn-cxx-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
LATEST_VERSION=$(git -C ndn-cxx-latest 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
# cp ndn-cxx ndn-cxx-hotfix
# else
# sudo rm -Rf ndn-cxx-latest
# fi
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 -f /usr/local/bin/ndnsec*
sudo rm -fr /usr/local/include/ndn-cxx
sudo rm -f /usr/local/lib/libndn-cxx*
sudo rm -f /usr/local/lib/pkgconfig/libndn-cxx.pc
## Change to the hotfix directory instead of the normal ndn-cxx directory
## Restore below line when #3920 and #4119 merge.
#pushd ndn-cxx >/dev/null
pushd ndn-cxx-hotfix >/dev/null
git checkout b555b00c280b9c9ed46f24a1fbebc73b720601af
pushd ndn-cxx >/dev/null
./waf configure --color=yes --enable-shared --disable-static --without-osx-keychain
./waf build --color=yes -j${WAF_JOBS:-1}

28
.jenkins.d/02-chronosync.sh

@ -18,30 +18,28 @@ if has OSX $NODE_LABELS; then
fi
fi
# if [[ -z $INSTALLED_VERSION ]]; then
# INSTALLED_VERSION=$(git -C ChronoSync rev-parse HEAD 2>/dev/null || echo NONE)
# fi
if [[ -z $INSTALLED_VERSION ]]; then
INSTALLED_VERSION=$(git -C ChronoSync rev-parse HEAD 2>/dev/null || echo NONE)
fi
sudo rm -Rf ChronoSync-latest
## Remove line when #3920 and #4119 merge.
sudo rm -rf ChronoSync-hotfix
git clone git://github.com/named-data/ChronoSync ChronoSync-hotfix
# LATEST_VERSION=$(git -C ChronoSync-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
git clone --depth 1 git://github.com/named-data/ChronoSync ChronoSync-latest
LATEST_VERSION=$(git -C ChronoSync-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
# if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
# sudo rm -Rf ChronoSync
# mv ChronoSync-latest ChronoSync
# else
# sudo rm -Rf ChronoSync-latest
# fi
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
sudo rm -Rf ChronoSync
mv ChronoSync-latest ChronoSync
else
sudo rm -Rf ChronoSync-latest
fi
sudo rm -fr /usr/local/include/ChronoSync
sudo rm -f /usr/local/lib/libChronoSync*
sudo rm -f /usr/local/lib/pkgconfig/ChronoSync*
pushd ChronoSync-hotfix >/dev/null
git checkout 097bb448f46b8bd9a5c1f431e824f8f6a169b650
pushd ChronoSync >/dev/null
if has FreeBSD10 $NODE_LABELS; then
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/

6
docs/redmine_issue.py

@ -50,8 +50,8 @@ def make_link_node(rawtext, app, type, slug, options):
base = app.config.redmine_project_url
if not base:
raise AttributeError
except AttributeError, err:
raise ValueError('redmine_project_url configuration value is not set (%s)' % str(err))
except AttributeError:
raise ValueError('redmine_project_url configuration value is not set')
#
slash = '/' if base[-1] != '/' else ''
ref = base + slash + type + '/' + slug + '/'
@ -67,4 +67,4 @@ def setup(app):
"""
app.add_role('issue', redmine_role)
app.add_config_value('redmine_project_url', None, 'env')
return
return

23
nlsr.conf

@ -68,7 +68,7 @@ neighbors
face-dataset-fetch-tries 3 ; default is 3. Valid values 1-10. The FaceDataset is
; gotten from NFD, and is needed to configure NLSR
; correctly. It is recommended not to set this
: variable too high, because it could cause
; variable too high, because it could cause
; congestion for NFD.
face-dataset-fetch-interval 3600 ; default is 3600. Valid values 1800-5400.
@ -166,7 +166,7 @@ security
type name
hyper-relation
{
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
k-expand \\1
h-relation equal
p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$
@ -194,7 +194,7 @@ security
type name
hyper-relation
{
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$
k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><>$
k-expand \\1
h-relation equal
; the last four components in the prefix should be <lsaType><seqNo><version><segmentNo>
@ -212,7 +212,7 @@ security
filter
{
type name
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><ksk-.*><ID-CERT><>$
regex ^[^<KEY><%C1.Router>]*<%C1.Router>[^<KEY><NLSR>]*<KEY><><><>$
}
checker
{
@ -223,10 +223,10 @@ security
type name
hyper-relation
{
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
k-expand \\1
h-relation equal
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><><><>$
p-expand \\1
}
}
@ -240,7 +240,7 @@ security
filter
{
type name
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
regex ^[^<KEY>]*<KEY><><><>$
}
checker
{
@ -265,7 +265,9 @@ security
filter
{
type name
regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$
; /<prefix>/<management-module>/<command-verb>/<control-parameters>
; /<timestamp>/<random-value>/<signed-interests-components>
regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<><><>$
}
checker
{
@ -274,7 +276,7 @@ security
key-locator
{
type name
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$
regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
}
}
}
@ -286,7 +288,7 @@ security
filter
{
type name
regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
regex ^[^<KEY>]*<KEY><><><>$
}
checker
{
@ -301,6 +303,7 @@ security
file-name "site.cert"
}
}
; cert-to-publish "root.cert" ; optional, a file containing the root certificate
; Only the router that is designated to publish the root cert
; needs to specify this

4
src/adjacency-list.cpp

@ -266,7 +266,7 @@ AdjacencyList::findAdjacent(uint64_t faceId)
}
AdjacencyList::iterator
AdjacencyList::findAdjacent(const ndn::util::FaceUri& faceUri)
AdjacencyList::findAdjacent(const ndn::FaceUri& faceUri)
{
return std::find_if(m_adjList.begin(),
m_adjList.end(),
@ -275,7 +275,7 @@ AdjacencyList::findAdjacent(const ndn::util::FaceUri& faceUri)
}
uint64_t
AdjacencyList::getFaceId(const ndn::util::FaceUri& faceUri)
AdjacencyList::getFaceId(const ndn::FaceUri& faceUri)
{
std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
m_adjList.end(),

4
src/adjacency-list.hpp

@ -149,7 +149,7 @@ public:
findAdjacent(uint64_t faceId);
AdjacencyList::iterator
findAdjacent(const ndn::util::FaceUri& faceUri);
findAdjacent(const ndn::FaceUri& faceUri);
/*! \brief Hack to stop developers from using this function
@ -165,7 +165,7 @@ public:
}
uint64_t
getFaceId(const ndn::util::FaceUri& faceUri);
getFaceId(const ndn::FaceUri& faceUri);
void
writeLog();

2
src/adjacent.cpp

@ -52,7 +52,7 @@ Adjacent::Adjacent(const ndn::Name& an)
{
}
Adjacent::Adjacent(const ndn::Name& an, const ndn::util::FaceUri& faceUri, double lc,
Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Status s, uint32_t iton, uint64_t faceId)
: m_name(an)
, m_faceUri(faceUri)

14
src/adjacent.hpp

@ -23,7 +23,7 @@
#include <boost/cstdint.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/face-uri.hpp>
#include <ndn-cxx/net/face-uri.hpp>
#ifndef NLSR_ADJACENT_HPP
#define NLSR_ADJACENT_HPP
@ -50,7 +50,7 @@ public:
Adjacent(const ndn::Name& an);
Adjacent(const ndn::Name& an, const ndn::util::FaceUri& faceUri, double lc,
Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Status s, uint32_t iton, uint64_t faceId);
const ndn::Name&
@ -65,14 +65,14 @@ public:
m_name = an;
}
const ndn::util::FaceUri&
const ndn::FaceUri&
getFaceUri() const
{
return m_faceUri;
}
void
setFaceUri(const ndn::util::FaceUri& faceUri)
setFaceUri(const ndn::FaceUri& faceUri)
{
m_faceUri = faceUri;
}
@ -152,7 +152,7 @@ public:
}
inline bool
compareFaceUri(const ndn::util::FaceUri& faceUri)
compareFaceUri(const ndn::FaceUri& faceUri)
{
return m_faceUri == faceUri;
}
@ -166,8 +166,8 @@ public:
private:
/*! m_name The NLSR-configured router name of the neighbor */
ndn::Name m_name;
/*! m_connectingFaceUri The NFD-level specification of the Face*/
ndn::util::FaceUri m_faceUri;
/*! m_faceUri The NFD-level specification of the Face*/
ndn::FaceUri m_faceUri;
/*! m_linkCost The semi-arbitrary cost to traverse the link. */
double m_linkCost;
/*! m_status Whether the neighbor is active or not */

10
src/conf-file-processor.cpp

@ -28,7 +28,7 @@
#include <boost/cstdint.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/util/face-uri.hpp>
#include <ndn-cxx/net/face-uri.hpp>
#include <iostream>
#include <fstream>
@ -496,7 +496,7 @@ ConfFileProcessor::processConfSectionNeighbors(const ConfigSection& section)
std::string name = CommandAttriTree.get<std::string>("name");
std::string uriString = CommandAttriTree.get<std::string>("face-uri");
ndn::util::FaceUri faceUri;
ndn::FaceUri faceUri;
if (! faceUri.parse(uriString)) {
std::cerr << "parsing failed!" << std::endl;
return false;
@ -665,15 +665,15 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
std::string file = it->second.data();
path certfilePath = absolute(file, path(m_confFileName).parent_path());
std::shared_ptr<ndn::IdentityCertificate> idCert =
ndn::io::load<ndn::IdentityCertificate>(certfilePath.string());
std::shared_ptr<ndn::security::v2::Certificate> idCert =
ndn::io::load<ndn::security::v2::Certificate>(certfilePath.string());
if (idCert == nullptr) {
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
return false;
}
m_nlsr.loadCertToPublish(idCert);
m_nlsr.loadCertToPublish(*idCert);
}
}

16
src/hello-protocol.cpp

@ -114,8 +114,11 @@ HelloProtocol::processInterest(const ndn::Name& name,
data->setFreshnessPeriod(ndn::time::seconds(10)); // 10 sec
data->setContent(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.c_str()),
INFO_COMPONENT.size());
m_nlsr.getKeyChain().sign(*data, m_nlsr.getDefaultCertName());
m_nlsr.getKeyChain().sign(*data, m_nlsr.getSigningInfo());
NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
m_nlsr.getNlsrFace().put(*data);
// increment SENT_HELLO_DATA
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
@ -195,11 +198,12 @@ HelloProtocol::onContent(const ndn::Interest& interest, const ndn::Data& data)
}
void
HelloProtocol::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
HelloProtocol::onContentValidated(const ndn::Data& data)
{
// data name: /<neighbor>/NLSR/INFO/<router>/<version>
ndn::Name dataName = data->getName();
ndn::Name dataName = data.getName();
NLSR_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
if (dataName.get(-3).toUri() == INFO_COMPONENT) {
ndn::Name neighbor = dataName.getPrefix(-4);
@ -225,10 +229,10 @@ HelloProtocol::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
}
void
HelloProtocol::onContentValidationFailed(const std::shared_ptr<const ndn::Data>& data,
const std::string& msg)
HelloProtocol::onContentValidationFailed(const ndn::Data& data,
const ndn::security::v2::ValidationError& ve)
{
NLSR_LOG_DEBUG("Validation Error: " << msg);
NLSR_LOG_DEBUG("Validation Error: " << ve);
}
} // namespace nlsr

7
src/hello-protocol.hpp

@ -30,6 +30,7 @@
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/security/v2/validation-error.hpp>
namespace nlsr {
@ -128,14 +129,14 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
* to contact this neighbor so that we will retry later.
*/
void
onContentValidated(const std::shared_ptr<const ndn::Data>& data);
onContentValidated(const ndn::Data& data);
private:
/*! \brief Log that incoming data couldn't be validated, but do nothing else.
*/
void
onContentValidationFailed(const std::shared_ptr<const ndn::Data>& data,
const std::string& msg);
onContentValidationFailed(const ndn::Data& data,
const ndn::security::v2::ValidationError& ve);
/*! \brief Treat a failed Face registration as an INACTIVE neighbor.
*

2
src/lsa.cpp

@ -248,7 +248,7 @@ AdjLsa::deserialize(const std::string& content) noexcept
ndn::Name adjName(*tok_iter++);
std::string connectingFaceUri(*tok_iter++);
double linkCost = boost::lexical_cast<double>(*tok_iter++);
Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
Adjacent adjacent(adjName, ndn::FaceUri(connectingFaceUri), linkCost,
Adjacent::STATUS_INACTIVE, 0, 0);
addAdjacent(adjacent);
}

7
src/lsdb.cpp

@ -38,9 +38,10 @@ class LsaContentPublisher : public SegmentPublisher<ndn::Face>
public:
LsaContentPublisher(ndn::Face& face,
ndn::KeyChain& keyChain,
const ndn::security::SigningInfo& signingInfo,
const ndn::time::milliseconds& freshnessPeriod,
const std::string& content)
: SegmentPublisher(face, keyChain, freshnessPeriod)
: SegmentPublisher(face, keyChain, signingInfo, freshnessPeriod)
, m_content(content)
{
}
@ -1073,12 +1074,12 @@ Lsdb::putLsaData(const ndn::Interest& interest, const std::string& content)
{
LsaContentPublisher publisher(m_nlsr.getNlsrFace(),
m_nlsr.getKeyChain(),
m_nlsr.getSigningInfo(),
m_lsaRefreshTime,
content);
NLSR_LOG_DEBUG("Sending requested data ( " << content << ") for interest (" << interest
<< ") to be published and added to face.");
publisher.publish(interest.getName(),
ndn::security::signingByCertificate(m_nlsr.getDefaultCertName()));
publisher.publish(interest.getName());
}
// \brief Finds and sends a requested name LSA.

288
src/nlsr.cpp

@ -29,7 +29,8 @@
#include <cstdio>
#include <unistd.h>
#include <ndn-cxx/util/face-uri.hpp>
#include <ndn-cxx/net/face-uri.hpp>
#include <ndn-cxx/signature.hpp>
namespace nlsr {
@ -61,20 +62,14 @@ Nlsr::Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::F
m_routerNameDispatcher,
m_nlsrFace,
m_keyChain)
, m_helloProtocol(*this, scheduler)
, m_certificateCache(new ndn::CertificateCacheTtl(ioService))
, m_validator(m_nlsrFace, DEFAULT_BROADCAST_PREFIX, m_certificateCache, m_certStore)
, m_controller(m_nlsrFace, m_keyChain, m_validator)
, m_validator(ndn::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(m_nlsrFace))
, m_controller(m_nlsrFace, m_keyChain)
, m_faceDatasetController(m_nlsrFace, m_keyChain)
, m_prefixUpdateProcessor(m_localhostDispatcher,
m_nlsrFace,
m_namePrefixList,
m_nlsrLsdb,
DEFAULT_BROADCAST_PREFIX,
m_keyChain,
m_certificateCache,
m_certStore)
m_nlsrLsdb)
, m_nfdRibCommandProcessor(m_localhostDispatcher,
m_namePrefixList,
m_nlsrLsdb)
@ -97,36 +92,17 @@ void
Nlsr::onRegistrationSuccess(const ndn::Name& name)
{
NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
if (name.equals(m_confParam.getRouterPrefix())) {
// the top-level prefixes are added.
try {
m_routerNameDispatcher.addTopPrefix(m_confParam.getRouterPrefix(), false, m_signingInfo);
}
catch (const std::exception& e) {
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
}
}
}
void
Nlsr::onLocalhostRegistrationSuccess(const ndn::Name& name)
{
// All dispatcher-related sub-prefixes *must* be registered before
// the top-level prefixes are added.
try {
m_localhostDispatcher.addTopPrefix(LOCALHOST_PREFIX, false, m_signingInfo);
}
catch (const std::exception& e) {
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
}
}
void
Nlsr::setInfoInterestFilter()
{
ndn::Name name(m_confParam.getRouterPrefix());
NLSR_LOG_DEBUG("Setting interest filter for name: " << name);
name.append("NLSR");
name.append("INFO");
NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
getNlsrFace().setInterestFilter(name,
std::bind(&HelloProtocol::processInterest,
&m_helloProtocol, _1, _2),
@ -142,7 +118,9 @@ Nlsr::setLsaInterestFilter()
ndn::Name name = m_confParam.getLsaPrefix();
name.append(m_confParam.getSiteName());
name.append(m_confParam.getRouterName());
NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);
getNlsrFace().setInterestFilter(name,
std::bind(&Lsdb::processInterest,
&m_nlsrLsdb, _1, _2),
@ -152,16 +130,29 @@ Nlsr::setLsaInterestFilter()
ndn::nfd::ROUTE_FLAG_CAPTURE);
}
void
Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
{
try {
if (topPrefix.equals(m_confParam.getRouterPrefix())) {
m_routerNameDispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
}
else {
m_localhostDispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
}
}
catch (const std::exception& e) {
NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
}
}
void
Nlsr::setStrategies()
{
const std::string strategy("ndn:/localhost/nfd/strategy/multicast");
ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
broadcastKeyPrefix.append("KEYS");
m_fib.setStrategy(m_confParam.getLsaPrefix(), strategy, 0);
m_fib.setStrategy(broadcastKeyPrefix, strategy, 0);
m_fib.setStrategy(m_confParam.getChronosyncPrefix(), strategy, 0);
}
@ -207,8 +198,8 @@ Nlsr::canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
std::function<void(void)> finally)
{
if (currentNeighbor != m_adjacencyList.getAdjList().end()) {
ndn::util::FaceUri uri(currentNeighbor->getFaceUri());
uri.canonize([this, then, currentNeighbor] (ndn::util::FaceUri canonicalUri) {
ndn::FaceUri uri(currentNeighbor->getFaceUri());
uri.canonize([this, then, currentNeighbor] (ndn::FaceUri canonicalUri) {
NLSR_LOG_DEBUG("Canonized URI: " << currentNeighbor->getFaceUri()
<< " to: " << canonicalUri);
currentNeighbor->setFaceUri(canonicalUri);
@ -228,6 +219,18 @@ Nlsr::canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
}
}
void
Nlsr::loadCertToPublish(const ndn::security::v2::Certificate& certificate)
{
m_certStore.insert(certificate);
m_validator.loadAnchor("Authoritative-Certificate",
ndn::security::v2::Certificate(certificate));
m_prefixUpdateProcessor.getValidator().
loadAnchor("Authoritative-Certificate",
ndn::security::v2::Certificate(certificate));
}
void
Nlsr::initialize()
{
@ -248,15 +251,24 @@ Nlsr::initialize()
m_adjacencyList.writeLog();
NLSR_LOG_DEBUG(m_namePrefixList);
// Logging end
initializeKey();
setStrategies();
NLSR_LOG_DEBUG("Default NLSR identity: " << m_signingInfo.getSignerName());
setInfoInterestFilter();
setLsaInterestFilter();
// add top-level prefixes: router and localhost prefix
addDispatcherTopPrefix(m_confParam.getRouterPrefix());
addDispatcherTopPrefix(LOCALHOST_PREFIX);
initializeFaces(std::bind(&Nlsr::processFaceDataset, this, _1),
std::bind(&Nlsr::onFaceDatasetFetchTimeout, this, _1, _2, 0));
enableIncomingFaceIdIndication();
// Set event intervals
setFirstHelloInterval(m_confParam.getFirstHelloInterval());
m_nlsrLsdb.setAdjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval());
@ -288,44 +300,96 @@ Nlsr::initialize()
void
Nlsr::initializeKey()
{
ndn::Name defaultIdentity = m_confParam.getRouterPrefix();
defaultIdentity.append("NLSR");
NLSR_LOG_DEBUG("Initializing Key ...");
ndn::Name nlsrInstanceName = m_confParam.getRouterPrefix();
nlsrInstanceName.append("NLSR");
try {
m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
} catch (const std::exception& e) {
NLSR_LOG_WARN(e.what());
}
auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
ndn::security::v2::Certificate certificate;
ndn::Name certificateName = nlsrInstanceKey.getName();
certificateName.append("NA");
certificateName.appendVersion();
certificate.setName(certificateName);
// set metainfo
certificate.setContentType(ndn::tlv::ContentType_Key);
certificate.setFreshnessPeriod(ndn::time::days(7300));
// set content
certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
// set signature-info
ndn::SignatureInfo signatureInfo;
signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
ndn::time::system_clock::now()
+ ndn::time::days(20 * 365)));
try {
m_keyChain.deleteIdentity(defaultIdentity);
m_keyChain.sign(certificate,
ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.getRouterPrefix()))
.setSignatureInfo(signatureInfo));
}
catch (const std::exception& e) {
NLSR_LOG_WARN("ERROR: Router's " << e.what()
<< "NLSR is running without security."
<< " If security is enabled NLSR will not converge.");
std::cerr << "Router's " << e.what() << "NLSR is running without security "
<< "(Only for testing, should not be used in production.)"
<< " If security is enabled NLSR will not converge." << std::endl;
}
m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID, defaultIdentity);
ndn::Name keyName = m_keyChain.generateRsaKeyPairAsDefault(defaultIdentity, true);
std::shared_ptr<ndn::IdentityCertificate> certificate =
std::make_shared<ndn::IdentityCertificate>();
std::shared_ptr<ndn::PublicKey> pubKey = m_keyChain.getPublicKey(keyName);
ndn::Name certificateName = keyName.getPrefix(-1);
certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
certificate->setName(certificateName);
certificate->setNotBefore(ndn::time::system_clock::now() - ndn::time::days(1));
certificate->setNotAfter(ndn::time::system_clock::now() + ndn::time::days(7300)); // ~20 years
certificate->setPublicKeyInfo(*pubKey);
certificate->addSubjectDescription(ndn::CertificateSubjectDescription(ndn::oid::ATTRIBUTE_NAME,
keyName.toUri()));
certificate->encode();
m_keyChain.signByIdentity(*certificate, m_confParam.getRouterPrefix());
m_keyChain.addCertificateAsIdentityDefault(*certificate);
m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
nlsrInstanceName);
loadCertToPublish(certificate);
m_defaultCertName = certificate->getName();
m_defaultCertName = certificate.getName();
}
void
Nlsr::registerKeyPrefix()
{
ndn::Name keyPrefix = DEFAULT_BROADCAST_PREFIX;
keyPrefix.append("KEYS");
m_nlsrFace.setInterestFilter(keyPrefix,
// Start listening for the interest of this router's NLSR certificate
ndn::Name nlsrKeyPrefix = getConfParameter().getRouterPrefix();
nlsrKeyPrefix.append("NLSR");
nlsrKeyPrefix.append("KEY");
m_nlsrFace.setInterestFilter(nlsrKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
// Start listening for the interest of this router's certificate
ndn::Name routerKeyPrefix = getConfParameter().getRouterPrefix();
routerKeyPrefix.append("KEY");
m_nlsrFace.setInterestFilter(routerKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
// Start listening for the interest of this router's operator's certificate
ndn::Name operatorKeyPrefix = getConfParameter().getNetwork();
operatorKeyPrefix.append(getConfParameter().getSiteName());
operatorKeyPrefix.append(std::string("%C1.Operator"));
m_nlsrFace.setInterestFilter(operatorKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
@ -333,52 +397,48 @@ Nlsr::registerKeyPrefix()
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
// Start listening for the interest of this router's site's certificate
ndn::Name siteKeyPrefix = getConfParameter().getNetwork();
siteKeyPrefix.append(getConfParameter().getSiteName());
siteKeyPrefix.append("KEY");
m_nlsrFace.setInterestFilter(siteKeyPrefix,
std::bind(&Nlsr::onKeyInterest,
this, _1, _2),
std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1),
m_signingInfo,
ndn::nfd::ROUTE_FLAG_CAPTURE);
}
void
Nlsr::registerLocalhostPrefix()
{
m_nlsrFace.registerPrefix(LOCALHOST_PREFIX,
std::bind(&Nlsr::onLocalhostRegistrationSuccess, this, _1),
std::bind(&Nlsr::onRegistrationSuccess, this, _1),
std::bind(&Nlsr::registrationFailed, this, _1));
}
void
Nlsr::onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
{
const ndn::Name& interestName = interest.getName();
ndn::Name certName = interestName.getSubName(name.size());
if (certName[-2].toUri() == "ID-CERT")
{
certName = certName.getPrefix(-1);
}
else if (certName[-1].toUri() != "ID-CERT")
{
NLSR_LOG_DEBUG("certName for interest " << interest << " is malformed,"
<< " contains incorrect namespace syntax");
return;
}
NLSR_LOG_DEBUG("Got interest for certificate. Interest: " << interest.getName());
std::shared_ptr<const ndn::IdentityCertificate> cert = getCertificate(certName);
const ndn::Name& interestName = interest.getName();
const ndn::security::v2::Certificate* cert = getCertificate(interestName);
if (!static_cast<bool>(cert))
{
NLSR_LOG_DEBUG("cert is not found for " << interest);
if (cert == nullptr) {
NLSR_LOG_DEBUG("Certificate is not found for: " << interest);
return; // cert is not found
}
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
data->setName(interestName);
data->setContent(cert->wireEncode());
m_keyChain.signWithSha256(*data);
}
m_nlsrFace.put(*data);
m_nlsrFace.put(*cert);
}
void
Nlsr::onKeyPrefixRegSuccess(const ndn::Name& name)
{
NLSR_LOG_DEBUG("KEY prefix: " << name << " registration is successful.");
}
void
@ -432,7 +492,7 @@ Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNo
case ndn::nfd::FACE_EVENT_CREATED: {
// Find the neighbor in our adjacency list
auto adjacent = m_adjacencyList.findAdjacent(
ndn::util::FaceUri(faceEventNotification.getRemoteUri()));
ndn::FaceUri(faceEventNotification.getRemoteUri()));
// If we have a neighbor by that FaceUri and it has no FaceId, we
// have a match.
if (adjacent != m_adjacencyList.end()) {
@ -505,10 +565,11 @@ void
Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
const ndn::time::milliseconds& timeout)
{
ndn::util::FaceUri faceUri = adj.getFaceUri();
ndn::FaceUri faceUri = adj.getFaceUri();
double linkCost = adj.getLinkCost();
const ndn::Name& adjName = adj.getName();
m_fib.registerPrefix(adj.getName(), faceUri, linkCost,
m_fib.registerPrefix(adjName, faceUri, linkCost,
timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
m_fib.registerPrefix(m_confParam.getChronosyncPrefix(),
@ -518,12 +579,6 @@ Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
m_fib.registerPrefix(m_confParam.getLsaPrefix(),
faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
broadcastKeyPrefix.append("KEYS");
m_fib.registerPrefix(broadcastKeyPrefix,
faceUri, linkCost, timeout,
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
}
void
@ -553,8 +608,8 @@ Nlsr::onFaceDatasetFetchTimeout(uint32_t code,
void
Nlsr::scheduleDatasetFetch()
{
NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval()
<< " seconds");
NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval());
m_scheduler.scheduleEvent(m_confParam.getFaceDatasetFetchInterval(),
[this] {
this->initializeFaces(
@ -567,6 +622,35 @@ Nlsr::scheduleDatasetFetch()
});
}
void
Nlsr::enableIncomingFaceIdIndication()
{
NLSR_LOG_DEBUG("Enabling incoming face id indication for local face.");
m_controller.start<ndn::nfd::FaceUpdateCommand>(
ndn::nfd::ControlParameters()
.setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED, true),
bind(&Nlsr::onFaceIdIndicationSuccess, this, _1),
bind(&Nlsr::onFaceIdIndicationFailure, this, _1));
}
void
Nlsr::onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp)
{
NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
<< "for face id " << cp.getFaceId());
}
void
Nlsr::onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr)
{
std::ostringstream os;
os << "Failed to enable incoming face id indication feature: " <<
"(code: " << cr.getCode() << ", reason: " << cr.getText() << ")";
NLSR_LOG_DEBUG(os.str());
}
void
Nlsr::startEventLoop()
{

96
src/nlsr.hpp

@ -29,7 +29,6 @@
#include "lsdb.hpp"
#include "name-prefix-list.hpp"
#include "test-access-control.hpp"
#include "validator.hpp"
#include "publisher/lsdb-dataset-interest-handler.hpp"
#include "route/fib.hpp"
#include "route/name-prefix-table.hpp"
@ -46,7 +45,10 @@
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/certificate-cache-ttl.hpp>
#include <ndn-cxx/security/validator-config.hpp>
#include <ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/signing-info.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
@ -54,6 +56,9 @@
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/encoding/block.hpp>
#include <ndn-cxx/encoding/nfd-constants.hpp>
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
namespace nlsr {
@ -83,15 +88,20 @@ public:
void
onRegistrationSuccess(const ndn::Name& name);
void
onLocalhostRegistrationSuccess(const ndn::Name& name);
void
setInfoInterestFilter();
void
setLsaInterestFilter();
/*! \brief Add top level prefixes for Dispatcher
*
* All dispatcher-related sub-prefixes *must* be registered before sub-prefixes
* must be added before adding top
*/
void
addDispatcherTopPrefix(const ndn::Name& topPrefix);
void
startEventLoop();
@ -275,6 +285,13 @@ public:
registerAdjacencyPrefixes(const Adjacent& adj,
const ndn::time::milliseconds& timeout);
/*! \brief Add a certificate NLSR claims to be authoritative for to the certificate store.
*
* \sa CertificateStore
*/
void
loadCertToPublish(const ndn::security::v2::Certificate& certificate);
void
initializeKey();
@ -285,22 +302,12 @@ public:
m_validator.load(section, filename);
}
Validator&
ndn::security::ValidatorConfig&
getValidator()
{
return m_validator;
}
/*! \brief Add a certificate NLSR claims to be authoritative for to the certificate store.
*
* \sa CertificateStore
*/
void
loadCertToPublish(std::shared_ptr<ndn::IdentityCertificate> certificate)
{
m_certStore.insert(certificate);
}
/*! \brief Find a certificate
*
* Find a certificate that NLSR has. First it checks against the
@ -309,20 +316,16 @@ public:
* checks the cache of certficates it has already fetched. If none
* can be found, it will return an empty pointer.
*/
std::shared_ptr<const ndn::IdentityCertificate>
getCertificate(const ndn::Name& certificateNameWithoutVersion)
const ndn::security::v2::Certificate*
getCertificate(const ndn::Name& certificateKeyName)
{
shared_ptr<const ndn::IdentityCertificate> cert =
m_certStore.find(certificateNameWithoutVersion);
if (cert != nullptr) {
return cert;
}
const ndn::security::v2::Certificate* cert =
m_certStore.find(certificateKeyName);
return m_certificateCache->getCertificate(certificateNameWithoutVersion);
return cert;
}
ndn::KeyChain&
ndn::security::v2::KeyChain&
getKeyChain()
{
return m_keyChain;
@ -334,6 +337,12 @@ public:
return m_defaultCertName;
}
const ndn::security::SigningInfo&
getSigningInfo()
{
return m_signingInfo;
}
update::PrefixUpdateProcessor&
getPrefixUpdateProcessor()
{
@ -397,13 +406,6 @@ public:
}
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
addCertificateToCache(std::shared_ptr<ndn::IdentityCertificate> certificate)
{
if (certificate != nullptr) {
m_certificateCache->insertCertificate(certificate);
}
}
security::CertificateStore&
getCertificateStore()
@ -457,13 +459,29 @@ private:
void
scheduleDatasetFetch();
/*! \brief Enables NextHopFaceId indication in NFD for incoming data packet.
*
* After enabling, when NFD gets a data packet, it will put the incoming face id
* of the data in NextHopFaceId field of the packet. The NextHopFaceId will be used
* by DirectFetcher to fetch the certificates needed to validate the data packet.
* \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2#Consumer-Controlled-Forwarding
*/
void
enableIncomingFaceIdIndication();
void
onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp);
void
onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr);
public:
static const ndn::Name LOCALHOST_PREFIX;
private:
ndn::Face& m_nlsrFace;
ndn::Scheduler& m_scheduler;
ndn::KeyChain& m_keyChain;
ndn::security::v2::KeyChain& m_keyChain;
ConfParameter m_confParam;
AdjacencyList m_adjacencyList;
NamePrefixList m_namePrefixList;
@ -486,20 +504,14 @@ private:
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
HelloProtocol m_helloProtocol;
ndn::security::ValidatorConfig m_validator;
private:
/*! \brief Where NLSR caches certificates it has fetched to validate
* Data signatures.
*/
std::shared_ptr<ndn::CertificateCacheTtl> m_certificateCache;
/*! \brief Where NLSR stores certificates it claims to be
* authoritative for. Usually the router certificate.
*/
security::CertificateStore m_certStore;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Validator m_validator;
private:
ndn::nfd::Controller m_controller;
ndn::nfd::Controller m_faceDatasetController;
ndn::security::SigningInfo m_signingInfo;

12
src/publisher/segment-publisher.hpp

@ -40,9 +40,11 @@ class SegmentPublisher : boost::noncopyable
public:
SegmentPublisher(FaceBase& face,
ndn::KeyChain& keyChain,
const ndn::security::SigningInfo& signingInfo,
const ndn::time::milliseconds& freshnessPeriod = getDefaultFreshness())
: m_face(face)
, m_keyChain(keyChain)
, m_signingInfo(signingInfo)
, m_freshnessPeriod(freshnessPeriod)
{
}
@ -75,8 +77,7 @@ public:
* final block ID set to a timestamp.
*/
void
publish(const ndn::Name& prefix,
const ndn::security::SigningInfo& signingInfo = ndn::security::KeyChain::DEFAULT_SIGNING_INFO)
publish(const ndn::Name& prefix)
{
ndn::EncodingBuffer buffer;
generate(buffer);
@ -107,7 +108,7 @@ public:
data->setFinalBlockId(segmentName[-1]);
}
publishSegment(data, signingInfo);
publishSegment(data);
++segmentNo;
} while (segmentBegin < end);
}
@ -122,15 +123,16 @@ private:
/*! \brief Helper function to sign and put data on a Face.
*/
void
publishSegment(std::shared_ptr<ndn::Data>& data, const ndn::security::SigningInfo& signingInfo)
publishSegment(std::shared_ptr<ndn::Data>& data)
{
m_keyChain.sign(*data, signingInfo);
m_keyChain.sign(*data, m_signingInfo);
m_face.put(*data);
}
private:
FaceBase& m_face;
ndn::KeyChain& m_keyChain;
const ndn::security::SigningInfo& m_signingInfo;
const ndn::time::milliseconds m_freshnessPeriod;
};

12
src/route/fib.cpp

@ -67,7 +67,7 @@ Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, NexthopList& hopsToAdd)
if (isPrefixUpdatable(name)) {
// Add nexthop to NDN-FIB
registerPrefix(name, ndn::util::FaceUri(it->getConnectingFaceUri()),
registerPrefix(name, ndn::FaceUri(it->getConnectingFaceUri()),
it->getRouteCostAsAdjustedInteger(),
ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
@ -196,12 +196,12 @@ Fib::isPrefixUpdatable(const ndn::Name& name) {
}
void
Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::util::FaceUri& faceUri,
Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
uint64_t faceCost,
const ndn::time::milliseconds& timeout,
uint64_t flags, uint8_t times)
{
uint64_t faceId = m_adjacencyList.getFaceId(ndn::util::FaceUri(faceUri));
uint64_t faceId = m_adjacencyList.getFaceId(ndn::FaceUri(faceUri));
if (faceId != 0) {
ndn::nfd::ControlParameters faceParameters;
@ -231,7 +231,7 @@ Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::util::FaceUri& faceU
void
Fib::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message, const ndn::util::FaceUri& faceUri)
const std::string& message, const ndn::FaceUri& faceUri)
{
NLSR_LOG_DEBUG(message << ": " << commandSuccessResult.getName() <<
" Face Uri: " << faceUri << " faceId: " << commandSuccessResult.getFaceId());
@ -250,7 +250,7 @@ void
Fib::onRegistrationFailure(const ndn::nfd::ControlResponse& response,
const std::string& message,
const ndn::nfd::ControlParameters& parameters,
const ndn::util::FaceUri& faceUri,
const ndn::FaceUri& faceUri,
uint8_t times)
{
NLSR_LOG_DEBUG(message << ": " << response.getText() << " (code: " << response.getCode() << ")");
@ -385,7 +385,7 @@ Fib::refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb)
for (const NextHop& hop : entry) {
registerPrefix(entry.getName(),
ndn::util::FaceUri(hop.getConnectingFaceUri()),
ndn::FaceUri(hop.getConnectingFaceUri()),
hop.getRouteCostAsAdjustedInteger(),
ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
ndn::nfd::ROUTE_FLAG_CAPTURE, 0);

8
src/route/fib.hpp

@ -55,7 +55,7 @@ class Fib
{
public:
Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList, ConfParameter& conf,
ndn::KeyChain& keyChain)
ndn::security::v2::KeyChain& keyChain)
: m_scheduler(scheduler)
, m_refreshTime(0)
, m_controller(face, keyChain)
@ -131,7 +131,7 @@ public:
*/
void
registerPrefix(const ndn::Name& namePrefix,
const ndn::util::FaceUri& faceUri,
const ndn::FaceUri& faceUri,
uint64_t faceCost,
const ndn::time::milliseconds& timeout,
uint64_t flags,
@ -173,7 +173,7 @@ private:
*/
void
onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const std::string& message, const ndn::util::FaceUri& faceUri);
const std::string& message, const ndn::FaceUri& faceUri);
/*! \brief Retry a prefix (next-hop) registration up to three (3) times.
*/
@ -181,7 +181,7 @@ private:
onRegistrationFailure(const ndn::nfd::ControlResponse& response,
const std::string& message,
const ndn::nfd::ControlParameters& parameters,
const ndn::util::FaceUri& faceUri,
const ndn::FaceUri& faceUri,
uint8_t times);
/*! \brief Log a successful unregistration.

19
src/security/certificate-store.hpp

@ -26,7 +26,7 @@
#include "../test-access-control.hpp"
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/security/v1/identity-certificate.hpp>
#include <ndn-cxx/security/v2/certificate.hpp>
namespace nlsr {
namespace security {
@ -42,21 +42,18 @@ class CertificateStore
{
public:
void
insert(std::shared_ptr<ndn::IdentityCertificate> certificate)
insert(const ndn::security::v2::Certificate& certificate)
{
if (certificate != nullptr) {
// Key is cert name without version
m_certificates[certificate->getName().getPrefix(-1)] = certificate;
}
m_certificates[certificate.getKeyName()] = certificate;
}
std::shared_ptr<const ndn::IdentityCertificate>
find(const ndn::Name& certificateNameWithoutVersion) const
const ndn::security::v2::Certificate*
find(const ndn::Name keyName)
{
CertMap::const_iterator it = m_certificates.find(certificateNameWithoutVersion);
CertMap::iterator it = m_certificates.find(keyName);
if (it != m_certificates.end()) {
return it->second;
return &it->second;
}
return nullptr;
@ -70,7 +67,7 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
}
private:
typedef std::map<ndn::Name, std::shared_ptr<ndn::IdentityCertificate>> CertMap;
typedef std::map<ndn::Name, ndn::security::v2::Certificate> CertMap;
CertMap m_certificates;
};

4
src/tlv/coordinate-lsa.cpp

@ -21,10 +21,12 @@
#include "coordinate-lsa.hpp"
#include "tlv-nlsr.hpp"
#include "logger.hpp"
#include <ndn-cxx/util/concepts.hpp>
#include <ndn-cxx/encoding/block-helpers.hpp>
#include "logger.hpp"
#include <iostream>
namespace nlsr {
namespace tlv {

2
src/update/manager-base.cpp

@ -55,7 +55,7 @@ CommandManagerBase::advertiseAndInsertPrefix(const ndn::Name& prefix,
const ndn::Interest& interest,
const ndn::mgmt::ControlParameters& parameters,
const ndn::mgmt::CommandContinuation& done)
{
{
const ndn::nfd::ControlParameters& castParams =
static_cast<const ndn::nfd::ControlParameters&>(parameters);

6
src/update/manager-base.hpp

@ -103,9 +103,9 @@ class CommandManagerBase: public ManagerBase
{
public:
CommandManagerBase(ndn::mgmt::Dispatcher& m_dispatcher,
NamePrefixList& m_namePrefixList,
Lsdb& lsdb,
const std::string& module);
NamePrefixList& m_namePrefixList,
Lsdb& lsdb,
const std::string& module);
/*! \brief add desired name prefix to the advertised name prefix list
* or insert a prefix into the FIB if parameters is valid.

24
src/update/prefix-update-processor.cpp

@ -24,7 +24,7 @@
#include "nlsr.hpp"
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
#include <ndn-cxx/tag.hpp>
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/face.hpp>
namespace nlsr {
namespace update {
@ -52,13 +52,10 @@ getSignerFromTag(const ndn::Interest& interest)
PrefixUpdateProcessor::PrefixUpdateProcessor(ndn::mgmt::Dispatcher& dispatcher,
ndn::Face& face,
NamePrefixList& namePrefixList,
Lsdb& lsdb,
const ndn::Name broadcastPrefix,
ndn::KeyChain& keyChain,
std::shared_ptr<ndn::CertificateCacheTtl> certificateCache,
security::CertificateStore& certStore)
Lsdb& lsdb)
: CommandManagerBase(dispatcher, namePrefixList, lsdb, "prefix-update")
, m_validator(face, broadcastPrefix, certificateCache, certStore)
, m_validator(ndn::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(face))
{
NLSR_LOG_DEBUG("Setting dispatcher to capture Interests for: "
<< ndn::Name(Nlsr::LOCALHOST_PREFIX).append("prefix-update"));
@ -84,17 +81,16 @@ PrefixUpdateProcessor::makeAuthorization()
const ndn::mgmt::AcceptContinuation& accept,
const ndn::mgmt::RejectContinuation& reject) {
m_validator.validate(interest,
[accept] (const std::shared_ptr<const ndn::Interest>& request) {
[accept] (const ndn::Interest& request) {
auto signer1 = getSignerFromTag(*request);
auto signer1 = getSignerFromTag(request);
std::string signer = signer1.value_or("*");
NLSR_LOG_DEBUG("accept " << request->getName() << " signer=" << signer);
NLSR_LOG_DEBUG("accept " << request.getName() << " signer=" << signer);
accept(signer);
},
[reject] (const std::shared_ptr<const ndn::Interest>& request,
const std::string& failureInfo) {
NLSR_LOG_DEBUG("reject " << request->getName() << " signer=" <<
getSignerFromTag(*request).value_or("?") << ' ' << failureInfo);
[reject] (const ndn::Interest& request, const ndn::security::v2::ValidationError& error) {
NLSR_LOG_DEBUG("reject " << request.getName() << " signer=" <<
getSignerFromTag(request).value_or("?") << ' ' << error);
reject(ndn::mgmt::RejectReply::STATUS403);
});
};

17
src/update/prefix-update-processor.hpp

@ -25,11 +25,11 @@
#include "manager-base.hpp"
#include "prefix-update-commands.hpp"
#include "test-access-control.hpp"
#include "validator.hpp"
#include <ndn-cxx/security/certificate-cache-ttl.hpp>
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/v2/validator.hpp>
#include <ndn-cxx/security/v2/certificate-storage.hpp>
#include <ndn-cxx/util/io.hpp>
#include <boost/property_tree/ptree.hpp>
#include <memory>
@ -50,11 +50,7 @@ public:
PrefixUpdateProcessor(ndn::mgmt::Dispatcher& dispatcher,
ndn::Face& face,
NamePrefixList& namePrefixList,
Lsdb& lsdb,
const ndn::Name broadcastPrefix,
ndn::KeyChain& keyChain,
std::shared_ptr<ndn::CertificateCacheTtl> certificateCache,
security::CertificateStore& certStore);
Lsdb& lsdb);
/*! \brief Load the validator's configuration from a section of a
* configuration file.
@ -70,8 +66,7 @@ public:
void
loadValidator(ConfigSection section, const std::string& filename);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Validator&
ndn::security::ValidatorConfig&
getValidator()
{
return m_validator;
@ -88,7 +83,7 @@ private:
makeAuthorization();
private:
Validator m_validator;
ndn::security::ValidatorConfig m_validator;
};
} // namespace update

89
src/validator.cpp

@ -1,89 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "validator.hpp"
namespace nlsr {
void
Validator::checkPolicy(const ndn::Data& data, int nSteps, const ndn::OnDataValidated& onValidated,
const ndn::OnDataValidationFailed& onValidationFailed,
std::vector<shared_ptr<ndn::ValidationRequest>>& nextSteps)
{
if (!m_shouldValidate) {
onValidated(data.shared_from_this());
}
else {
ValidatorConfig::checkPolicy(data, nSteps, onValidated, onValidationFailed, nextSteps);
}
}
void
Validator::afterCheckPolicy(const NextSteps& nextSteps, const OnFailure& onFailure)
{
if (m_face == nullptr) {
onFailure("Require more information to validate the packet!");
return;
}
for (const std::shared_ptr<ndn::ValidationRequest>& request : nextSteps) {
ndn::Interest& interest = request->m_interest;
// Look for certificate in permanent storage
std::shared_ptr<const ndn::IdentityCertificate> cert = m_certStore.find(interest.getName());
if (cert != nullptr) {
// If the certificate is found, no reason to express interest
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(interest.getName());
data->setContent(cert->wireEncode());
Validator::onData(interest, *data, request);
}
else {
// Prepend broadcast prefix to interest name
ndn::Name broadcastName = m_broadcastPrefix;
broadcastName.append(interest.getName());
interest.setName(broadcastName);
// Attempt to fetch the certificate
m_face->expressInterest(interest,
std::bind(&Validator::onData, this, _1, _2, request),
std::bind(&Validator::onTimeout, // Nack
this, _1, request->m_nRetries,
onFailure,
request),
std::bind(&Validator::onTimeout,
this, _1, request->m_nRetries,
onFailure,
request));
}
}
}
std::shared_ptr<const ndn::Data>
Validator::preCertificateValidation(const ndn::Data& data)
{
std::shared_ptr<ndn::Data> internalData = std::make_shared<ndn::Data>();
internalData->wireDecode(data.getContent().blockFromValue());
return internalData;
}
} // namespace nlsr

103
src/validator.hpp

@ -1,103 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_VALIDATOR_HPP
#define NLSR_VALIDATOR_HPP
#include "common.hpp"
#include "security/certificate-store.hpp"
#include <ndn-cxx/security/validator-config.hpp>
namespace nlsr {
class Validator : public ndn::ValidatorConfig
{
public:
class Error : public ndn::ValidatorConfig::Error
{
public:
explicit
Error(const std::string& what)
: ndn::ValidatorConfig::Error(what)
{
}
};
explicit
Validator(ndn::Face& face,
const ndn::Name broadcastPrefix,
const std::shared_ptr<ndn::CertificateCache>& cache,
security::CertificateStore& certStore,
const int stepLimit = 10)
: ndn::ValidatorConfig(face, cache, ndn::ValidatorConfig::DEFAULT_GRACE_INTERVAL, stepLimit)
, m_shouldValidate(true)
, m_broadcastPrefix(broadcastPrefix)
, m_certStore(certStore)
{
m_broadcastPrefix.append("KEYS");
}
virtual
~Validator()
{
}
const ndn::Name&
getBroadcastPrefix()
{
return m_broadcastPrefix;
}
void
setBroadcastPrefix(const ndn::Name& broadcastPrefix)
{
m_broadcastPrefix = broadcastPrefix;
}
protected:
typedef std::vector<std::shared_ptr<ndn::ValidationRequest>> NextSteps;
void
checkPolicy(const ndn::Data& data,
int nSteps,
const ndn::OnDataValidated& onValidated,
const ndn::OnDataValidationFailed& onValidationFailed,
std::vector<shared_ptr<ndn::ValidationRequest>>& nextSteps) override;
void
afterCheckPolicy(const NextSteps& nextSteps,
const OnFailure& onFailure) override;
std::shared_ptr<const ndn::Data>
preCertificateValidation(const ndn::Data& data) override;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
bool m_shouldValidate;
private:
ndn::Name m_broadcastPrefix;
security::CertificateStore& m_certStore;
};
} // namespace nlsr
#endif // NLSR_VALIDATOR_HPP

34
tests-integrated/boost-test.hpp

@ -1,34 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis
* Regents of the University of California,
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_TESTS_INTEGRATED_BOOST_TEST_HPP
#define NLSR_TESTS_INTEGRATED_BOOST_TEST_HPP
// suppress warnings from Boost.Test
#pragma GCC system_header
#pragma clang system_header
#include <boost/test/unit_test.hpp>
#include <boost/concept_check.hpp>
#include <boost/test/output_test_stream.hpp>
#endif // NLSR_TESTS_INTEGRATED_BOOST_TEST_HPP

24
tests-integrated/main.cpp

@ -1,24 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#define BOOST_TEST_MAIN 1
#define BOOST_TEST_DYN_LINK 1
#include "boost-test.hpp"

273
tests-integrated/test-validator.cpp

@ -1,273 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "validator.hpp"
#include <ndn-cxx/security/certificate-cache-ttl.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include "boost-test.hpp"
#include "common.hpp"
#include "security/certificate-store.hpp"
namespace nlsr {
namespace test {
BOOST_AUTO_TEST_SUITE(TestValidator)
struct ValidatorFixture
{
ValidatorFixture()
: m_face2(m_face.getIoService())
, m_scheduler(m_face.getIoService())
, m_keyPrefix("/ndn/broadcast/KEYS")
, m_certificateCache(new ndn::CertificateCacheTtl(m_face.getIoService()))
, m_validator(m_face2, ndn::Name("/ndn/broadcast"), m_certificateCache, m_certStore)
, m_identity("/TestValidator/NLSR")
, m_wasValidated(false)
{
m_face.setInterestFilter(m_keyPrefix,
std::bind(&ValidatorFixture::onKeyInterest, this, _1, _2),
std::bind(&ValidatorFixture::onKeyPrefixRegSuccess, this, _1),
std::bind(&ValidatorFixture::registrationFailed, this, _1, _2));
m_keyChain.createIdentity(m_identity);
ndn::Name certName = m_keyChain.getDefaultCertificateNameForIdentity(m_identity);
m_cert = m_keyChain.getCertificate(certName);
ndn::io::save(*m_cert, "trust-anchor.cert");
const std::string CONFIG =
"rule\n"
"{\n"
" id \"NSLR Hello Rule\"\n"
" for data\n"
" filter\n"
" {\n"
" type name\n"
" regex ^[^<NLSR><INFO>]*<NLSR><INFO><><>$\n"
" }\n"
" checker\n"
" {\n"
" type customized\n"
" sig-type rsa-sha256\n"
" key-locator\n"
" {\n"
" type name\n"
" hyper-relation\n"
" {\n"
" k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$\n"
" k-expand \\\\1\n"
" h-relation equal\n"
" p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$\n"
" p-expand \\\\1\n"
" }\n"
" }\n"
" }\n"
"}\n"
"rule\n"
"{\n"
" id \"Single Rule\"\n"
" for data\n"
" filter\n"
" {\n"
" type name\n"
" regex ^<TestValidator>([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><><>$\n"
" }\n"
" checker\n"
" {\n"
" type fixed-signer\n"
" sig-type rsa-sha256\n"
" signer\n"
" {\n"
" type file\n"
" file-name \"trust-anchor.cert\"\n"
" }\n"
" }\n"
"}\n";
const boost::filesystem::path CONFIG_PATH =
(boost::filesystem::current_path() / std::string("unit-test.conf"));
m_validator.load(CONFIG, CONFIG_PATH.native());
}
~ValidatorFixture()
{
m_keyChain.deleteIdentity(m_identity);
const boost::filesystem::path CERT_PATH =
(boost::filesystem::current_path() / std::string("trust-anchor.cert"));
boost::filesystem::remove(CERT_PATH);
}
void
onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
{
const ndn::Name& interestName = interest.getName();
ndn::Name certName = interestName.getSubName(name.size());
if (certName[-2].toUri() == "ID-CERT")
{
certName = certName.getPrefix(-1);
}
else if (certName[-1].toUri() != "ID-CERT")
return; //Wrong key interest.
if (certName != m_cert->getName().getPrefix(-1))
return; //No such a cert
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(interestName);
data->setContent(m_cert->wireEncode());
m_keyChain.signWithSha256(*data);
m_face.put(*data);
}
void
onKeyPrefixRegSuccess(const ndn::Name& name)
{
BOOST_REQUIRE(true);
}
void
registrationFailed(const ndn::Name& name, const std::string& msg)
{
std::cerr << "Failure Info: " << msg << std::endl;
BOOST_REQUIRE(false);
}
void
onValidated(const std::shared_ptr<const ndn::Data>& data)
{
m_wasValidated = true;
}
void
onValidationFailed(const std::shared_ptr<const ndn::Data>& data,
const std::string& failureInfo)
{
std::cerr << "Failure Info: " << failureInfo << std::endl;
m_wasValidated = false;
}
void
validate(const std::shared_ptr<const ndn::Data>& data)
{
m_validator.validate(*data,
std::bind(&ValidatorFixture::onValidated, this, _1),
std::bind(&ValidatorFixture::onValidationFailed, this, _1, _2));
}
void
terminate()
{
m_face.getIoService().stop();
}
protected:
ndn::Face m_face;
ndn::Face m_face2;
ndn::Scheduler m_scheduler;
const ndn::Name m_keyPrefix;
std::shared_ptr<ndn::CertificateCacheTtl> m_certificateCache;
security::CertificateStore m_certStore;
nlsr::Validator m_validator;
ndn::KeyChain m_keyChain;
ndn::Name m_identity;
std::shared_ptr<ndn::IdentityCertificate> m_cert;
bool m_wasValidated;
};
BOOST_FIXTURE_TEST_CASE(InfoCertFetch, ValidatorFixture)
{
ndn::Name dataName = m_identity;
dataName.append("INFO").append("neighbor").append("version");
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(dataName);
m_keyChain.signByIdentity(*data, m_identity);
m_scheduler.scheduleEvent(ndn::time::milliseconds(200),
std::bind(&ValidatorFixture::validate, this, data));
m_scheduler.scheduleEvent(ndn::time::milliseconds(1000),
std::bind(&ValidatorFixture::terminate, this));
BOOST_REQUIRE_NO_THROW(m_face.processEvents());
BOOST_CHECK(m_wasValidated);
}
BOOST_FIXTURE_TEST_CASE(CertificateStorage, ValidatorFixture)
{
std::vector<ndn::security::v1::CertificateSubjectDescription> subjectDescription;
// Create an operator identity
ndn::Name opIdentity("/TestValidator/operator/NLSR");
m_keyChain.createIdentity(opIdentity);
// Create an operator cert signed by the trust anchor
ndn::Name keyName = m_keyChain.generateRsaKeyPairAsDefault(opIdentity, true);
std::shared_ptr<ndn::IdentityCertificate> opCert =
m_keyChain.prepareUnsignedIdentityCertificate(keyName,
m_identity,
ndn::time::system_clock::now(),
ndn::time::system_clock::now()
+ ndn::time::days(1),
subjectDescription);
m_keyChain.signByIdentity(*opCert, m_identity);
m_keyChain.addCertificateAsIdentityDefault(*opCert);
// Sign data with operator cert
ndn::Name dataName = opIdentity;
dataName.append("INFO").append("neighbor").append("version");
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(dataName);
m_keyChain.signByIdentity(*data, opIdentity);
// Check without cert in CertificateStore
m_scheduler.scheduleEvent(ndn::time::milliseconds(200),
std::bind(&ValidatorFixture::validate, this, data));
m_scheduler.scheduleEvent(ndn::time::milliseconds(1000),
std::bind(&ValidatorFixture::terminate, this));
BOOST_REQUIRE_NO_THROW(m_face.processEvents());
BOOST_CHECK_EQUAL(m_wasValidated, false);
// Check with cert in CertificateStore
m_certStore.insert(opCert);
m_scheduler.scheduleEvent(ndn::time::milliseconds(200),
std::bind(&ValidatorFixture::validate, this, data));
m_scheduler.scheduleEvent(ndn::time::milliseconds(1000),
std::bind(&ValidatorFixture::terminate, this));
BOOST_REQUIRE_NO_THROW(m_face.processEvents());
BOOST_CHECK(m_wasValidated);
// Cleanup
m_keyChain.deleteIdentity(opIdentity);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace test
} // namespace nlsr

41
tests-integrated/wscript

@ -1,41 +0,0 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2016, The University of Memphis
Regents of the University of California,
This file is part of NLSR (Named-data Link State Routing).
See AUTHORS.md for complete list of NLSR authors and contributors.
NLSR 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.
NLSR 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
NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
"""
top = '..'
def build(bld):
if bld.env['WITH_TESTS']:
integrated_test_main = bld(
target='integrated-tests-main',
name='integrated-tests-main',
features='cxx',
source=bld.path.ant_glob(['*.cpp']),
use='nlsr-objects',
)
integrated_test_nlsr = bld.program (
target="../integrated-tests-nlsr",
features="cxx cxxprogram",
source=bld.path.ant_glob(['nlsr/**/*.cpp']),
use='nlsr-objects integrated-tests-main',
includes='.',
install_path=None,
)

214
tests/boost-multi-log-formatter.hpp

@ -0,0 +1,214 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017 Regents of the University of California.
*
* Based on work by Martin Ba (http://stackoverflow.com/a/26718189)
*
* This file is distributed under the Boost Software License, Version 1.0.
* (See http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
#define NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
#include <boost/version.hpp>
#if BOOST_VERSION >= 105900
#include <boost/test/unit_test_parameters.hpp>
#else
#include <boost/test/detail/unit_test_parameters.hpp>
#endif // BOOST_VERSION >= 105900
#include <boost/test/unit_test_log_formatter.hpp>
#include <boost/test/output/compiler_log_formatter.hpp>
#include <boost/test/output/xml_log_formatter.hpp>
namespace boost {
namespace unit_test {
namespace output {
/**
* @brief Log formatter for Boost.Test that outputs the logging to multiple formatters
*
* The log formatter is designed to output to one or multiple formatters at the same time. For
* example, one HRF formatter can output to the standard output, while XML formatter output to
* the file.
*
* Usage:
*
* // Call in init_unit_test_suite: (this will override the --log_format parameter)
* auto formatter = new boost::unit_test::output::multi_log_formatter; // same as already configured logger
*
* // Prepare and add additional logger(s)
* formatter.add(std::make_shared<boost::unit_test::output::xml_log_formatter>(),
* std::make_shared<std::ofstream>("out.xml"));
*
* boost::unit_test::unit_test_log.set_formatter(formatter);
*
* @note Calling `boost::unit_test::unit_test_log.set_stream(...)` will change the stream for
* the original logger.
*/
class multi_log_formatter : public unit_test_log_formatter
{
public:
/**
* @brief Create instance of the logger, based on the configured logger instance
*/
multi_log_formatter()
{
auto format =
#if BOOST_VERSION > 105900
runtime_config::get<output_format>(runtime_config::LOG_FORMAT);
#else
runtime_config::log_format();
#endif // BOOST_VERSION > 105900
switch (format) {
default:
#if BOOST_VERSION >= 105900
case OF_CLF:
#else
case CLF:
#endif // BOOST_VERSION >= 105900
m_loggers.push_back({std::make_shared<compiler_log_formatter>(), nullptr});
break;
#if BOOST_VERSION >= 105900
case OF_XML:
#else
case XML:
#endif // BOOST_VERSION >= 105900
m_loggers.push_back({std::make_shared<xml_log_formatter>(), nullptr});
break;
}
}
void
add(std::shared_ptr<unit_test_log_formatter> formatter, std::shared_ptr<std::ostream> os)
{
m_loggers.push_back({formatter, os});
}
// Formatter interface
void
log_start(std::ostream& os, counter_t test_cases_amount)
{
for (auto& l : m_loggers)
l.logger->log_start(l.os == nullptr ? os : *l.os, test_cases_amount);
}
void
log_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_finish(l.os == nullptr ? os : *l.os);
}
void
log_build_info(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_build_info(l.os == nullptr ? os : *l.os);
}
void
test_unit_start(std::ostream& os, const test_unit& tu)
{
for (auto& l : m_loggers)
l.logger->test_unit_start(l.os == nullptr ? os : *l.os, tu);
}
void
test_unit_finish(std::ostream& os, const test_unit& tu, unsigned long elapsed)
{
for (auto& l : m_loggers)
l.logger->test_unit_finish(l.os == nullptr ? os : *l.os, tu, elapsed);
}
void
test_unit_skipped(std::ostream& os, const test_unit& tu)
{
for (auto& l : m_loggers)
l.logger->test_unit_skipped(l.os == nullptr ? os : *l.os, tu);
}
#if BOOST_VERSION >= 105900
void
log_exception_start(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
{
for (auto& l : m_loggers)
l.logger->log_exception_start(l.os == nullptr ? os : *l.os, lcd, ex);
}
void
log_exception_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_exception_finish(l.os == nullptr ? os : *l.os);
}
#else
void
log_exception(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
{
for (auto& l : m_loggers)
l.logger->log_exception(l.os == nullptr ? os : *l.os, lcd, ex);
}
#endif // BOOST_VERSION >= 105900
void
log_entry_start(std::ostream& os, const log_entry_data& entry_data, log_entry_types let)
{
for (auto& l : m_loggers)
l.logger->log_entry_start(l.os == nullptr ? os : *l.os, entry_data, let);
}
void
log_entry_value(std::ostream& os, const_string value)
{
for (auto& l : m_loggers)
l.logger->log_entry_value(l.os == nullptr ? os : *l.os, value);
}
void
log_entry_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_entry_finish(l.os == nullptr ? os : *l.os);
}
#if BOOST_VERSION >= 105900
void
entry_context_start(std::ostream& os, log_level level)
{
for (auto& l : m_loggers)
l.logger->entry_context_start(l.os == nullptr ? os : *l.os, level);
}
void
log_entry_context(std::ostream& os, const_string value)
{
for (auto& l : m_loggers)
l.logger->log_entry_context(l.os == nullptr ? os : *l.os, value);
}
void
entry_context_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->entry_context_finish(l.os == nullptr ? os : *l.os);
}
#endif // BOOST_VERSION >= 105900
private:
struct LoggerInfo
{
std::shared_ptr<unit_test_log_formatter> logger;
std::shared_ptr<std::ostream> os;
};
std::vector<LoggerInfo> m_loggers;
};
} // namespace output
} // namespace unit_test
} // namespace boost
#endif // NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP

102
tests/identity-fixture.cpp

@ -1,102 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
**/
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library 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 Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include <ndn-cxx/security/key-chain.hpp>
#include "boost-test.hpp"
namespace nlsr {
// OSX KeyChain, when used on a headless server,
// forbids usage of a private key if that key isn't created by the calling process.
// Therefore, unit testing must create its own key pair.
class IdentityFixture
{
public:
IdentityFixture()
{
// save the old default identity
try {
m_oldDefaultIdentity = m_keyChain.getDefaultIdentity();
m_hasOldDefaultIdentity = true;
}
catch (ndn::SecPublicInfo::Error& e) {
m_hasOldDefaultIdentity = false;
}
m_newIdentity = "/nlsr-test-identity";
m_newIdentity.appendVersion();
// create the new identity and self-signed certificate
m_keyChain.createIdentity(m_newIdentity);
// set the new identity as default identity,
// and the corresponding certificate becomes the default certificate
m_keyChain.setDefaultIdentity(m_newIdentity);
}
~IdentityFixture()
{
// recover the old default setting
if (m_hasOldDefaultIdentity) {
m_keyChain.setDefaultIdentity(m_oldDefaultIdentity);
}
// remove the temporarily created identity and certificates
// XXX This has no effect if oldDefaultIdentity doesn't exist.
// newIdentity would be kept as default.
m_keyChain.deleteIdentity(m_newIdentity);
}
private:
ndn::KeyChain m_keyChain;
bool m_hasOldDefaultIdentity;
ndn::Name m_oldDefaultIdentity;
ndn::Name m_newIdentity;
};
BOOST_GLOBAL_FIXTURE(IdentityFixture)
#if BOOST_VERSION >= 105900
;
#endif // BOOST_VERSION >= 105900
} // namespace nlsr

143
tests/identity-management-fixture.cpp

@ -0,0 +1,143 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, 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 NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "identity-management-fixture.hpp"
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/security/v2/additional-description.hpp>
#include <boost/filesystem.hpp>
namespace nlsr {
namespace tests {
namespace v2 = ndn::security::v2;
namespace io = ndn::io;
namespace time = ndn::time;
IdentityManagementBaseFixture::~IdentityManagementBaseFixture()
{
boost::system::error_code ec;
for (const auto& certFile : m_certFiles) {
boost::filesystem::remove(certFile, ec); // ignore error
}
}
bool
IdentityManagementBaseFixture::saveCertToFile(const ndn::Data& obj,
const std::string& filename)
{
m_certFiles.insert(filename);
try {
io::save(obj, filename);
return true;
}
catch (const io::Error&) {
return false;
}
}
IdentityManagementFixture::IdentityManagementFixture()
: m_keyChain("pib-memory:", "tpm-memory:")
{
}
ndn::security::Identity
IdentityManagementFixture::addIdentity(const ndn::Name& identityName,
const ndn::KeyParams& params)
{
auto identity = m_keyChain.createIdentity(identityName, params);
m_identities.insert(identityName);
return identity;
}
bool
IdentityManagementFixture::saveCertificate(const ndn::security::Identity& identity,
const std::string& filename)
{
try {
auto cert = identity.getDefaultKey().getDefaultCertificate();
return saveCertToFile(cert, filename);
}
catch (const ndn::security::Pib::Error&) {
return false;
}
}
ndn::security::Identity
IdentityManagementFixture::addSubCertificate(const ndn::Name& subIdentityName,
const ndn::security::Identity& issuer,
const ndn::KeyParams& params)
{
auto subIdentity = addIdentity(subIdentityName, params);
v2::Certificate request = subIdentity.getDefaultKey().getDefaultCertificate();
request.setName(request.getKeyName().append("parent").appendVersion());
ndn::SignatureInfo info;
info.setValidityPeriod(ndn::security::ValidityPeriod(time::system_clock::now(),
time::system_clock::now()
+ time::days(7300)));
v2::AdditionalDescription description;
description.set("type", "sub-certificate");
info.appendTypeSpecificTlv(description.wireEncode());
m_keyChain.sign(request, ndn::signingByIdentity(issuer).setSignatureInfo(info));
m_keyChain.setDefaultCertificate(subIdentity.getDefaultKey(), request);
return subIdentity;
}
v2::Certificate
IdentityManagementFixture::addCertificate(const ndn::security::Key& key,
const std::string& issuer)
{
ndn::Name certificateName = key.getName();
certificateName
.append(issuer)
.appendVersion();
v2::Certificate certificate;
certificate.setName(certificateName);
// set metainfo
certificate.setContentType(ndn::tlv::ContentType_Key);
certificate.setFreshnessPeriod(time::hours(1));
// set content
certificate.setContent(key.getPublicKey().data(), key.getPublicKey().size());
// set signature-info
ndn::SignatureInfo info;
info.setValidityPeriod(ndn::security::ValidityPeriod(time::system_clock::now(),
time::system_clock::now() + time::days(10)));
m_keyChain.sign(certificate, ndn::signingByKey(key).setSignatureInfo(info));
return certificate;
}
} // namespace tests
} // namespace nlsr

106
tests/identity-management-fixture.hpp

@ -0,0 +1,106 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, 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 NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NLSR_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
#define NLSR_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
#include "boost-test.hpp"
#include "test-home-fixture.hpp"
#include <vector>
#include <ndn-cxx/security/v2/key-chain.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
namespace nlsr {
namespace tests {
class IdentityManagementBaseFixture : public TestHomeFixture<DefaultPibDir>
{
public:
~IdentityManagementBaseFixture();
bool
saveCertToFile(const ndn::Data& obj, const std::string& filename);
protected:
std::set<ndn::Name> m_identities;
std::set<std::string> m_certFiles;
};
/**
* @brief A test suite level fixture to help with identity management
*
* Test cases in the suite can use this fixture to create identities. Identities,
* certificates, and saved certificates are automatically removed during test teardown.
*/
class IdentityManagementFixture : public IdentityManagementBaseFixture
{
public:
IdentityManagementFixture();
/**
* @brief Add identity @p identityName
* @return name of the created self-signed certificate
*/
ndn::security::Identity
addIdentity(const ndn::Name& identityName, const ndn::KeyParams& params = ndn::KeyChain::getDefaultKeyParams());
/**
* @brief Save identity certificate to a file
* @param identity identity
* @param filename file name, should be writable
* @return whether successful
*/
bool
saveCertificate(const ndn::security::Identity& identity, const std::string& filename);
/**
* @brief Issue a certificate for \p subidentityName signed by \p issuer
*
* If identity does not exist, it is created.
* A new key is generated as the default key for identity.
* A default certificate for the key is signed by the issuer using its default certificate.
*
* @return the sub identity
*/
ndn::security::Identity
addSubCertificate(const ndn::Name& identityName, const ndn::security::Identity& issuer,
const ndn::KeyParams& params = ndn::KeyChain::getDefaultKeyParams());
/**
* @brief Add a self-signed certificate to @p key with issuer ID @p issuer
*/
ndn::security::v2::Certificate
addCertificate(const ndn::security::Key& key, const std::string& issuer);
protected:
ndn::KeyChain m_keyChain;
};
} // namespace tests
} // namespace nlsr
#endif // NLSR_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP

104
tests/main.cpp

@ -1,7 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
* Copyright (c) 2014-2017, 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 NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
@ -16,12 +21,95 @@
*
* You should have received a copy of the GNU General Public License along with
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* \author Yingdi Yu <yingdi@cs.ucla.edu>
*
**/
*/
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_ALTERNATIVE_INIT_API
#define BOOST_TEST_MAIN 1
#define BOOST_TEST_DYN_LINK 1
#include <boost/version.hpp>
#if BOOST_VERSION >= 106200
// Boost.Test v3.3 (Boost 1.62) natively supports multi-logger output
#include "boost-test.hpp"
#else
#define BOOST_TEST_NO_MAIN
#include "boost-test.hpp"
#include "boost-multi-log-formatter.hpp"
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <fstream>
#include <iostream>
static bool
init_tests()
{
init_unit_test();
namespace po = boost::program_options;
namespace ut = boost::unit_test;
po::options_description extraOptions;
std::string logger;
std::string outputFile = "-";
extraOptions.add_options()
("log_format2", po::value<std::string>(&logger), "Type of second log formatter: HRF or XML")
("log_sink2", po::value<std::string>(&outputFile)->default_value(outputFile), "Second log sink, - for stdout")
;
po::variables_map vm;
try {
po::store(po::command_line_parser(ut::framework::master_test_suite().argc,
ut::framework::master_test_suite().argv)
.options(extraOptions)
.run(),
vm);
po::notify(vm);
}
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << "\n"
<< extraOptions << std::endl;
return false;
}
if (vm.count("log_format2") == 0) {
// second logger is not configured
return true;
}
std::shared_ptr<ut::unit_test_log_formatter> formatter;
if (logger == "XML") {
formatter = std::make_shared<ut::output::xml_log_formatter>();
}
else if (logger == "HRF") {
formatter = std::make_shared<ut::output::compiler_log_formatter>();
}
else {
std::cerr << "ERROR: only HRF or XML log formatter can be specified" << std::endl;
return false;
}
std::shared_ptr<std::ostream> output;
if (outputFile == "-") {
output = std::shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
}
else {
output = std::make_shared<std::ofstream>(outputFile.c_str());
}
auto multiFormatter = new ut::output::multi_log_formatter;
multiFormatter->add(formatter, output);
ut::unit_test_log.set_formatter(multiFormatter);
return true;
}
int
main(int argc, char* argv[])
{
return ::boost::unit_test::unit_test_main(&init_tests, argc, argv);
}
#endif // BOOST_VERSION >= 106200

17
tests/publisher/publisher-fixture.hpp

@ -30,6 +30,9 @@
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/pib/identity.hpp>
#include <ndn-cxx/util/io.hpp>
#include <boost/filesystem.hpp>
@ -42,13 +45,16 @@ class PublisherFixture : public BaseFixture
{
public:
PublisherFixture()
: face(g_ioService, keyChain, {true, true})
, nlsr(g_ioService, g_scheduler, face, g_keyChain)
: face(m_ioService, m_keyChain, {true, true})
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, lsdb(nlsr.getLsdb())
{
INIT_LOGGERS("/tmp/","TRACE");
INIT_LOGGERS("/tmp/", "TRACE");
nlsr.getConfParameter().setNetwork("/ndn");
nlsr.getConfParameter().setRouterName("/This/Router");
routerId = addIdentity("/ndn/This/Router");
nlsr.initialize();
face.processEvents(ndn::time::milliseconds(100));
}
@ -56,7 +62,7 @@ public:
void
addAdjacency(AdjLsa& lsa, const std::string& name, const std::string& faceUri, double cost)
{
Adjacent adjacency(name, ndn::util::FaceUri(faceUri), cost, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent adjacency(name, ndn::FaceUri(faceUri), cost, Adjacent::STATUS_ACTIVE, 0, 0);
lsa.addAdjacent(std::move(adjacency));
}
@ -148,10 +154,11 @@ public:
public:
ndn::util::DummyClientFace face;
ndn::KeyChain keyChain;
Nlsr nlsr;
Lsdb& lsdb;
ndn::security::pib::Identity routerId;
};
} // namespace test

25
tests/publisher/test-segment-publisher.cpp

@ -26,6 +26,7 @@
#include "publisher/segment-publisher.hpp"
#include "../boost-test.hpp"
#include "../test-common.hpp"
#include <ndn-cxx/encoding/tlv.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>
@ -36,14 +37,17 @@
namespace nlsr {
namespace tests {
using namespace nlsr::test;
template<int64_t N=10000>
class TestSegmentPublisher : public SegmentPublisher<ndn::util::DummyClientFace>
{
public:
TestSegmentPublisher(ndn::util::DummyClientFace& face,
ndn::KeyChain& keyChain,
ndn::security::SigningInfo& signingInfo,
const ndn::time::milliseconds freshnessPeriod)
: SegmentPublisher(face, keyChain, freshnessPeriod)
: SegmentPublisher(face, keyChain, signingInfo, freshnessPeriod)
, m_totalPayloadLength(0)
{
@ -72,10 +76,10 @@ protected:
generate(ndn::EncodingBuffer& outBuffer)
{
size_t totalLength = 0;
for (int64_t i = 0; i < N; i++)
{
for (int64_t i = 0; i < N; i++) {
totalLength += prependNonNegativeIntegerBlock(outBuffer, ndn::tlv::Content, i);
}
}
m_totalPayloadLength += totalLength;
return totalLength;
}
@ -85,13 +89,13 @@ protected:
};
template<int64_t N>
class SegmentPublisherFixture
class SegmentPublisherFixture : public BaseFixture
{
public:
SegmentPublisherFixture()
: m_face(std::make_shared<ndn::util::DummyClientFace>())
: m_face(std::make_shared<ndn::util::DummyClientFace>(m_ioService, m_keyChain))
, m_expectedFreshnessPeriod(ndn::time::milliseconds(111))
, m_publisher(*m_face, m_keyChain, m_expectedFreshnessPeriod)
, m_publisher(*m_face, m_keyChain, m_signingInfo, m_expectedFreshnessPeriod)
, m_publishingPrefix("/localhost/nfd/SegmentPublisherFixture")
{
}
@ -106,10 +110,9 @@ public:
m_buffer.appendByteArray(payload.value(), payload.value_size());
// uint64_t segmentNo = data.getName()[-1].toSegment();
if (data.getFinalBlockId() != data.getName()[-1])
{
if (data.getFinalBlockId() != data.getName()[-1]) {
return;
}
}
// wrap data in a single Content TLV for easy parsing
m_buffer.prependVarNumber(m_buffer.size());
@ -138,7 +141,7 @@ protected:
const ndn::time::milliseconds m_expectedFreshnessPeriod;
TestSegmentPublisher<N> m_publisher;
ndn::EncodingBuffer m_buffer;
ndn::KeyChain m_keyChain;
ndn::security::SigningInfo m_signingInfo;
const ndn::Name m_publishingPrefix;
};

22
tests/security/test-certificate-store.cpp

@ -30,28 +30,20 @@ namespace security {
namespace test {
using std::shared_ptr;
using namespace nlsr::test;
class CertificateStoreFixture
class CertificateStoreFixture : public BaseFixture
{
public:
CertificateStoreFixture()
{
// Create certificate
ndn::Name identity("/TestNLSR/identity");
identity.appendVersion();
ndn::KeyChain keyChain;
keyChain.createIdentity(identity);
ndn::Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
certificate = keyChain.getCertificate(certName);
BOOST_REQUIRE(certificate != nullptr);
certificateKey = certificate->getName().getPrefix(-1);
auto identity = addIdentity("/TestNLSR/identity");
certificateKey = identity.getDefaultKey().getName();
certificate = identity.getDefaultKey().getDefaultCertificate();
}
public:
std::shared_ptr<ndn::IdentityCertificate> certificate;
ndn::security::v2::Certificate certificate;
ndn::Name certificateKey;
};
@ -64,7 +56,7 @@ BOOST_AUTO_TEST_CASE(Basic)
BOOST_REQUIRE(store.find(certificateKey) == nullptr);
store.insert(certificate);
BOOST_CHECK(*store.find(certificateKey) == *certificate);
BOOST_CHECK(*store.find(certificateKey) == certificate);
store.clear();
BOOST_REQUIRE(store.find(certificateKey) == nullptr);

2
tests/test-adjacency-list.cpp

@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(Basic)
BOOST_AUTO_TEST_CASE(findAdjacentByFaceUri)
{
ndn::util::FaceUri faceUri("udp4://10.0.0.1:6363");
ndn::FaceUri faceUri("udp4://10.0.0.1:6363");
Adjacent adj1("/ndn/test/1", faceUri, 10, Adjacent::STATUS_INACTIVE, 0, 0);
AdjacencyList adjList;
adjList.insert(adj1);

4
tests/test-adjacent.cpp

@ -34,7 +34,7 @@ BOOST_AUTO_TEST_SUITE(TestAdjacent)
BOOST_AUTO_TEST_CASE(OperatorEquals)
{
const ndn::Name ADJ_NAME_1 = "name1";
const ndn::util::FaceUri ADJ_URI_1 = ndn::util::FaceUri("udp4://10.0.0.1:8000");
const ndn::FaceUri ADJ_URI_1 = ndn::FaceUri("udp4://10.0.0.1:8000");
const double ADJ_LINK_COST_1 = 1;
Adjacent adjacent1(ADJ_NAME_1);
Adjacent adjacent2(ADJ_NAME_1);
@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(compareFaceUri)
{
const ndn::Name ADJ_NAME_1 = "name1";
const ndn::Name ADJ_NAME_2 = "name2";
const ndn::util::FaceUri ADJ_URI_1 = ndn::util::FaceUri("udp4://10.0.0.1:8000");
const ndn::FaceUri ADJ_URI_1 = ndn::FaceUri("udp4://10.0.0.1:8000");
Adjacent adjacent1(ADJ_NAME_1);
Adjacent adjacent2(ADJ_NAME_2);
adjacent1.setFaceUri(ADJ_URI_1);

8
tests/test-common.cpp

@ -35,7 +35,7 @@ signData(ndn::Data& data)
}
MockNfdMgmtFixture::MockNfdMgmtFixture()
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
: m_face(m_ioService, m_keyChain, {true, true})
{
}
@ -52,11 +52,11 @@ UnitTestTimeFixture::advanceClocks(const ndn::time::nanoseconds& tick, size_t nT
steadyClock->advance(tick);
systemClock->advance(tick);
if (g_ioService.stopped()) {
g_ioService.reset();
if (m_ioService.stopped()) {
m_ioService.reset();
}
g_ioService.poll();
m_ioService.poll();
}
}

20
tests/test-common.hpp

@ -23,6 +23,7 @@
#define NLSR_TEST_COMMON_HPP
#include "common.hpp"
#include "identity-management-fixture.hpp"
#include <boost/asio.hpp>
#include <boost/test/unit_test.hpp>
@ -50,18 +51,17 @@ signData(shared_ptr<ndn::Data> data)
return data;
}
class BaseFixture
class BaseFixture : public tests::IdentityManagementFixture
{
public:
BaseFixture()
: g_scheduler(g_ioService)
: m_scheduler(m_ioService)
{
}
protected:
boost::asio::io_service g_ioService;
ndn::Scheduler g_scheduler;
ndn::KeyChain g_keyChain;
boost::asio::io_service m_ioService;
ndn::Scheduler m_scheduler;
};
class UnitTestTimeFixture : public BaseFixture
@ -140,12 +140,12 @@ public:
// These warnings assist in debugging when nfdc does not receive StatusDataset.
// They usually indicate a misspelled prefix or incorrect timing in the test case.
if (face->sentInterests.empty()) {
if (m_face.sentInterests.empty()) {
BOOST_WARN_MESSAGE(false, "no Interest expressed");
}
else {
BOOST_WARN_MESSAGE(face->sentInterests.back().getName().isPrefixOf(name),
"last Interest " << face->sentInterests.back().getName() <<
BOOST_WARN_MESSAGE(m_face.sentInterests.back().getName().isPrefixOf(name),
"last Interest " << m_face.sentInterests.back().getName() <<
" cannot be satisfied by this Data " << name);
}
@ -153,14 +153,14 @@ public:
data->setFinalBlockId(name[-1]);
data->setContent(std::forward<ContentArgs>(contentArgs)...);
this->signDatasetReply(*data);
face->receive(*data);
m_face.receive(*data);
}
virtual void
signDatasetReply(ndn::Data& data);
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace m_face;
};
} // namespace test

101
tests/test-conf-file-processor.cpp

@ -25,6 +25,7 @@
#include "nlsr.hpp"
#include <fstream>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
@ -142,11 +143,11 @@ class ConfFileProcessorFixture : public BaseFixture
{
public:
ConfFileProcessorFixture()
: face(std::make_shared<ndn::util::DummyClientFace>())
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: face(m_ioService, m_keyChain)
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, CONFIG_FILE("unit-test-nlsr.conf")
, m_logConfigFileName(boost::filesystem::unique_path().native())
, m_logFileName(boost::filesystem::unique_path().native())
, m_logConfigFileName(boost::filesystem::unique_path().string())
, m_logFileName(boost::filesystem::unique_path().string())
{
}
@ -159,7 +160,8 @@ public:
boost::filesystem::remove(boost::filesystem::path(getLogFileName()));
}
bool processConfigurationString(std::string confString)
bool
processConfigurationString(std::string confString)
{
std::ofstream config;
config.open("unit-test-nlsr.conf");
@ -210,7 +212,7 @@ public:
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace face;
Nlsr nlsr;
private:
@ -498,64 +500,51 @@ BOOST_AUTO_TEST_CASE(NegativeValue)
BOOST_AUTO_TEST_CASE(LoadCertToPublish)
{
ndn::Name identity("/TestNLSR/identity");
identity.appendVersion();
ndn::KeyChain keyChain;
keyChain.createIdentity(identity);
ndn::Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
std::shared_ptr<ndn::IdentityCertificate> certificate = keyChain.getCertificate(certName);
const boost::filesystem::path CERT_PATH =
(boost::filesystem::current_path() / std::string("cert-to-publish.cert"));
ndn::io::save(*certificate, CERT_PATH.string());
const std::string SECTION_SECURITY =
"security\n"
"{\n"
" validator\n"
" {\n"
" trust-anchor\n"
" {\n"
" type any\n"
" }\n"
" }\n"
" prefix-update-validator\n"
" {\n"
" trust-anchor\n"
" {\n"
" type any\n"
" }\n"
" }\n"
" cert-to-publish \"cert-to-publish.cert\"\n"
"}\n\n";
auto identity = addIdentity("/TestNLSR/identity");
saveCertificate(identity, "cert-to-publish.cert");
const std::string SECTION_SECURITY = R"CONF(
security
{
validator
{
trust-anchor
{
type any
}
}
prefix-update-validator
{
trust-anchor
{
type any
}
}
cert-to-publish "cert-to-publish.cert"
}
)CONF";
BOOST_CHECK(processConfigurationString(SECTION_SECURITY));
// Certificate should now be in the CertificateStore
const security::CertificateStore& certStore = nlsr.getCertificateStore();
const ndn::Name certKey = certificate->getName().getPrefix(-1);
BOOST_CHECK(certStore.find(certKey) != nullptr);
// Cleanup
keyChain.deleteIdentity(identity);
boost::filesystem::remove(CERT_PATH);
security::CertificateStore& certStore = nlsr.getCertificateStore();
BOOST_CHECK(certStore.find(identity.getDefaultKey().getName()) != nullptr);
}
BOOST_AUTO_TEST_CASE(PrefixUpdateValidatorOptional) // Bug #2814
{
const std::string SECTION_SECURITY =
"security\n"
"{\n"
" validator\n"
" {\n"
" trust-anchor\n"
" {\n"
" type any\n"
" }\n"
" }\n"
"}\n\n";
const std::string SECTION_SECURITY = R"CONF(
security
{
validator
{
trust-anchor
{
type any
}
}
}
)CONF";
BOOST_CHECK(processConfigurationString(SECTION_SECURITY));
}

12
tests/test-fib.cpp

@ -36,24 +36,23 @@ class FibFixture : public UnitTestTimeFixture
{
public:
FibFixture()
: face(std::make_shared<ndn::util::DummyClientFace>())
: face(std::make_shared<ndn::util::DummyClientFace>(m_keyChain))
, interests(face->sentInterests)
{
INIT_LOGGERS("/tmp", "DEBUG");
Adjacent neighbor1(router1Name, ndn::util::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
Adjacent neighbor1(router1Name, ndn::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
adjacencies.insert(neighbor1);
Adjacent neighbor2(router2Name, ndn::util::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
Adjacent neighbor2(router2Name, ndn::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
adjacencies.insert(neighbor2);
Adjacent neighbor3(router3Name, ndn::util::FaceUri(router3FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
Adjacent neighbor3(router3Name, ndn::FaceUri(router3FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
adjacencies.insert(neighbor3);
conf.setMaxFacesPerPrefix(2);
fib = std::make_shared<Fib>(std::ref(*face), std::ref(g_scheduler), std::ref(adjacencies),
std::ref(conf), keyChain);
fib = std::make_shared<Fib>(*face, m_scheduler, adjacencies, conf, m_keyChain);
fib->m_faceMap.update(router1FaceUri, router1FaceId);
fib->m_faceMap.update(router2FaceUri, router2FaceId);
@ -62,7 +61,6 @@ public:
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::KeyChain keyChain;
std::shared_ptr<Fib> fib;
AdjacencyList adjacencies;

132
tests/test-home-fixture.hpp

@ -0,0 +1,132 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, 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 NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NLSR_TEST_HOME_FIXTURE_HPP
#define NLSR_TEST_HOME_FIXTURE_HPP
#include "boost-test.hpp"
#include <fstream>
#include <ndn-cxx/security/v2/key-chain.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
namespace nlsr {
namespace tests {
/**
* @brief Fixture to adjust/restore NDN_CLIENT_PIB and NDN_CLIENT_TPM paths
*
* Note that the specified PATH will be removed after fixture is destroyed.
* **Do not specify non-temporary paths.**
*/
template<class Path>
class PibDirFixture
{
public:
PibDirFixture()
: m_pibDir(Path().PATH)
{
if (getenv("NDN_CLIENT_PIB") != nullptr) {
m_oldPib = getenv("NDN_CLIENT_PIB");
}
if (getenv("NDN_CLIENT_TPM") != nullptr) {
m_oldTpm = getenv("NDN_CLIENT_TPM");
}
/// @todo Consider change to an in-memory PIB/TPM
setenv("NDN_CLIENT_PIB", ("pib-sqlite3:" + m_pibDir).c_str(), true);
setenv("NDN_CLIENT_TPM", ("tpm-file:" + m_pibDir).c_str(), true);
}
~PibDirFixture()
{
if (!m_oldPib.empty()) {
setenv("NDN_CLIENT_PIB", m_oldPib.c_str(), true);
}
else {
unsetenv("NDN_CLIENT_PIB");
}
if (!m_oldTpm.empty()) {
setenv("NDN_CLIENT_TPM", m_oldTpm.c_str(), true);
}
else {
unsetenv("NDN_CLIENT_TPM");
}
boost::filesystem::remove_all(m_pibDir);
//const_cast<std::string&>(ndn::security::v2::KeyChain::getDefaultPibLocator()).clear();
//const_cast<std::string&>(ndn::security::v2::KeyChain::getDefaultTpmLocator()).clear();
}
protected:
const std::string m_pibDir;
private:
std::string m_oldPib;
std::string m_oldTpm;
};
/**
* @brief Extension of PibDirFixture to set TEST_HOME variable and allow config file creation
*/
template<class Path>
class TestHomeFixture : public PibDirFixture<Path>
{
public:
TestHomeFixture()
{
setenv("TEST_HOME", this->m_pibDir.c_str(), true);
}
~TestHomeFixture()
{
unsetenv("TEST_HOME");
}
void
createClientConf(std::initializer_list<std::string> lines)
{
boost::filesystem::create_directories(boost::filesystem::path(this->m_pibDir) / ".ndn");
std::ofstream of((boost::filesystem::path(this->m_pibDir) / ".ndn" / "client.conf").c_str());
for (auto line : lines) {
boost::replace_all(line, "%PATH%", this->m_pibDir);
of << line << std::endl;
}
}
};
struct DefaultPibDir
{
const std::string PATH = "build/keys";
};
} // namespace tests
} // namespace nlsr
#endif // NLSR_TEST_HOME_FIXTURE_HPP

12
tests/test-hyperbolic-calculator.cpp

@ -45,8 +45,8 @@ class HyperbolicCalculatorFixture : public BaseFixture
{
public:
HyperbolicCalculatorFixture()
: face(std::make_shared<ndn::util::DummyClientFace>())
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: face(m_ioService, m_keyChain)
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, routingTable(nlsr.getRoutingTable())
, adjacencies(nlsr.getAdjacencyList())
, lsdb(nlsr.getLsdb())
@ -59,9 +59,9 @@ public:
{
INIT_LOGGERS("/tmp", "TRACE");
Adjacent a(ROUTER_A_NAME, ndn::util::FaceUri(ROUTER_A_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent b(ROUTER_B_NAME, ndn::util::FaceUri(ROUTER_B_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent c(ROUTER_C_NAME, ndn::util::FaceUri(ROUTER_C_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent a(ROUTER_A_NAME, ndn::FaceUri(ROUTER_A_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent b(ROUTER_B_NAME, ndn::FaceUri(ROUTER_B_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent c(ROUTER_C_NAME, ndn::FaceUri(ROUTER_C_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
// Router A
adjacencies.insert(b);
@ -149,7 +149,7 @@ public:
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace face;
Nlsr nlsr;
Map map;

12
tests/test-link-state-calculator.cpp

@ -41,8 +41,8 @@ class LinkStateCalculatorFixture : public BaseFixture
{
public:
LinkStateCalculatorFixture()
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: face(m_ioService, m_keyChain)
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, routingTable(nlsr.getRoutingTable())
, lsdb(nlsr.getLsdb())
{
@ -60,9 +60,9 @@ public:
conf.setRouterName("/a");
conf.buildRouterPrefix();
Adjacent a(ROUTER_A_NAME, ndn::util::FaceUri(ROUTER_A_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent b(ROUTER_B_NAME, ndn::util::FaceUri(ROUTER_B_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent c(ROUTER_C_NAME, ndn::util::FaceUri(ROUTER_C_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent a(ROUTER_A_NAME, ndn::FaceUri(ROUTER_A_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent b(ROUTER_B_NAME, ndn::FaceUri(ROUTER_B_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent c(ROUTER_C_NAME, ndn::FaceUri(ROUTER_C_FACE), 0, Adjacent::STATUS_ACTIVE, 0, 0);
// Router A
b.setLinkCost(LINK_AB_COST);
@ -101,7 +101,7 @@ public:
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace face;
Nlsr nlsr;
Map map;

153
tests/test-lsa-rule.cpp

@ -37,38 +37,32 @@ using namespace ndn;
namespace nlsr {
namespace test {
class LsaRuleFixture : public nlsr::test::BaseFixture
class LsaRuleFixture : public nlsr::test::UnitTestTimeFixture
{
public:
LsaRuleFixture()
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
, rootId(ndn::Name("ndn"))
, siteIdentity(ndn::Name("/ndn/edu/test-site"))
, opIdentity(ndn::Name(siteIdentity).append(ndn::Name("%C1.Operator/op1")))
, routerId(ndn::Name("/ndn/edu/test-site/%C1.Router/router1"))
, nlsr(g_ioService, g_scheduler, *face, g_keyChain)
: face(m_ioService, m_keyChain, {true, true})
, rootIdName("/ndn")
, siteIdentityName("/ndn/edu/test-site")
, opIdentityName("/ndn/edu/test-site/%C1.Operator/op1")
, routerIdName("/ndn/edu/test-site/%C1.Router/router1")
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, ROOT_CERT_PATH(boost::filesystem::current_path() / std::string("root.cert"))
{
try {
keyChain.deleteIdentity(rootId);
keyChain.deleteIdentity(siteIdentity);
keyChain.deleteIdentity(opIdentity);
keyChain.deleteIdentity(routerId);
}
catch (const std::exception& e) {
}
createCert(rootId, rootCertName, rootCert, rootId);
BOOST_REQUIRE(rootCert != nullptr);
rootId = addIdentity(rootIdName);
siteIdentity = addSubCertificate(siteIdentityName, rootId);
opIdentity = addSubCertificate(opIdentityName, siteIdentity);
routerId = addSubCertificate(routerIdName, opIdentity);
createCert(siteIdentity, siteCertName, siteCert, rootId);
BOOST_REQUIRE(siteCert != nullptr);
saveCertificate(rootId, ROOT_CERT_PATH.string());
createCert(opIdentity, opCertName, opCert, siteIdentity);
BOOST_REQUIRE(opCert != nullptr);
createCert(routerId, routerCertName, routerCert, opIdentity);
BOOST_REQUIRE(routerCert != nullptr);
auto load = [this] (const ndn::security::Identity& id) {
nlsr.loadCertToPublish(id.getDefaultKey().getDefaultCertificate());
};
load(rootId);
load(siteIdentity);
load(opIdentity);
load(routerId);
// Loading the security section's validator part into the validator
// See conf file processor for more details
@ -99,97 +93,52 @@ public:
// Initialize NLSR to initialize the keyChain
nlsr.initialize();
}
void
createCert(ndn::Name& identity, ndn::Name& certName, std::shared_ptr<IdentityCertificate>& cert, const ndn::Name& signer)
{
ndn::Name keyName = keyChain.generateRsaKeyPairAsDefault(identity, true);
this->advanceClocks(ndn::time::milliseconds(10));
cert = std::make_shared<ndn::IdentityCertificate>();
std::shared_ptr<ndn::PublicKey> pubKey = keyChain.getPublicKey(keyName);
certName = keyName.getPrefix(-1);
certName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
cert->setName(certName);
cert->setNotBefore(time::system_clock::now() - time::days(1));
cert->setNotAfter(time::system_clock::now() + time::days(1));
cert->setPublicKeyInfo(*pubKey);
cert->addSubjectDescription(CertificateSubjectDescription(ndn::oid::ATTRIBUTE_NAME,
keyName.toUri()));
cert->encode();
// root is self signed and root.cert is saved
if (signer == identity) {
keyChain.selfSign(*cert);
keyChain.addCertificateAsIdentityDefault(*cert);
nlsr.loadCertToPublish(cert);
ndn::io::save(*cert, ROOT_CERT_PATH.string());
}
else {
ndn::security::SigningInfo signingInfo;
signingInfo.setSigningIdentity(signer);
keyChain.sign(*cert, signingInfo);
keyChain.addCertificateAsIdentityDefault(*cert);
nlsr.loadCertToPublish(cert);
}
}
~LsaRuleFixture()
{
keyChain.deleteIdentity(rootId);
keyChain.deleteIdentity(siteIdentity);
keyChain.deleteIdentity(opIdentity);
keyChain.deleteIdentity(routerId);
boost::filesystem::remove(ROOT_CERT_PATH);
}
face.sentInterests.clear();
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::KeyChain keyChain;
ndn::util::DummyClientFace face;
ndn::Name rootId, siteIdentity, opIdentity, routerId;
ndn::Name rootCertName, siteCertName, opCertName, routerCertName;
std::shared_ptr<IdentityCertificate> rootCert, siteCert, opCert, routerCert;
ndn::Name rootIdName, siteIdentityName, opIdentityName, routerIdName;
ndn::security::pib::Identity rootId, siteIdentity, opIdentity, routerId;
Nlsr nlsr;
const boost::filesystem::path ROOT_CERT_PATH;
//std::function<void(const ndn::Interest& interest)> processInterest;
};
BOOST_FIXTURE_TEST_SUITE(TestLsaDataValidation, LsaRuleFixture)
BOOST_AUTO_TEST_CASE(ValidateCorrectLSA)
{
ndn::Name lsaInterestName = nlsr.getConfParameter().getLsaPrefix();
lsaInterestName.append(nlsr.getConfParameter().getSiteName());
lsaInterestName.append(nlsr.getConfParameter().getRouterName());
ndn::Name lsaDataName = nlsr.getConfParameter().getLsaPrefix();
lsaDataName.append(nlsr.getConfParameter().getSiteName());
lsaDataName.append(nlsr.getConfParameter().getRouterName());
// Append LSA type
lsaInterestName.append(std::to_string(Lsa::Type::NAME));
lsaDataName.append(std::to_string(Lsa::Type::NAME));
// This would be the sequence number of its own NameLsa
lsaInterestName.appendNumber(nlsr.getLsdb().getSequencingManager().getNameLsaSeq());
lsaDataName.appendNumber(nlsr.getLsdb().getSequencingManager().getNameLsaSeq());
// Append version, segmentNo
lsaInterestName.appendNumber(1).appendNumber(1);
lsaDataName.appendNumber(1).appendNumber(1);
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
data->setName(lsaInterestName);
data->setFreshnessPeriod(ndn::time::seconds(10));
ndn::Data data(lsaDataName);
data.setFreshnessPeriod(ndn::time::seconds(10));
// Sign data with NLSR's key
nlsr.getKeyChain().sign(*data, ndn::security::signingByCertificate(nlsr.getDefaultCertName()));
nlsr.getKeyChain().sign(data, nlsr.getSigningInfo());
// Make NLSR validate data signed by its own key
nlsr.getValidator().validate(*data,
[] (const std::shared_ptr<const Data>&) { BOOST_CHECK(true); },
[] (const std::shared_ptr<const Data>&, const std::string&) {
nlsr.getValidator().validate(data,
[] (const Data&) { BOOST_CHECK(true); },
[] (const Data&, const ndn::security::v2::ValidationError&) {
BOOST_CHECK(false);
});
}
@ -197,28 +146,26 @@ BOOST_AUTO_TEST_CASE(ValidateCorrectLSA)
BOOST_AUTO_TEST_CASE(DoNotValidateIncorrectLSA)
{
// getSubName removes the /localhop compnonent from /localhop/ndn/NLSR/LSA
ndn::Name lsaInterestName = nlsr.getConfParameter().getLsaPrefix().getSubName(1);
lsaInterestName.append(nlsr.getConfParameter().getSiteName());
lsaInterestName.append(nlsr.getConfParameter().getRouterName());
ndn::Name lsaDataName = nlsr.getConfParameter().getLsaPrefix().getSubName(1);
lsaDataName.append(nlsr.getConfParameter().getSiteName());
lsaDataName.append(nlsr.getConfParameter().getRouterName());
// Append LSA type
lsaInterestName.append(std::to_string(Lsa::Type::NAME));
lsaDataName.append(std::to_string(Lsa::Type::NAME));
// This would be the sequence number of its own NameLsa
lsaInterestName.appendNumber(nlsr.getLsdb().getSequencingManager().getNameLsaSeq());
lsaDataName.appendNumber(nlsr.getLsdb().getSequencingManager().getNameLsaSeq());
// Append version, segmentNo
lsaInterestName.appendNumber(1).appendNumber(1);
lsaDataName.appendNumber(1).appendNumber(1);
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
data->setName(lsaInterestName);
data->setFreshnessPeriod(ndn::time::seconds(10));
nlsr.getKeyChain().sign(*data, ndn::security::signingByCertificate(nlsr.getDefaultCertName()));
ndn::Data data(lsaDataName);
data.setFreshnessPeriod(ndn::time::seconds(10));
// Make NLSR validate data signed by its own key
nlsr.getValidator().validate(*data,
[] (const std::shared_ptr<const Data>&) { BOOST_CHECK(false); },
[] (const std::shared_ptr<const Data>&, const std::string&) {
nlsr.getValidator().validate(data,
[] (const Data&) { BOOST_CHECK(false); },
[] (const Data&, const ndn::security::v2::ValidationError&) {
BOOST_CHECK(true);
});
}

6
tests/test-lsa.cpp

@ -161,9 +161,9 @@ BOOST_AUTO_TEST_CASE(TestInitializeFromContent)
//If we don't do this the test will fail
//Adjacent has default cost of 10 but no default
//connecting face URI, so deserialize fails
adj1.setFaceUri(ndn::util::FaceUri("udp://10.0.0.1"));
adj2.setFaceUri(ndn::util::FaceUri("udp://10.0.0.2"));
//connecting face URI, so initializeFromContent fails
adj1.setFaceUri(ndn::FaceUri("udp://10.0.0.1"));
adj2.setFaceUri(ndn::FaceUri("udp://10.0.0.2"));
AdjacencyList adjList;
adjList.insert(adj1);

43
tests/test-lsdb.cpp

@ -29,17 +29,19 @@
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <unistd.h>
namespace nlsr {
namespace test {
using std::shared_ptr;
class LsdbFixture : public BaseFixture
class LsdbFixture : public UnitTestTimeFixture
{
public:
LsdbFixture()
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: face(m_ioService, m_keyChain)
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, lsdb(nlsr.getLsdb())
, conf(nlsr.getConfParameter())
, REGISTER_COMMAND_PREFIX("/localhost/nfd/rib")
@ -47,12 +49,14 @@ public:
{
conf.setNetwork("/ndn");
conf.setSiteName("/site");
conf.setRouterName("/%C1.router/this-router");
conf.setRouterName("/%C1.Router/this-router");
addIdentity("/ndn/site/%C1.Router/this-router");
nlsr.initialize();
face->processEvents(ndn::time::milliseconds(1));
face->sentInterests.clear();
advanceClocks(ndn::time::milliseconds(1), 10);
face.sentInterests.clear();
INIT_LOGGERS("/tmp", "DEBUG");
}
@ -89,7 +93,7 @@ public:
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace face;
Nlsr nlsr;
Lsdb& lsdb;
ConfParameter& conf;
@ -109,9 +113,9 @@ BOOST_AUTO_TEST_CASE(LsdbSync)
oldInterestName.appendNumber(oldSeqNo);
lsdb.expressInterest(oldInterestName, 0);
face->processEvents(ndn::time::milliseconds(1));
advanceClocks(ndn::time::milliseconds(1), 10);
std::vector<ndn::Interest>& interests = face->sentInterests;
std::vector<ndn::Interest>& interests = face.sentInterests;
BOOST_REQUIRE(interests.size() > 0);
@ -129,7 +133,7 @@ BOOST_AUTO_TEST_CASE(LsdbSync)
// Simulate an LSA interest timeout
lsdb.onFetchLsaError(ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT, "Timeout",
oldInterestName, 0, deadline, interestName, oldSeqNo);
face->processEvents(ndn::time::milliseconds(1));
advanceClocks(ndn::time::milliseconds(1), 10);
BOOST_REQUIRE(interests.size() > 0);
@ -147,7 +151,7 @@ BOOST_AUTO_TEST_CASE(LsdbSync)
newInterestName.appendNumber(newSeqNo);
lsdb.expressInterest(newInterestName, 0);
face->processEvents(ndn::time::milliseconds(1));
advanceClocks(ndn::time::milliseconds(1), 10);
BOOST_REQUIRE(interests.size() > 0);
@ -163,7 +167,7 @@ BOOST_AUTO_TEST_CASE(LsdbSync)
// Simulate an LSA interest timeout where the sequence number is outdated
lsdb.onFetchLsaError(ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT, "Timeout",
oldInterestName, 0, deadline, interestName, oldSeqNo);
face->processEvents(ndn::time::milliseconds(1));
advanceClocks(ndn::time::milliseconds(1), 10);
// Interest should not be expressed for outdated sequence number
BOOST_CHECK_EQUAL(interests.size(), 0);
@ -191,18 +195,21 @@ BOOST_AUTO_TEST_CASE(SegmentLsaData)
interestName.appendNumber(seqNo);
ndn::Interest interest(interestName);
lsdb.processInterest(ndn::Name(), interest);
advanceClocks(ndn::time::milliseconds(1), 10);
face.sentData.clear();
lsdb.processInterest(ndn::Name(), interest);
face->processEvents(ndn::time::milliseconds(1));
std::vector<ndn::Data> data = face->sentData;
advanceClocks(ndn::time::milliseconds(1), 10);
std::string recvDataContent;
for (unsigned int i = 0; i < data.size(); ++i)
for (const ndn::Data& data : face.sentData)
{
const ndn::Block& nameBlock = data[i].getContent();
const ndn::Block& nameBlock = data.getContent();
std::string nameBlockContent(reinterpret_cast<char const*>(nameBlock.value()),
nameBlock.value_size());
recvDataContent += nameBlockContent;
}
@ -253,7 +260,7 @@ BOOST_AUTO_TEST_CASE(LsdbRemoveAndExists)
//1800 is the default life time.
NameLsa nlsa1(ndn::Name("/router1/1"), 12, testTimePoint, npl1);
Lsdb lsdb1(nlsr, g_scheduler);
Lsdb lsdb1(nlsr, m_scheduler);
lsdb1.installNameLsa(nlsa1);
lsdb1.writeNameLsdbLog();

10
tests/test-name-prefix-table.cpp

@ -32,8 +32,8 @@ class NamePrefixTableFixture : public UnitTestTimeFixture
{
public:
NamePrefixTableFixture()
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: face(m_ioService, m_keyChain)
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, lsdb(nlsr.getLsdb())
, npt(nlsr.getNamePrefixTable())
{
@ -41,7 +41,7 @@ public:
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace face;
Nlsr nlsr;
Lsdb& lsdb;
@ -63,10 +63,10 @@ BOOST_FIXTURE_TEST_CASE(Bupt, NamePrefixTableFixture)
NamePrefixTable& npt = nlsr.getNamePrefixTable();
Adjacent thisRouter(conf.getRouterPrefix(), ndn::util::FaceUri("udp4://10.0.0.1"), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent thisRouter(conf.getRouterPrefix(), ndn::FaceUri("udp4://10.0.0.1"), 0, Adjacent::STATUS_ACTIVE, 0, 0);
ndn::Name buptRouterName("/ndn/cn/edu/bupt/%C1.Router/bupthub");
Adjacent bupt(buptRouterName, ndn::util::FaceUri("udp4://10.0.0.2"), 0, Adjacent::STATUS_ACTIVE, 0, 0);
Adjacent bupt(buptRouterName, ndn::FaceUri("udp4://10.0.0.2"), 0, Adjacent::STATUS_ACTIVE, 0, 0);
// This router's Adjacency LSA
nlsr.getAdjacencyList().insert(bupt);

197
tests/test-nlsr.cpp

@ -35,12 +35,18 @@ class NlsrFixture : public MockNfdMgmtFixture
{
public:
NlsrFixture()
: nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: nlsr(m_ioService, m_scheduler, m_face, m_keyChain)
, lsdb(nlsr.getLsdb())
, neighbors(nlsr.getAdjacencyList())
, nSuccessCallbacks(0)
, nFailureCallbacks(0)
{
nlsr.getConfParameter().setNetwork("/ndn");
nlsr.getConfParameter().setSiteName("/site");
nlsr.getConfParameter().setRouterName("/%C1.Router/this-router");
nlsr.getConfParameter().buildRouterPrefix();
addIdentity(nlsr.getConfParameter().getRouterPrefix());
}
void
@ -49,10 +55,10 @@ public:
ndn::Name dataName(sender);
dataName.append("NLSR").append("INFO").append(receiver.wireEncode()).appendVersion();
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(dataName);
ndn::Data data(dataName);
nlsr.m_helloProtocol.onContentValidated(data);
}
}
public:
Nlsr nlsr;
@ -60,7 +66,6 @@ public:
AdjacencyList& neighbors;
uint32_t nSuccessCallbacks;
uint32_t nFailureCallbacks;
};
BOOST_FIXTURE_TEST_SUITE(TestNlsr, NlsrFixture)
@ -68,20 +73,19 @@ BOOST_FIXTURE_TEST_SUITE(TestNlsr, NlsrFixture)
BOOST_AUTO_TEST_CASE(HyperbolicOn_ZeroCostNeighbors)
{
// Simulate loading configuration file
Adjacent neighborA("/ndn/neighborA", ndn::util::FaceUri("udp4://10.0.0.1"), 25,
Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"), 25,
Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborA);
Adjacent neighborB("/ndn/neighborB", ndn::util::FaceUri("udp4://10.0.0.2"), 10,
Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"), 10,
Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborB);
Adjacent neighborC("/ndn/neighborC", ndn::util::FaceUri("udp4://10.0.0.3"), 17,
Adjacent neighborC("/ndn/neighborC", ndn::FaceUri("udp4://10.0.0.3"), 17,
Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborC);
nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
nlsr.getConfParameter().setNetwork(ndn::Name("/test"));
nlsr.initialize();
@ -94,15 +98,15 @@ BOOST_AUTO_TEST_CASE(HyperbolicOn_ZeroCostNeighbors)
BOOST_AUTO_TEST_CASE(HyperbolicOff_LinkStateCost)
{
// Simulate loading configuration file
Adjacent neighborA("/ndn/neighborA", ndn::util::FaceUri("udp4://10.0.0.1"), 25,
Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"), 25,
Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborA);
Adjacent neighborB("/ndn/neighborB", ndn::util::FaceUri("udp4://10.0.0.2"), 10,
Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"), 10,
Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborB);
Adjacent neighborC("/ndn/neighborC", ndn::util::FaceUri("udp4://10.0.0.3"), 17,
Adjacent neighborC("/ndn/neighborC", ndn::FaceUri("udp4://10.0.0.3"), 17,
Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborC);
@ -137,11 +141,13 @@ BOOST_AUTO_TEST_CASE(FaceCreateEvent)
// Setting constants for the unit test
const uint32_t faceId = 1;
const std::string faceUri = "udp4://10.0.0.1:6363";
Adjacent neighbor("/ndn/neighborA", ndn::util::FaceUri(faceUri), 10,
Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
Adjacent::STATUS_INACTIVE, 0, 0);
BOOST_REQUIRE_EQUAL(nlsr.getAdjacencyList().insert(neighbor), 0);
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
// Build, sign, and send the Face Event
ndn::nfd::FaceEventNotification event;
@ -151,14 +157,14 @@ BOOST_AUTO_TEST_CASE(FaceCreateEvent)
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
data->setContent(event.wireEncode());
nlsr.getKeyChain().sign(*data);
face->receive(*data);
m_face.receive(*data);
// Move the clocks forward so that the Face processes the event.
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
// Need to explicitly provide a FaceUri object, because the
// conversion will attempt to create Name objects.
auto iterator = nlsr.getAdjacencyList().findAdjacent(ndn::util::FaceUri(faceUri));
auto iterator = nlsr.getAdjacencyList().findAdjacent(ndn::FaceUri(faceUri));
BOOST_REQUIRE(iterator != nlsr.getAdjacencyList().end());
BOOST_CHECK_EQUAL(iterator->getFaceId(), faceId);
}
@ -169,8 +175,10 @@ BOOST_AUTO_TEST_CASE(FaceCreateEventNoMatch)
const uint32_t faceId = 1;
const std::string eventUri = "udp4://10.0.0.1:6363";
const std::string neighborUri = "udp4://10.0.0.2:6363";
Adjacent neighbor("/ndn/neighborA", ndn::util::FaceUri(neighborUri), 10,
Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(neighborUri), 10,
Adjacent::STATUS_INACTIVE, 0, 0);
nlsr.getAdjacencyList().insert(neighbor);
// Build, sign, and send the Face Event
@ -181,13 +189,13 @@ BOOST_AUTO_TEST_CASE(FaceCreateEventNoMatch)
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
data->setContent(event.wireEncode());
nlsr.getKeyChain().sign(*data);
face->receive(*data);
m_face.receive(*data);
// Move the clocks forward so that the Face processes the event.
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
// The Face URIs did not match, so this neighbor should be unconfigured.
auto iterator = nlsr.getAdjacencyList().findAdjacent(ndn::util::FaceUri(neighborUri));
auto iterator = nlsr.getAdjacencyList().findAdjacent(ndn::FaceUri(neighborUri));
BOOST_REQUIRE(iterator != nlsr.getAdjacencyList().end());
BOOST_CHECK_EQUAL(iterator->getFaceId(), 0);
}
@ -198,7 +206,8 @@ BOOST_AUTO_TEST_CASE(FaceCreateEventAlreadyConfigured)
const uint32_t eventFaceId = 1;
const uint32_t neighborFaceId = 2;
const std::string faceUri = "udp4://10.0.0.1:6363";
Adjacent neighbor("/ndn/neighborA", ndn::util::FaceUri(faceUri), 10,
Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
Adjacent::STATUS_ACTIVE, 0, neighborFaceId);
nlsr.getAdjacencyList().insert(neighbor);
@ -210,29 +219,22 @@ BOOST_AUTO_TEST_CASE(FaceCreateEventAlreadyConfigured)
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
data->setContent(event.wireEncode());
nlsr.getKeyChain().sign(*data);
face->receive(*data);
m_face.receive(*data);
// Move the clocks forward so that the Face processes the event.
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
// Since the neighbor was already configured, this (simply erroneous) event should have no effect.
auto iterator = nlsr.getAdjacencyList().findAdjacent(ndn::util::FaceUri(faceUri));
auto iterator = nlsr.getAdjacencyList().findAdjacent(ndn::FaceUri(faceUri));
BOOST_REQUIRE(iterator != nlsr.getAdjacencyList().end());
BOOST_CHECK_EQUAL(iterator->getFaceId(), neighborFaceId);
}
BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
BOOST_AUTO_TEST_CASE(FaceDestroyEvent)
{
std::shared_ptr<ndn::util::DummyClientFace> face =
std::make_shared<ndn::util::DummyClientFace>(g_ioService);
Nlsr nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain);
Lsdb& lsdb = nlsr.getLsdb();
// Simulate loading configuration file
ConfParameter& conf = nlsr.getConfParameter();
conf.setNetwork("/ndn");
conf.setSiteName("/site");
conf.setRouterName("/%C1.router/this-router");
conf.setAdjLsaBuildInterval(0);
conf.setRoutingCalcInterval(0);
@ -241,13 +243,13 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
uint64_t destroyFaceId = 128;
// Create a neighbor whose Face will be destroyed
Adjacent failNeighbor("/ndn/neighborA", ndn::util::FaceUri("udp4://10.0.0.1"), 10, Adjacent::STATUS_ACTIVE, 0,
destroyFaceId);
Adjacent failNeighbor("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"),
10, Adjacent::STATUS_ACTIVE, 0, destroyFaceId);
neighbors.insert(failNeighbor);
// Create an additional neighbor so an adjacency LSA can be built after the face is destroyed
Adjacent otherNeighbor("/ndn/neighborB", ndn::util::FaceUri("udp4://10.0.0.2"), 10,
Adjacent::STATUS_ACTIVE, 0, 256);
Adjacent otherNeighbor("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"),
10, Adjacent::STATUS_ACTIVE, 0, 256);
neighbors.insert(otherNeighbor);
nlsr.initialize();
@ -257,10 +259,11 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
// Set up adjacency LSAs
// This router
Adjacent thisRouter(conf.getRouterPrefix(), ndn::util::FaceUri("udp4://10.0.0.3"), 10,
Adjacent::STATUS_ACTIVE, 0, 256);
Adjacent thisRouter(conf.getRouterPrefix(), ndn::FaceUri("udp4://10.0.0.3"),
10, Adjacent::STATUS_ACTIVE, 0, 256);
AdjLsa ownAdjLsa(conf.getRouterPrefix(), 10, ndn::time::system_clock::now(), 1, neighbors);
AdjLsa ownAdjLsa(conf.getRouterPrefix(), 10,
ndn::time::system_clock::now(), 1, neighbors);
lsdb.installAdjLsa(ownAdjLsa);
// Router that will fail
@ -268,7 +271,8 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
failAdjacencies.insert(thisRouter);
AdjLsa failAdjLsa("/ndn/neighborA", 10,
ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, failAdjacencies);
ndn::time::system_clock::now() + ndn::time::seconds(3600),
1, failAdjacencies);
lsdb.installAdjLsa(failAdjLsa);
@ -277,12 +281,13 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
otherAdjacencies.insert(thisRouter);
AdjLsa otherAdjLsa("/ndn/neighborB", 10,
ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, otherAdjacencies);
ndn::time::system_clock::now() + ndn::time::seconds(3600),
1, otherAdjacencies);
lsdb.installAdjLsa(otherAdjLsa);
// Run the scheduler to build an adjacency LSA
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
// Make sure an adjacency LSA was built
ndn::Name key = ndn::Name(nlsr.getConfParameter().getRouterPrefix())
@ -307,10 +312,10 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
data->setContent(event.wireEncode());
nlsr.getKeyChain().sign(*data);
face->receive(*data);
m_face.receive(*data);
// Run the scheduler to build an adjacency LSA
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
Adjacent updatedNeighbor = neighbors.getAdjacent(failNeighbor.getName());
@ -332,15 +337,16 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
BOOST_AUTO_TEST_CASE(GetCertificate)
{
// Create certificate
ndn::Name identity("/TestNLSR/identity");
identity.appendVersion();
ndn::Name identityName("/TestNLSR/identity");
identityName.appendVersion();
ndn::security::pib::Identity identity = nlsr.getKeyChain().
createIdentity(identityName);
ndn::KeyChain keyChain;
keyChain.createIdentity(identity);
ndn::Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
std::shared_ptr<ndn::IdentityCertificate> certificate = keyChain.getCertificate(certName);
ndn::security::v2::Certificate certificate =
identity.getDefaultKey().getDefaultCertificate();
const ndn::Name certKey = certificate->getName().getPrefix(-1);
const ndn::Name certKey = certificate.getKeyName();
BOOST_CHECK(nlsr.getCertificate(certKey) == nullptr);
@ -350,59 +356,44 @@ BOOST_AUTO_TEST_CASE(GetCertificate)
BOOST_CHECK(nlsr.getCertificate(certKey) != nullptr);
nlsr.getCertificateStore().clear();
// Certificate should be retrievable from the cache
nlsr.addCertificateToCache(certificate);
this->advanceClocks(ndn::time::milliseconds(10));
BOOST_CHECK(nlsr.getCertificate(certKey) != nullptr);
}
BOOST_AUTO_TEST_CASE(SetRouterCommandPrefix)
{
// Simulate loading configuration file
ConfParameter& conf = nlsr.getConfParameter();
conf.setNetwork("/ndn");
conf.setSiteName("/site");
conf.setRouterName("/%C1.router/this-router");
nlsr.initialize();
BOOST_CHECK_EQUAL(nlsr.getLsdbDatasetHandler().getRouterNameCommandPrefix(),
ndn::Name("/ndn/site/%C1.router/this-router/lsdb"));
ndn::Name("/ndn/site/%C1.Router/this-router/lsdb"));
}
BOOST_AUTO_TEST_CASE(BuildAdjLsaAfterHelloResponse)
{
// Configure NLSR
ConfParameter& conf = nlsr.getConfParameter();
conf.setNetwork("/ndn");
conf.setSiteName("/site");
ndn::Name routerName("/%C1.Router/this-router");
conf.setRouterName(routerName);
conf.setAdjLsaBuildInterval(1);
// Add neighbors
// Router A
ndn::Name neighborAName("/ndn/site/%C1.router/routerA");
Adjacent neighborA(neighborAName, ndn::util::FaceUri("udp4://10.0.0.1"), 0,
Adjacent::STATUS_INACTIVE, 0, 0);
ndn::Name neighborAName("/ndn/site/%C1.Router/routerA");
Adjacent neighborA(neighborAName, ndn::FaceUri("udp4://10.0.0.1"),
0, Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborA);
// Router B
ndn::Name neighborBName("/ndn/site/%C1.router/routerB");
Adjacent neighborB(neighborBName, ndn::util::FaceUri("udp4://10.0.0.1"), 0,
Adjacent::STATUS_INACTIVE, 0, 0);
ndn::Name neighborBName("/ndn/site/%C1.Router/routerB");
Adjacent neighborB(neighborBName, ndn::FaceUri("udp4://10.0.0.1"),
0, Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborB);
nlsr.initialize();
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
// Receive HELLO response from Router A
receiveHelloData(neighborAName, conf.getRouterPrefix());
this->advanceClocks(ndn::time::seconds(1));
this->advanceClocks(ndn::time::seconds(1), 10);
ndn::Name lsaKey = ndn::Name(conf.getRouterPrefix()).append(std::to_string(Lsa::Type::ADJACENCY));
@ -420,17 +411,17 @@ BOOST_AUTO_TEST_CASE(BuildAdjLsaAfterHelloResponse)
adjacency.setInterestTimedOutNo(HELLO_RETRIES_DEFAULT);
}
this->advanceClocks(ndn::time::seconds(1));
this->advanceClocks(ndn::time::seconds(1), 10);
// Adjacency LSA should have been removed since this router's adjacencies are INACTIVE
// and have timed out
// Adjacency LSA should have been removed since this router's adjacencies are
// INACTIVE and have timed out
lsa = lsdb.findAdjLsa(lsaKey);
BOOST_CHECK(lsa == nullptr);
// Receive HELLO response from Router A and B
receiveHelloData(neighborAName, conf.getRouterPrefix());
receiveHelloData(neighborBName, conf.getRouterPrefix());
this->advanceClocks(ndn::time::seconds(1));
this->advanceClocks(ndn::time::seconds(1), 10);
// Adjacency LSA should be built
lsa = lsdb.findAdjLsa(lsaKey);
@ -440,13 +431,13 @@ BOOST_AUTO_TEST_CASE(BuildAdjLsaAfterHelloResponse)
BOOST_AUTO_TEST_CASE(CanonizeUris)
{
ndn::Name neighborAName("/ndn/site/%C1.router/routerA");
ndn::util::FaceUri faceUriA("udp://10.0.0.1");
ndn::Name neighborAName("/ndn/site/%C1.Router/routerA");
ndn::FaceUri faceUriA("udp://10.0.0.1");
Adjacent neighborA(neighborAName, faceUriA, 0, Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborA);
ndn::Name neighborBName("/ndn/site/%C1.router/routerB");
ndn::util::FaceUri faceUriB("udp://10.0.0.2");
ndn::Name neighborBName("/ndn/site/%C1.Router/routerB");
ndn::FaceUri faceUriB("udp://10.0.0.2");
Adjacent neighborB(neighborBName, faceUriB, 0, Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborB);
@ -467,20 +458,19 @@ BOOST_AUTO_TEST_CASE(CanonizeUris)
},
finallyCallback);
while (nCanonizationsLeft != 0) {
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
}
BOOST_CHECK_EQUAL(nlsr.getAdjacencyList().getAdjacent(neighborAName).getFaceUri(),
ndn::util::FaceUri("udp4://10.0.0.1:6363"));
ndn::FaceUri("udp4://10.0.0.1:6363"));
BOOST_CHECK_EQUAL(nlsr.getAdjacencyList().getAdjacent(neighborBName).getFaceUri(),
ndn::util::FaceUri("udp4://10.0.0.2:6363"));
ndn::FaceUri("udp4://10.0.0.2:6363"));
}
BOOST_AUTO_TEST_CASE(FaceDatasetFetchSuccess)
{
bool hasResult = false;
nlsr.m_validator.m_shouldValidate = false;
nlsr.initializeFaces([&hasResult] (const std::vector<ndn::nfd::FaceStatus>& faces) {
hasResult = true;
@ -490,7 +480,7 @@ BOOST_AUTO_TEST_CASE(FaceDatasetFetchSuccess)
},
[] (uint32_t code, const std::string& reason) {});
this->advanceClocks(ndn::time::milliseconds(500));
this->advanceClocks(ndn::time::milliseconds(100), 5);
ndn::nfd::FaceStatus payload1;
payload1.setFaceId(25401);
@ -498,22 +488,21 @@ BOOST_AUTO_TEST_CASE(FaceDatasetFetchSuccess)
payload2.setFaceId(25402);
this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
this->advanceClocks(ndn::time::milliseconds(500));
this->advanceClocks(ndn::time::milliseconds(100), 5);
BOOST_CHECK(hasResult);
}
BOOST_AUTO_TEST_CASE(FaceDatasetFetchFailure)
{
nlsr.m_validator.m_shouldValidate = false;
nlsr.initializeFaces([](const std::vector<ndn::nfd::FaceStatus>& faces) {},
[this](uint32_t code, const std::string& reason){
this->nFailureCallbacks++;
});
this->advanceClocks(ndn::time::milliseconds(500));
this->advanceClocks(ndn::time::milliseconds(100), 5);
ndn::Name payload;
this->sendDataset("/localhost/nfd/faces/list", payload);
this->advanceClocks(ndn::time::milliseconds(500));
this->advanceClocks(ndn::time::milliseconds(100), 5);
BOOST_CHECK_EQUAL(nFailureCallbacks, 1);
BOOST_CHECK_EQUAL(nSuccessCallbacks, 0);
@ -521,12 +510,12 @@ BOOST_AUTO_TEST_CASE(FaceDatasetFetchFailure)
BOOST_AUTO_TEST_CASE(FaceDatasetProcess)
{
Adjacent neighborA("/ndn/neighborA", ndn::util::FaceUri("udp4://192.168.0.100:6363"), 25,
Adjacent::STATUS_INACTIVE, 0, 0);
Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://192.168.0.100:6363"),
25, Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborA);
Adjacent neighborB("/ndn/neighborB", ndn::util::FaceUri("udp4://192.168.0.101:6363"), 10,
Adjacent::STATUS_INACTIVE, 0, 0);
Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://192.168.0.101:6363"),
10, Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborB);
ndn::nfd::FaceStatus payload1;
@ -538,7 +527,6 @@ BOOST_AUTO_TEST_CASE(FaceDatasetProcess)
std::vector<ndn::nfd::FaceStatus> faceStatuses = {payload1, payload2};
nlsr.processFaceDataset(faceStatuses);
this->advanceClocks(ndn::time::milliseconds(100));
AdjacencyList adjList = nlsr.getAdjacencyList();
@ -548,8 +536,7 @@ BOOST_AUTO_TEST_CASE(FaceDatasetProcess)
BOOST_AUTO_TEST_CASE(UnconfiguredNeighbor)
{
Adjacent neighborA("/ndn/neighborA", ndn::util::FaceUri("udp4://192.168.0.100:6363"), 25,
Adjacent::STATUS_INACTIVE, 0, 0);
Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://192.168.0.100:6363"), 25, Adjacent::STATUS_INACTIVE, 0, 0);
neighbors.insert(neighborA);
ndn::nfd::FaceStatus payload;
@ -558,7 +545,7 @@ BOOST_AUTO_TEST_CASE(UnconfiguredNeighbor)
std::vector<ndn::nfd::FaceStatus> faceStatuses = {payload};
nlsr.processFaceDataset(faceStatuses);
this->advanceClocks(ndn::time::milliseconds(100));
this->advanceClocks(ndn::time::milliseconds(20), 5);
AdjacencyList adjList = nlsr.getAdjacencyList();
@ -584,7 +571,7 @@ BOOST_AUTO_TEST_CASE(FaceDatasetPeriodicFetch)
this->advanceClocks(defaultTimeout);
// Check that we have one interest for face list in the sent interests.
for (const ndn::Interest& interest : face->sentInterests) {
for (const ndn::Interest& interest : m_face.sentInterests) {
if (datasetPrefix.isPrefixOf(interest.getName())) {
nNameMatches++;
}
@ -600,7 +587,7 @@ BOOST_AUTO_TEST_CASE(FaceDatasetPeriodicFetch)
// Check that we now have two interests
nNameMatches = 0;
for (const ndn::Interest& interest : face->sentInterests) {
for (const ndn::Interest& interest : m_face.sentInterests) {
if (datasetPrefix.isPrefixOf(interest.getName())) {
nNameMatches++;
}

4
tests/test-routing-table.cpp

@ -21,8 +21,8 @@
*
**/
#include "test-common.hpp"
#include "route/routing-table.hpp"
#include "test-common.hpp"
#include "route/routing-table-entry.hpp"
#include "route/nexthop.hpp"
#include <boost/test/unit_test.hpp>
@ -34,7 +34,7 @@ BOOST_FIXTURE_TEST_SUITE(TestRoutingTable, BaseFixture)
BOOST_AUTO_TEST_CASE(RoutingTableAddNextHop)
{
RoutingTable rt1(g_scheduler);
RoutingTable rt1(m_scheduler);
NextHop nh1;

56
tests/test-statistics.cpp

@ -30,12 +30,12 @@
namespace nlsr {
namespace test {
class StatisticsFixture : public BaseFixture
class StatisticsFixture : public UnitTestTimeFixture
{
public:
StatisticsFixture()
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: face(m_ioService, m_keyChain)
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, lsdb(nlsr.getLsdb())
, hello(nlsr.m_helloProtocol)
, conf(nlsr.getConfParameter())
@ -43,13 +43,15 @@ public:
{
conf.setNetwork("/ndn");
conf.setSiteName("/site");
conf.setRouterName("/%C1.router/this-router");
conf.setRouterName("/%C1.Router/this-router");
conf.buildRouterPrefix();
addIdentity(conf.getRouterPrefix());
nlsr.initialize();
face->processEvents(ndn::time::milliseconds(1));
face->sentInterests.clear();
this->advanceClocks(ndn::time::milliseconds(1), 10);
face.sentInterests.clear();
}
/*!
@ -77,7 +79,7 @@ public:
ndn::Name interestName = ndn::Name(ndn::Name(interestPrefix + lsaType).appendNumber(seqNo));
lsdb.processInterest(ndn::Name(), ndn::Interest(interestName));
face->processEvents(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
BOOST_CHECK_EQUAL(collector.getStatistics().get(receivedInterestType), rcvBefore + 1);
BOOST_CHECK_EQUAL(collector.getStatistics().get(sentDataType), sentBefore + 1);
@ -104,13 +106,13 @@ public:
lsdb.expressInterest(ndn::Name(prefix + lsaType).appendNumber(seqNo), 0,
ndn::time::steady_clock::TimePoint::min());
face->processEvents(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
BOOST_CHECK_EQUAL(collector.getStatistics().get(statsType), sentBefore + 1);
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace face;
Nlsr nlsr;
Lsdb& lsdb;
@ -143,48 +145,44 @@ BOOST_AUTO_TEST_CASE(StatsReset)
BOOST_CHECK_EQUAL(stats.get(Statistics::PacketType::SENT_HELLO_INTEREST), 0);
}
/*
* This tests hello interests and hello data statistical collection by constructing an adjacency lsa
* and calling functions that trigger the sending and receiving hello of interests/data.
*/
BOOST_AUTO_TEST_CASE(SendHelloInterest)
{
nlsr.initialize();
face->processEvents(ndn::time::milliseconds(1));
face->sentInterests.clear();
Adjacent other("/ndn/router/other", ndn::util::FaceUri("udp4://other"), 25, Adjacent::STATUS_INACTIVE, 0, 0);
Adjacent other("/ndn/router/other", ndn::FaceUri("udp4://other"), 25, Adjacent::STATUS_INACTIVE, 0, 0);
// This router's Adjacency LSA
nlsr.getAdjacencyList().insert(other);
ndn::Name name(conf.getRouterPrefix());
name.append("NLSR");
name.append("INFO");
name.append(other.getName().wireEncode());
ndn::Name otherName(other.getName());
otherName.append("NLSR");
otherName.append("INFO");
otherName.append(conf.getRouterPrefix().wireEncode());
hello.expressInterest(name, 1);
face->processEvents(ndn::time::milliseconds(1));
hello.expressInterest(otherName, 1);
this->advanceClocks(ndn::time::milliseconds(1), 10);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::SENT_HELLO_INTEREST), 1);
ndn::Interest interest(name);
ndn::Name thisName(conf.getRouterPrefix());
thisName.append("NLSR");
thisName.append("INFO");
thisName.append(other.getName().wireEncode());
ndn::Interest interest(thisName);
hello.processInterest(ndn::Name(), interest);
face->processEvents(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_HELLO_INTEREST), 1);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::SENT_HELLO_DATA), 1);
// Receive Hello Data
ndn::Name dataName = other.getName();
dataName.append("NLSR");
dataName.append("INFO");
dataName.append(conf.getRouterPrefix().wireEncode());
ndn::Name dataName = otherName;
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(dataName);
ndn::Data data(dataName);
hello.onContentValidated(data);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_HELLO_DATA), 1);

31
tests/test-sync-logic-handler.cpp

@ -33,12 +33,12 @@ namespace test {
using std::shared_ptr;
class SyncLogicFixture : public BaseFixture
class SyncLogicFixture : public UnitTestTimeFixture
{
public:
SyncLogicFixture()
: face(std::make_shared<ndn::util::DummyClientFace>())
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
: face(m_ioService, m_keyChain)
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, testIsLsaNew([] (const ndn::Name& name, const Lsa::Type& lsaType,
const uint64_t sequenceNumber) {
return true;
@ -57,6 +57,9 @@ public:
conf.setSiteName(CONFIG_SITE);
conf.setRouterName(CONFIG_ROUTER_NAME);
conf.buildRouterPrefix();
addIdentity(conf.getRouterPrefix());
INIT_LOGGERS("/tmp", "TRACE");
}
@ -68,16 +71,16 @@ public:
std::vector<chronosync::MissingDataInfo> updates;
updates.push_back(info);
face->processEvents(ndn::time::milliseconds(1));
face->sentInterests.clear();
this->advanceClocks(ndn::time::milliseconds(1), 10);
face.sentInterests.clear();
p_sync.onChronoSyncUpdate(updates);
face->processEvents(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
ndn::util::DummyClientFace face;
Nlsr nlsr;
ConfParameter conf;
SyncLogicHandler::IsLsaNew testIsLsaNew;
@ -98,7 +101,7 @@ BOOST_FIXTURE_TEST_SUITE(TestSyncLogicHandler, SyncLogicFixture)
*/
BOOST_AUTO_TEST_CASE(UpdateForOtherLS)
{
SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
SyncLogicHandler sync{face, testIsLsaNew, conf};
sync.createSyncSocket(conf.getChronosyncPrefix());
std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::ADJACENCY};
@ -128,7 +131,7 @@ BOOST_AUTO_TEST_CASE(UpdateForOtherHR)
{
conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
SyncLogicHandler sync{face, testIsLsaNew, conf};
sync.createSyncSocket(conf.getChronosyncPrefix());
uint64_t syncSeqNo = 1;
@ -156,7 +159,7 @@ BOOST_AUTO_TEST_CASE(UpdateForOtherHRDry)
{
conf.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
SyncLogicHandler sync{face, testIsLsaNew, conf};
sync.createSyncSocket(conf.getChronosyncPrefix());
for (const Lsa::Type& lsaType : lsaTypes) {
@ -183,7 +186,7 @@ BOOST_AUTO_TEST_CASE(NoUpdateForSelf)
{
const uint64_t sequenceNumber = 1;
SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
SyncLogicHandler sync{face, testIsLsaNew, conf};
sync.createSyncSocket(conf.getChronosyncPrefix());
for (const Lsa::Type& lsaType : lsaTypes) {
@ -209,7 +212,7 @@ BOOST_AUTO_TEST_CASE(MalformedUpdate)
{
const uint64_t sequenceNumber = 1;
SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
SyncLogicHandler sync{face, testIsLsaNew, conf};
sync.createSyncSocket(conf.getChronosyncPrefix());
for (const Lsa::Type& lsaType : lsaTypes) {
@ -237,7 +240,7 @@ BOOST_AUTO_TEST_CASE(LsaNotNew)
};
const uint64_t sequenceNumber = 1;
SyncLogicHandler sync{std::ref(*face), testLsaAlwaysFalse, conf};
SyncLogicHandler sync{face, testLsaAlwaysFalse, conf};
sync.createSyncSocket(conf.getChronosyncPrefix());
ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
[& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
@ -258,7 +261,7 @@ BOOST_AUTO_TEST_CASE(LsaNotNew)
BOOST_AUTO_TEST_CASE(UpdatePrefix)
{
SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
SyncLogicHandler sync{face, testIsLsaNew, conf};
ndn::Name expectedPrefix = nlsr.getConfParameter().getLsaPrefix();
expectedPrefix.append(CONFIG_SITE);

14
tests/update/test-advertise-crash.cpp

@ -30,14 +30,14 @@ class AdvertiseCrashFixture : public nlsr::test::UnitTestTimeFixture
{
public:
AdvertiseCrashFixture()
: face(g_ioService, keyChain, {true, true})
, nlsr(g_ioService, g_scheduler, face, g_keyChain)
: face(m_ioService, m_keyChain, {true, true})
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, namePrefixList(nlsr.getNamePrefixList())
, updatePrefixUpdateProcessor(nlsr.getPrefixUpdateProcessor())
{
// Add an adjacency to nlsr
Adjacent adj("/ndn/edu/test-site-2/%C1.Router/test",
ndn::util::FaceUri("udp://1.0.0.2"), 10, Adjacent::STATUS_INACTIVE, 0, 0);
ndn::FaceUri("udp://1.0.0.2"), 10, Adjacent::STATUS_INACTIVE, 0, 0);
nlsr.getAdjacencyList().insert(adj);
// Create a face dataset response with the face having the same uri as
@ -50,6 +50,9 @@ public:
// Set the network so the LSA prefix is constructed
nlsr.getConfParameter().setNetwork("/ndn");
nlsr.getConfParameter().setRouterName(ndn::Name("/This/router"));
addIdentity(ndn::Name("/ndn/This/router"));
// So that NLSR starts listening on prefixes
nlsr.initialize();
@ -59,14 +62,13 @@ public:
// in fib.cpp if an operation is done on non-existent faceUri
nlsr.processFaceDataset(faces);
this->advanceClocks(ndn::time::milliseconds(1));
this->advanceClocks(ndn::time::milliseconds(1), 10);
face.sentInterests.clear();
}
public:
ndn::util::DummyClientFace face;
ndn::KeyChain keyChain;
Nlsr nlsr;
NamePrefixList& namePrefixList;
@ -89,7 +91,7 @@ BOOST_FIXTURE_TEST_CASE(TestAdvertiseCrash, AdvertiseCrashFixture)
std::shared_ptr<ndn::Interest> advertiseInterest = std::make_shared<ndn::Interest>(advertiseCommand);
face.receive(*advertiseInterest);
this->advanceClocks(ndn::time::milliseconds(10));
this->advanceClocks(ndn::time::milliseconds(10), 10);
}
} // namespace test

21
tests/update/test-nfd-rib-command-processor.cpp

@ -39,13 +39,16 @@ class NfdRibCommandProcessorFixture : public nlsr::test::UnitTestTimeFixture
{
public:
NfdRibCommandProcessorFixture()
: face(g_ioService, keyChain, {true, true})
, nlsr(g_ioService, g_scheduler, face, g_keyChain)
: face(m_ioService, m_keyChain, {true, true})
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, namePrefixes(nlsr.getNamePrefixList())
, processor(nlsr.getNfdRibCommandProcessor())
{
// Set the network so the LSA prefix is constructed
nlsr.getConfParameter().setNetwork("/ndn");
nlsr.getConfParameter().setRouterName(ndn::Name("/This/router"));
addIdentity(ndn::Name("/ndn/This/router"));
// Initialize NLSR so a sync socket is created
nlsr.initialize();
@ -54,7 +57,7 @@ public:
// be the same value as what ChronoSync uses in setting the sessionName
sessionTime.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
this->advanceClocks(ndn::time::milliseconds(10));
this->advanceClocks(ndn::time::milliseconds(10), 10);
face.sentInterests.clear();
nameLsaSeqNoBeforeInterest = nlsr.getLsdb().getSequencingManager().getNameLsaSeq();
@ -74,7 +77,7 @@ public:
// Need to send an interest now since ChronoSync
// no longer does face->put(*data) in publishData.
// Instead it does it in onInterest
ndn::Name lsaInterestName("/localhop/ndn/NLSR/LSA");
ndn::Name lsaInterestName("/localhop/ndn/NLSR/LSA/This/router");
lsaInterestName.append(std::to_string(Lsa::Type::NAME));
// The part after LSA is Chronosync getSession
@ -83,13 +86,14 @@ public:
shared_ptr<ndn::Interest> lsaInterest = make_shared<ndn::Interest>(lsaInterestName);
face.receive(*lsaInterest);
this->advanceClocks(ndn::time::milliseconds(10));
this->advanceClocks(ndn::time::milliseconds(10), 10);
}
bool
wasRoutingUpdatePublished()
{
sendInterestForPublishedData();
const ndn::Name& lsaPrefix = nlsr.getConfParameter().getLsaPrefix();
const auto& it = std::find_if(face.sentData.begin(), face.sentData.end(),
@ -102,7 +106,6 @@ public:
public:
ndn::util::DummyClientFace face;
ndn::KeyChain keyChain;
Nlsr nlsr;
NamePrefixList& namePrefixes;
@ -148,7 +151,7 @@ BOOST_AUTO_TEST_CASE(onReceiveInterestRegisterCommand)
.wireEncode()), 0);
face.receive(*command);
this->advanceClocks(ndn::time::milliseconds(10));
this->advanceClocks(ndn::time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(namePrefixes.getNames().size(), 1);
std::list<ndn::Name> names = namePrefixes.getNames();
@ -173,7 +176,7 @@ BOOST_AUTO_TEST_CASE(onReceiveInterestUnregisterCommand)
.wireEncode()), 0);
face.receive(ndn::Interest(name));
this->advanceClocks(ndn::time::milliseconds(10));
this->advanceClocks(ndn::time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(namePrefixes.getNames().size(), 0);
BOOST_CHECK(wasRoutingUpdatePublished());
@ -190,7 +193,7 @@ BOOST_AUTO_TEST_CASE(onReceiveInterestInvalidPrefix)
.wireEncode()), 0);
face.receive(ndn::Interest(name));
this->advanceClocks(ndn::time::milliseconds(10));
this->advanceClocks(ndn::time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(namePrefixes.getNames().size(), 0);

212
tests/update/test-prefix-update-processor.cpp

@ -29,7 +29,11 @@
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/pib/identity.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/command-interest-signer.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <boost/filesystem.hpp>
@ -43,74 +47,78 @@ class PrefixUpdateFixture : public nlsr::test::UnitTestTimeFixture
{
public:
PrefixUpdateFixture()
: face(g_ioService, keyChain, {true, true})
, siteIdentity(ndn::Name("/ndn/edu/test-site").appendVersion())
, opIdentity(ndn::Name(siteIdentity).append(ndn::Name("%C1.Operator")).appendVersion())
, nlsr(g_ioService, g_scheduler, face, g_keyChain)
, keyPrefix(("/ndn/broadcast"))
: face(m_ioService, m_keyChain, {true, true})
, siteIdentityName(ndn::Name("/edu/test-site"))
, opIdentityName(ndn::Name("/edu/test-site").append(ndn::Name("%C1.Operator")))
, nlsr(m_ioService, m_scheduler, face, m_keyChain)
, namePrefixList(nlsr.getNamePrefixList())
, updatePrefixUpdateProcessor(nlsr.getPrefixUpdateProcessor())
, SITE_CERT_PATH(boost::filesystem::current_path() / std::string("site.cert"))
{
createSiteCert();
BOOST_REQUIRE(siteCert != nullptr);
createOperatorCert();
BOOST_REQUIRE(opCert != nullptr);
const std::string CONFIG =
"rule\n"
"{\n"
" id \"NLSR ControlCommand Rule\"\n"
" for interest\n"
" filter\n"
" {\n"
" type name\n"
" regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$\n"
" }\n"
" checker\n"
" {\n"
" type customized\n"
" sig-type rsa-sha256\n"
" key-locator\n"
" {\n"
" type name\n"
" regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$\n"
" }\n"
" }\n"
"}\n"
"rule\n"
"{\n"
" id \"NLSR Hierarchy Rule\"\n"
" for data\n"
" filter\n"
" {\n"
" type name\n"
" regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$\n"
" }\n"
" checker\n"
" {\n"
" type hierarchical\n"
" sig-type rsa-sha256\n"
" }\n"
"}\n"
"trust-anchor\n"
"{\n"
" type file\n"
" file-name \"site.cert\"\n"
"}\n";
// Site cert
siteIdentity = addIdentity(siteIdentityName);
saveCertificate(siteIdentity, SITE_CERT_PATH.string());
// Operator cert
opIdentity = addSubCertificate(opIdentityName, siteIdentity);
const std::string CONFIG = R"CONF(
rule
{
id "NLSR ControlCommand Rule"
for interest
filter
{
type name
regex ^(<localhost><nlsr>)<prefix-update>[<advertise><withdraw>]<><><>$
}
checker
{
type customized
sig-type rsa-sha256
key-locator
{
type name
regex ^<>*<KEY><>$
}
}
}
rule
{
id "NLSR Hierarchy Rule"
for data
filter
{
type name
regex ^[^<KEY>]*<KEY><><><>$
}
checker
{
type hierarchical
sig-type rsa-sha256
}
}
trust-anchor
{
type file
file-name "site.cert"
}
)CONF";
const boost::filesystem::path CONFIG_PATH =
(boost::filesystem::current_path() / std::string("unit-test.conf"));
updatePrefixUpdateProcessor.getValidator().load(CONFIG, CONFIG_PATH.native());
// Insert certs after the validator is loaded since ValidatorConfig::load() clears
// the certificate cache
nlsr.addCertificateToCache(opCert);
nlsr.loadCertToPublish(opIdentity.getDefaultKey().getDefaultCertificate());
// Set the network so the LSA prefix is constructed
nlsr.getConfParameter().setNetwork("/ndn");
nlsr.getConfParameter().setSiteName("/edu/test-site");
nlsr.getConfParameter().setRouterName("/%C1.Router/this-router");
nlsr.getConfParameter().buildRouterPrefix();
addIdentity(ndn::Name("/ndn/edu/test-site/%C1.Router/this-router"));
// Initialize NLSR so a sync socket is created
nlsr.initialize();
@ -124,45 +132,14 @@ public:
face.sentInterests.clear();
}
void
createSiteCert()
{
// Site cert
keyChain.createIdentity(siteIdentity);
siteCertName = keyChain.getDefaultCertificateNameForIdentity(siteIdentity);
siteCert = keyChain.getCertificate(siteCertName);
ndn::io::save(*siteCert, SITE_CERT_PATH.string());
}
void
createOperatorCert()
void sendInterestForPublishedData()
{
// Operator cert
ndn::Name keyName = keyChain.generateRsaKeyPairAsDefault(opIdentity, true);
opCert = std::make_shared<ndn::IdentityCertificate>();
std::shared_ptr<ndn::PublicKey> pubKey = keyChain.getPublicKey(keyName);
opCertName = keyName.getPrefix(-1);
opCertName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
opCert->setName(opCertName);
opCert->setNotBefore(time::system_clock::now() - time::days(1));
opCert->setNotAfter(time::system_clock::now() + time::days(1));
opCert->setPublicKeyInfo(*pubKey);
opCert->addSubjectDescription(ndn::security::v1::CertificateSubjectDescription(ndn::oid::ATTRIBUTE_NAME,
keyName.toUri()));
opCert->encode();
keyChain.signByIdentity(*opCert, siteIdentity);
keyChain.addCertificateAsIdentityDefault(*opCert);
}
void sendInterestForPublishedData() {
// Need to send an interest now since ChronoSync
// no longer does face->put(*data) in publishData.
// Instead it does it in onInterest
ndn::Name lsaInterestName("/localhop/ndn/NLSR/LSA");
ndn::Name lsaInterestName = nlsr.getConfParameter().getLsaPrefix();
lsaInterestName.append(nlsr.getConfParameter().getSiteName());
lsaInterestName.append(nlsr.getConfParameter().getRouterName());
lsaInterestName.append(std::to_string(Lsa::Type::NAME));
// The part after LSA is Chronosync getSession
@ -172,7 +149,7 @@ public:
std::shared_ptr<Interest> lsaInterest = std::make_shared<Interest>(lsaInterestName);
face.receive(*lsaInterest);
this->advanceClocks(ndn::time::milliseconds(10));
this->advanceClocks(ndn::time::milliseconds(100));
}
bool
@ -185,7 +162,8 @@ public:
const auto& it = std::find_if(face.sentData.begin(), face.sentData.end(),
[lsaPrefix] (const ndn::Data& data) {
return lsaPrefix.isPrefixOf(data.getName());
});
}
);
return (it != face.sentData.end());
}
@ -204,28 +182,16 @@ public:
BOOST_CHECK_EQUAL(response.getCode(), expectedCode);
}
~PrefixUpdateFixture()
{
keyChain.deleteIdentity(siteIdentity);
keyChain.deleteIdentity(opIdentity);
boost::filesystem::remove(SITE_CERT_PATH);
}
public:
ndn::util::DummyClientFace face;
ndn::KeyChain keyChain;
ndn::Name siteIdentity;
ndn::Name siteCertName;
std::shared_ptr<IdentityCertificate> siteCert;
ndn::Name siteIdentityName;
ndn::security::pib::Identity siteIdentity;
ndn::Name opIdentity;
ndn::Name opCertName;
std::shared_ptr<IdentityCertificate> opCert;
ndn::Name opIdentityName;
ndn::security::pib::Identity opIdentity;
Nlsr nlsr;
ndn::Name keyPrefix;
NamePrefixList& namePrefixList;
PrefixUpdateProcessor& updatePrefixUpdateProcessor;
@ -238,16 +204,29 @@ BOOST_FIXTURE_TEST_SUITE(TestPrefixUpdateProcessor, PrefixUpdateFixture)
BOOST_AUTO_TEST_CASE(Basic)
{
uint64_t nameLsaSeqNoBeforeInterest = nlsr.getLsdb().getSequencingManager().getNameLsaSeq();
// Advertise
ndn::nfd::ControlParameters parameters;
parameters.setName("/prefix/to/advertise/");
// Control Command format: /<prefix>/<management-module>/<command-verb>/<control-parameters>
// /<timestamp>/<random-value>/<signed-interests-components>
// Advertise
ndn::Name advertiseCommand("/localhost/nlsr/prefix-update/advertise");
// append /<control-parameters>
advertiseCommand.append(parameters.wireEncode());
std::shared_ptr<Interest> advertiseInterest = std::make_shared<Interest>(advertiseCommand);
keyChain.signByIdentity(*advertiseInterest, opIdentity);
ndn::security::CommandInterestSigner cis(m_keyChain);
// CommandInterestSigner::makeCommandInterest() will append the last
// three components: (<timestamp>/<random-value>/<signed-interests-components>)
ndn::Interest advertiseInterest =
cis.makeCommandInterest(advertiseCommand,
ndn::security::signingByIdentity(opIdentity));
face.receive(advertiseInterest);
face.receive(*advertiseInterest);
this->advanceClocks(ndn::time::milliseconds(10));
NamePrefixList& namePrefixList = nlsr.getNamePrefixList();
@ -261,14 +240,15 @@ BOOST_AUTO_TEST_CASE(Basic)
face.sentData.clear();
nameLsaSeqNoBeforeInterest = nlsr.getLsdb().getSequencingManager().getNameLsaSeq();
// Withdraw
//Withdraw
ndn::Name withdrawCommand("/localhost/nlsr/prefix-update/withdraw");
withdrawCommand.append(parameters.wireEncode());
std::shared_ptr<Interest> withdrawInterest = std::make_shared<Interest>(withdrawCommand);
keyChain.signByIdentity(*withdrawInterest, opIdentity);
ndn::Interest withdrawInterest
= cis.makeCommandInterest(withdrawCommand,
ndn::security::signingByIdentity(opIdentity));
face.receive(*withdrawInterest);
face.receive(withdrawInterest);
this->advanceClocks(ndn::time::milliseconds(10));
BOOST_CHECK_EQUAL(namePrefixList.size(), 0);

44
tests/wscript

@ -1,8 +1,8 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2016, The University of Memphis
Regents of the University of California,
Copyright (c) 2014-2017, The University of Memphis
Regents of the University of California
This file is part of NLSR (Named-data Link State Routing).
See AUTHORS.md for complete list of NLSR authors and contributors.
@ -22,23 +22,23 @@ NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
top = '..'
def build(bld):
# Unit tests
if bld.env['WITH_TESTS']:
unit_test_main = bld(
target='unit-tests-main',
name='unit-tests-main',
features='cxx',
source=bld.path.ant_glob(['**/*.cpp']),
use='nlsr-objects',
)
# nlsr tests
unit_tests_nlsr = bld.program(
target='../unit-tests-nlsr',
features='cxx cxxprogram',
source=bld.path.ant_glob(['nlsr/**/*.cpp']),
use='nlsr-objects unit-tests-main',
includes='.',
install_path=None,
)
if not bld.env['WITH_TESTS']:
return
bld(
features='cxx',
name='unit-tests-main',
target='unit-tests-main',
source='main.cpp',
defines=['BOOST_TEST_MODULE=NLSR Unit Tests'],
use='nlsr-objects'
)
bld.program(
target='../unit-tests-nlsr',
features='cxx cxxprogram',
source=bld.path.ant_glob(['**/*.cpp'], excl=['main.cpp']),
use='nlsr-objects unit-tests-main',
install_path=None,
# defines='TEST_CONFIG_PATH=\"%s/conf-test\"' %(bld.bldnode)
)

16
tools/nlsrc.cpp

@ -31,6 +31,8 @@
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/command-interest-signer.hpp>
#include <iostream>
@ -150,12 +152,18 @@ Nlsrc::sendNamePrefixUpdate(const ndn::Name& name,
ndn::Name commandName = NAME_UPDATE_PREFIX;
commandName.append(verb);
commandName.append(parameters.wireEncode());
ndn::Interest interest(commandName.append(parameters.wireEncode()));
interest.setMustBeFresh(true);
m_keyChain.sign(interest);
ndn::security::CommandInterestSigner cis(m_keyChain);
m_face.expressInterest(interest,
ndn::Interest commandInterest =
cis.makeCommandInterest(commandName,
ndn::security::signingByIdentity(m_keyChain.getPib().
getDefaultIdentity()));
commandInterest.setMustBeFresh(true);
m_face.expressInterest(commandInterest,
std::bind(&Nlsrc::onControlResponse, this, info, _2),
std::bind(&Nlsrc::onTimeout, this, ERROR_CODE_TIMEOUT, "Nack"),
std::bind(&Nlsrc::onTimeout, this, ERROR_CODE_TIMEOUT, "Timeout"));

2
tools/nlsrc.hpp

@ -147,7 +147,7 @@ private:
private:
ndn::KeyChain m_keyChain;
ndn::Face& m_face;
ndn::ValidatorNull m_validator;
ndn::security::ValidatorNull m_validator;
std::deque<std::function<void()>> m_fetchSteps;

1
wscript

@ -126,7 +126,6 @@ def build(bld):
if bld.env['WITH_TESTS']:
bld.recurse('tests')
bld.recurse('tests-integrated')
if bld.env['SPHINX_BUILD']:
bld(features="sphinx",

Loading…
Cancel
Save