Compare commits
11
Commits
NLSR-0.2.0
...
NLSR-0.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5363c7946b | ||
|
|
f4772d4f21 | ||
|
|
46ccaae829 | ||
|
|
c69c9af931 | ||
|
|
d33e5bc475 | ||
|
|
dce3f18229 | ||
|
|
cae33b69f2 | ||
|
|
18df0602d3 | ||
|
|
41b173ed54 | ||
|
|
9630fbf4e0 | ||
|
|
a6f3e645f5 |
No files matched your search
@@ -1,6 +1,27 @@
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
NLSR version 0.2.1 (changes since version 0.2.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Release date: June 30, 2015
|
||||
|
||||
**Code changes**:
|
||||
|
||||
- Using a configuration file without ``prefix-update-validator`` disables runtime advertise/withdraw instead of exiting (:issue:`2814`)
|
||||
|
||||
**Bug fixes**:
|
||||
|
||||
- Prevent incomplete removal of NPT entry (:issue:`2785`)
|
||||
|
||||
- Correct bidirectional links with differing costs (:issue:`2801`)
|
||||
|
||||
- Fix non-incrementing Adjacency number in AdjLsa::writeLog (:issue:`2594`)
|
||||
|
||||
- Remove FaceDestroyEvent test's reliance on nlsrSeqNo.txt (:issue:`2881`)
|
||||
|
||||
- Test ACTIVE/INACTIVE Adjacencies in LSA construction (:issue:`2735`)
|
||||
|
||||
NLSR version 0.2.0 (changes since version 0.1.0)
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
+2
-2
@@ -30,14 +30,14 @@ NLSR Documentation
|
||||
:maxdepth: 3
|
||||
|
||||
RELEASE-NOTES
|
||||
INSTALL
|
||||
GETTING-STARTED
|
||||
INSTALL
|
||||
ROUTER-CONFIG
|
||||
SECURITY-CONFIG
|
||||
manpages
|
||||
|
||||
- :doc:`INSTALL`
|
||||
- :doc:`GETTING-STARTED`
|
||||
- :doc:`INSTALL`
|
||||
- :doc:`ROUTER-CONFIG`
|
||||
- :doc:`SECURITY-CONFIG`
|
||||
- :doc:`RELEASE-NOTES`
|
||||
|
||||
+21
-7
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* Copyright (c) 2014-2015, 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.
|
||||
@@ -16,10 +17,8 @@
|
||||
*
|
||||
* 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 A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef NLSR_ADJACENCY_LIST_HPP
|
||||
#define NLSR_ADJACENCY_LIST_HPP
|
||||
|
||||
@@ -34,8 +33,10 @@ class Nlsr;
|
||||
|
||||
class AdjacencyList
|
||||
{
|
||||
|
||||
public:
|
||||
typedef std::list<Adjacent>::const_iterator const_iterator;
|
||||
typedef std::list<Adjacent>::iterator iterator;
|
||||
|
||||
AdjacencyList();
|
||||
~AdjacencyList();
|
||||
|
||||
@@ -110,8 +111,21 @@ public:
|
||||
void
|
||||
writeLog();
|
||||
|
||||
public:
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return m_adjList.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return m_adjList.end();
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<Adjacent>::iterator
|
||||
iterator
|
||||
find(const ndn::Name& adjName);
|
||||
|
||||
private:
|
||||
|
||||
+21
-27
@@ -612,46 +612,40 @@ ConfFileProcessor::processConfSectionSecurity(const ConfigSection& section)
|
||||
{
|
||||
ConfigSection::const_iterator it = section.begin();
|
||||
|
||||
if (it == section.end() || it->first != "validator")
|
||||
{
|
||||
std::cerr << "Error: Expect validator section!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (it == section.end() || it->first != "validator") {
|
||||
std::cerr << "Error: Expect validator section!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.loadValidator(it->second, m_confFileName);
|
||||
|
||||
it++;
|
||||
if (it != section.end() && it->first == "prefix-update-validator") {
|
||||
m_nlsr.getPrefixUpdateProcessor().enable();
|
||||
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
|
||||
|
||||
if (it == section.end() || it->first != "prefix-update-validator")
|
||||
{
|
||||
std::cerr << "Error: Expect prefix-update-validator section" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.getPrefixUpdateProcessor().loadValidator(it->second, m_confFileName);
|
||||
it++;
|
||||
|
||||
for (; it != section.end(); it++)
|
||||
{
|
||||
it++;
|
||||
for (; it != section.end(); it++) {
|
||||
using namespace boost::filesystem;
|
||||
if (it->first != "cert-to-publish")
|
||||
{
|
||||
std::cerr << "Error: Expect cert-to-publish!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (it->first != "cert-to-publish") {
|
||||
std::cerr << "Error: Expect cert-to-publish!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file = it->second.data();
|
||||
path certfilePath = absolute(file, path(m_confFileName).parent_path());
|
||||
ndn::shared_ptr<ndn::IdentityCertificate> idCert =
|
||||
shared_ptr<ndn::IdentityCertificate> idCert =
|
||||
ndn::io::load<ndn::IdentityCertificate>(certfilePath.string());
|
||||
|
||||
if (!static_cast<bool>(idCert))
|
||||
{
|
||||
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (idCert == nullptr) {
|
||||
std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nlsr.loadCertToPublish(idCert);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+25
-17
@@ -320,22 +320,30 @@ AdjLsa::removeNptEntries(Nlsr& pnlsr)
|
||||
void
|
||||
AdjLsa::writeLog()
|
||||
{
|
||||
_LOG_DEBUG("Adj Lsa: ");
|
||||
_LOG_DEBUG(" Origination Router: " << m_origRouter);
|
||||
_LOG_DEBUG(" Ls Type: " << m_lsType);
|
||||
_LOG_DEBUG(" Ls Seq No: " << m_lsSeqNo);
|
||||
_LOG_DEBUG(" Ls Lifetime: " << m_expirationTimePoint);
|
||||
_LOG_DEBUG(" Adjacents: ");
|
||||
int i = 1;
|
||||
std::list<Adjacent> al = m_adl.getAdjList();
|
||||
for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++)
|
||||
{
|
||||
_LOG_DEBUG(" Adjacent " << i << ": ");;
|
||||
_LOG_DEBUG(" Adjacent Name: " << (*it).getName());
|
||||
_LOG_DEBUG(" Connecting FaceUri: " << (*it).getConnectingFaceUri());
|
||||
_LOG_DEBUG(" Link Cost: " << (*it).getLinkCost());
|
||||
}
|
||||
_LOG_DEBUG("adj_lsa_end");
|
||||
_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
}//namespace nlsr
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& adjLsa)
|
||||
{
|
||||
os << "Adj Lsa:\n"
|
||||
<< " Origination Router: " << adjLsa.getOrigRouter() << "\n"
|
||||
<< " Ls Type: " << adjLsa.getLsType() << "\n"
|
||||
<< " Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
|
||||
<< " Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
|
||||
<< " Adjacents: \n";
|
||||
|
||||
int adjacencyIndex = 1;
|
||||
|
||||
for (const Adjacent& adjacency : adjLsa) {
|
||||
os << " Adjacent " << adjacencyIndex++ << ":\n"
|
||||
<< " Adjacent Name: " << adjacency.getName() << "\n"
|
||||
<< " Connecting FaceUri: " << adjacency.getConnectingFaceUri() << "\n"
|
||||
<< " Link Cost: " << adjacency.getLinkCost() << "\n";
|
||||
}
|
||||
os << "adj_lsa_end";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+18
@@ -165,6 +165,8 @@ public:
|
||||
class AdjLsa: public Lsa
|
||||
{
|
||||
public:
|
||||
typedef AdjacencyList::const_iterator const_iterator;
|
||||
|
||||
AdjLsa()
|
||||
: Lsa()
|
||||
, m_adl()
|
||||
@@ -215,6 +217,19 @@ public:
|
||||
void
|
||||
writeLog();
|
||||
|
||||
public:
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return m_adl.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return m_adl.end();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_noLink;
|
||||
AdjacencyList m_adl;
|
||||
@@ -285,6 +300,9 @@ public:
|
||||
static const std::string TYPE_STRING;
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const AdjLsa& adjLsa);
|
||||
|
||||
}//namespace nlsr
|
||||
|
||||
#endif //NLSR_LSA_HPP
|
||||
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* Copyright (c) 2014-2015, 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.
|
||||
@@ -16,16 +17,11 @@
|
||||
*
|
||||
* 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 A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
*
|
||||
**/
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
#include "name-prefix-table-entry.hpp"
|
||||
|
||||
#include "common.hpp"
|
||||
#include "name-prefix-table-entry.hpp"
|
||||
#include "routing-table-entry.hpp"
|
||||
#include "nexthop.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
@@ -33,8 +29,6 @@ namespace nlsr {
|
||||
|
||||
INIT_LOGGER("NamePrefixTableEntry");
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
NamePrefixTableEntry::generateNhlfromRteList()
|
||||
{
|
||||
@@ -105,4 +99,16 @@ NamePrefixTableEntry::writeLog()
|
||||
m_nexthopList.writeLog();
|
||||
}
|
||||
|
||||
}//namespace nlsr
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NamePrefixTableEntry& entry)
|
||||
{
|
||||
os << "Name: " << entry.getNamePrefix() << "\n";
|
||||
|
||||
for (const RoutingTableEntry& rte : entry.getRteList()) {
|
||||
os << "Destination: " << rte.getDestination() << "\n";
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* Copyright (c) 2014-2015, 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.
|
||||
@@ -16,18 +17,15 @@
|
||||
*
|
||||
* 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 A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef NLSR_NAME_PREFIX_TABLE_ENTRY_HPP
|
||||
#define NLSR_NAME_PREFIX_TABLE_ENTRY_HPP
|
||||
|
||||
#include "routing-table-entry.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include "routing-table-entry.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
@@ -50,8 +48,8 @@ public:
|
||||
return m_namePrefix;
|
||||
}
|
||||
|
||||
std::list<RoutingTableEntry>&
|
||||
getRteList()
|
||||
const std::list<RoutingTableEntry>&
|
||||
getRteList() const
|
||||
{
|
||||
return m_rteList;
|
||||
}
|
||||
@@ -97,6 +95,9 @@ private:
|
||||
NexthopList m_nexthopList;
|
||||
};
|
||||
|
||||
}//namespace nlsr
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NamePrefixTableEntry& entry);
|
||||
|
||||
#endif //NLSR_NAME_PREFIX_TABLE_ENTRY_HPP
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_NAME_PREFIX_TABLE_ENTRY_HPP
|
||||
+105
-69
@@ -19,56 +19,68 @@
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "name-prefix-table.hpp"
|
||||
|
||||
#include "logger.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "routing-table.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
#include "nlsr.hpp"
|
||||
#include "name-prefix-table.hpp"
|
||||
#include "name-prefix-table-entry.hpp"
|
||||
#include "routing-table.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
INIT_LOGGER("NamePrefixTable");
|
||||
|
||||
using namespace std;
|
||||
|
||||
static bool
|
||||
npteCompare(NamePrefixTableEntry& npte, const ndn::Name& name)
|
||||
{
|
||||
return npte.getNamePrefix() == name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
NamePrefixTable::addEntry(const ndn::Name& name, RoutingTableEntry& rte)
|
||||
{
|
||||
std::list<NamePrefixTableEntry>::iterator it = std::find_if(m_table.begin(),
|
||||
m_table.end(),
|
||||
ndn::bind(&npteCompare, _1, name));
|
||||
NptEntryList::iterator it = std::find_if(m_table.begin(),
|
||||
m_table.end(),
|
||||
bind(&npteCompare, _1, name));
|
||||
if (it == m_table.end()) {
|
||||
NamePrefixTableEntry newEntry(name);
|
||||
newEntry.addRoutingTableEntry(rte);
|
||||
newEntry.generateNhlfromRteList();
|
||||
newEntry.getNexthopList().sort();
|
||||
m_table.push_back(newEntry);
|
||||
_LOG_TRACE("Adding origin: " << rte.getDestination() << " to new name prefix: " << name);
|
||||
|
||||
NamePrefixTableEntry entry(name);
|
||||
|
||||
entry.addRoutingTableEntry(rte);
|
||||
|
||||
entry.generateNhlfromRteList();
|
||||
entry.getNexthopList().sort();
|
||||
|
||||
m_table.push_back(entry);
|
||||
|
||||
if (rte.getNexthopList().getSize() > 0) {
|
||||
m_nlsr.getFib().update(name, newEntry.getNexthopList());
|
||||
_LOG_TRACE("Updating FIB with next hops for " << entry);
|
||||
m_nlsr.getFib().update(name, entry.getNexthopList());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rte.getNexthopList().getSize() > 0) {
|
||||
(*it).addRoutingTableEntry(rte);
|
||||
(*it).generateNhlfromRteList();
|
||||
(*it).getNexthopList().sort();
|
||||
m_nlsr.getFib().update(name, (*it).getNexthopList());
|
||||
_LOG_TRACE("Adding origin: " << rte.getDestination() << " to existing prefix: " << *it);
|
||||
|
||||
it->addRoutingTableEntry(rte);
|
||||
|
||||
it->generateNhlfromRteList();
|
||||
it->getNexthopList().sort();
|
||||
|
||||
if (it->getNexthopList().getSize() > 0) {
|
||||
_LOG_TRACE("Updating FIB with next hops for " << *it);
|
||||
m_nlsr.getFib().update(name, it->getNexthopList());
|
||||
}
|
||||
else {
|
||||
(*it).resetRteListNextHop();
|
||||
(*it).getNexthopList().reset();
|
||||
// The routing table may recalculate and add a routing table entry with no next hops to
|
||||
// replace an existing routing table entry. In this case, the name prefix is no longer
|
||||
// reachable through a next hop and should be removed from the FIB. But, the prefix
|
||||
// should remain in the Name Prefix Table as a future routing table calculation may
|
||||
// add next hops.
|
||||
_LOG_TRACE(*it << " has no next hops; removing from FIB");
|
||||
m_nlsr.getFib().remove(name);
|
||||
}
|
||||
}
|
||||
@@ -77,38 +89,50 @@ NamePrefixTable::addEntry(const ndn::Name& name, RoutingTableEntry& rte)
|
||||
void
|
||||
NamePrefixTable::removeEntry(const ndn::Name& name, RoutingTableEntry& rte)
|
||||
{
|
||||
std::list<NamePrefixTableEntry>::iterator it = std::find_if(m_table.begin(),
|
||||
m_table.end(),
|
||||
ndn::bind(&npteCompare, _1, name));
|
||||
NptEntryList::iterator it = std::find_if(m_table.begin(),
|
||||
m_table.end(),
|
||||
bind(&npteCompare, _1, name));
|
||||
if (it != m_table.end()) {
|
||||
ndn::Name destRouter = rte.getDestination();
|
||||
(*it).removeRoutingTableEntry(rte);
|
||||
if (((*it).getRteListSize() == 0) &&
|
||||
(!m_nlsr.getLsdb().doesLsaExist(destRouter.append("/" + NameLsa::TYPE_STRING),
|
||||
(NameLsa::TYPE_STRING))) &&
|
||||
(!m_nlsr.getLsdb().doesLsaExist(destRouter.append("/" + AdjLsa::TYPE_STRING),
|
||||
(AdjLsa::TYPE_STRING))) &&
|
||||
(!m_nlsr.getLsdb().doesLsaExist(destRouter.append("/" + CoordinateLsa::TYPE_STRING),
|
||||
(CoordinateLsa::TYPE_STRING)))) {
|
||||
_LOG_TRACE("Removing origin: " << rte.getDestination() << " from prefix: " << *it);
|
||||
|
||||
it->removeRoutingTableEntry(rte);
|
||||
|
||||
// If the prefix is a router prefix and it does not have any other routing table entries,
|
||||
// the Adjacency/Coordinate LSA associated with that origin router has been removed from
|
||||
// the LSDB and so the router prefix should be removed from the Name Prefix Table.
|
||||
//
|
||||
// If the prefix is an advertised name prefix:
|
||||
// If another router advertises this name prefix, the RteList should have another entry
|
||||
// for that router; the next hops should be recalculated and installed in the FIB.
|
||||
//
|
||||
// If no other router advertises this name prefix, the RteList should be empty and the
|
||||
// prefix can be removed from the Name Prefix Table. Once a new Name LSA advertises this
|
||||
// prefix, a new entry for the prefix will be created.
|
||||
//
|
||||
if (it->getRteListSize() == 0) {
|
||||
_LOG_TRACE(*it << " has no routing table entries; removing from table and FIB");
|
||||
m_table.erase(it);
|
||||
m_nlsr.getFib().remove(name);
|
||||
}
|
||||
else {
|
||||
(*it).generateNhlfromRteList();
|
||||
m_nlsr.getFib().update(name, (*it).getNexthopList());
|
||||
_LOG_TRACE(*it << " has other routing table entries; updating FIB with next hops");
|
||||
it->generateNhlfromRteList();
|
||||
it->getNexthopList().sort();
|
||||
|
||||
m_nlsr.getFib().update(name, it->getNexthopList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
{
|
||||
//
|
||||
RoutingTableEntry* rteCheck =
|
||||
m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
|
||||
if (rteCheck != 0) {
|
||||
addEntry(name, *(rteCheck));
|
||||
_LOG_DEBUG("Adding origin: " << destRouter << " to " << name);
|
||||
|
||||
RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
|
||||
|
||||
if (rteCheck != nullptr) {
|
||||
addEntry(name, *rteCheck);
|
||||
}
|
||||
else {
|
||||
RoutingTableEntry rte(destRouter);
|
||||
@@ -119,11 +143,12 @@ NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
void
|
||||
NamePrefixTable::removeEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
{
|
||||
//
|
||||
RoutingTableEntry* rteCheck =
|
||||
m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
|
||||
if (rteCheck != 0) {
|
||||
removeEntry(name, *(rteCheck));
|
||||
_LOG_DEBUG("Removing origin: " << destRouter << " from " << name);
|
||||
|
||||
RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
|
||||
|
||||
if (rteCheck != nullptr) {
|
||||
removeEntry(name, *rteCheck);
|
||||
}
|
||||
else {
|
||||
RoutingTableEntry rte(destRouter);
|
||||
@@ -134,19 +159,23 @@ NamePrefixTable::removeEntry(const ndn::Name& name, const ndn::Name& destRouter)
|
||||
void
|
||||
NamePrefixTable::updateWithNewRoute()
|
||||
{
|
||||
for (std::list<NamePrefixTableEntry>::iterator it = m_table.begin();
|
||||
it != m_table.end(); ++it) {
|
||||
std::list<RoutingTableEntry> rteList = (*it).getRteList();
|
||||
for (std::list<RoutingTableEntry>::iterator rteit = rteList.begin();
|
||||
rteit != rteList.end(); ++rteit) {
|
||||
_LOG_DEBUG("Updating table with newly calculated routes");
|
||||
|
||||
// Update each name prefix entry in the Name Prefix Table with newly calculated next hops
|
||||
for (const NamePrefixTableEntry& prefixEntry : m_table) {
|
||||
for (const RoutingTableEntry& routingEntry : prefixEntry.getRteList()) {
|
||||
_LOG_TRACE("Updating next hops to origin: " << routingEntry.getDestination()
|
||||
<< " for prefix: " << prefixEntry);
|
||||
|
||||
RoutingTableEntry* rteCheck =
|
||||
m_nlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
|
||||
if (rteCheck != 0) {
|
||||
addEntry((*it).getNamePrefix(), *(rteCheck));
|
||||
m_nlsr.getRoutingTable().findRoutingTableEntry(routingEntry.getDestination());
|
||||
|
||||
if (rteCheck != nullptr) {
|
||||
addEntry(prefixEntry.getNamePrefix(), *rteCheck);
|
||||
}
|
||||
else {
|
||||
RoutingTableEntry rte((*rteit).getDestination());
|
||||
addEntry((*it).getNamePrefix(), rte);
|
||||
RoutingTableEntry rte(routingEntry.getDestination());
|
||||
addEntry(prefixEntry.getNamePrefix(), rte);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,12 +184,19 @@ NamePrefixTable::updateWithNewRoute()
|
||||
void
|
||||
NamePrefixTable::writeLog()
|
||||
{
|
||||
_LOG_DEBUG("----------------NPT----------------------");
|
||||
for (std::list<NamePrefixTableEntry>::iterator it = m_table.begin();
|
||||
it != m_table.end();
|
||||
++it) {
|
||||
(*it).writeLog();
|
||||
}
|
||||
_LOG_DEBUG(*this);
|
||||
}
|
||||
|
||||
} //namespace nlsr
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NamePrefixTable& table)
|
||||
{
|
||||
os << "----------------NPT----------------------\n";
|
||||
|
||||
for (const NamePrefixTableEntry& entry : table) {
|
||||
os << entry << std::endl;
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* Copyright (c) 2014-2015, 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.
|
||||
@@ -16,25 +17,26 @@
|
||||
*
|
||||
* 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 A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef NLSR_NAME_PREFIX_TABLE_HPP
|
||||
#define NLSR_NAME_PREFIX_TABLE_HPP
|
||||
|
||||
#include <list>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include "name-prefix-table-entry.hpp"
|
||||
#include "routing-table-entry.hpp"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace nlsr {
|
||||
class Nlsr;
|
||||
|
||||
class NamePrefixTable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::list<NamePrefixTableEntry> NptEntryList;
|
||||
typedef NptEntryList::const_iterator const_iterator;
|
||||
|
||||
NamePrefixTable(Nlsr& nlsr)
|
||||
: m_nlsr(nlsr)
|
||||
{
|
||||
@@ -52,6 +54,12 @@ public:
|
||||
void
|
||||
writeLog();
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
private:
|
||||
void
|
||||
addEntry(const ndn::Name& name, RoutingTableEntry& rte);
|
||||
@@ -64,6 +72,21 @@ private:
|
||||
std::list<NamePrefixTableEntry> m_table;
|
||||
};
|
||||
|
||||
}//namespace nlsr
|
||||
inline NamePrefixTable::const_iterator
|
||||
NamePrefixTable::begin() const
|
||||
{
|
||||
return m_table.begin();
|
||||
}
|
||||
|
||||
#endif //NLSR_NAME_PREFIX_TABLE_HPP
|
||||
inline NamePrefixTable::const_iterator
|
||||
NamePrefixTable::end() const
|
||||
{
|
||||
return m_table.end();
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NamePrefixTable& table);
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
#endif // NLSR_NAME_PREFIX_TABLE_HPP
|
||||
@@ -1,7 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014 University of Memphis,
|
||||
* Regents of the University of California
|
||||
* Copyright (c) 2014-2015, 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.
|
||||
@@ -16,10 +17,8 @@
|
||||
*
|
||||
* 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 A K M Mahmudul Hoque <ahoque1@memphis.edu>
|
||||
*
|
||||
**/
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include "lsdb.hpp"
|
||||
@@ -78,6 +77,37 @@ RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Links that do not have the same cost for both directions should have their
|
||||
// costs corrected:
|
||||
//
|
||||
// If the cost of one side of the link is 0, both sides of the link should have their cost
|
||||
// corrected to 0.
|
||||
//
|
||||
// Otherwise, both sides of the link should use the larger of the two costs.
|
||||
//
|
||||
for (size_t row = 0; row < m_nRouters; ++row) {
|
||||
for (size_t col = 0; col < m_nRouters; ++col) {
|
||||
double toCost = adjMatrix[row][col];
|
||||
double fromCost = adjMatrix[col][row];
|
||||
|
||||
if (fromCost != toCost) {
|
||||
double correctedCost = 0.0;
|
||||
|
||||
if (toCost != 0 && fromCost != 0) {
|
||||
// If both sides of the link are up, use the larger cost
|
||||
correctedCost = std::max(toCost, fromCost);
|
||||
}
|
||||
|
||||
_LOG_WARN("Cost between [" << row << "][" << col << "] and [" << col << "][" << row <<
|
||||
"] are not the same (" << toCost << " != " << fromCost << "). " <<
|
||||
"Correcting to cost: " << correctedCost);
|
||||
|
||||
adjMatrix[row][col] = correctedCost;
|
||||
adjMatrix[col][row] = correctedCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -45,21 +45,19 @@ Adjacency::Adjacency(const ndn::Block& block)
|
||||
|
||||
template<bool T>
|
||||
size_t
|
||||
Adjacency::wireEncode(ndn::EncodingImpl<T>& block) const
|
||||
Adjacency::wireEncode(ndn::EncodingImpl<T>& encoder) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
totalLength += ndn::prependNonNegativeIntegerBlock(block,
|
||||
ndn::tlv::nlsr::Cost,
|
||||
m_cost);
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, ndn::tlv::nlsr::Cost, m_cost);
|
||||
|
||||
totalLength += block.prependByteArrayBlock(
|
||||
totalLength += encoder.prependByteArrayBlock(
|
||||
ndn::tlv::nlsr::Uri, reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
|
||||
|
||||
totalLength += m_name.wireEncode(block);
|
||||
totalLength += m_name.wireEncode(encoder);
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(ndn::tlv::nlsr::Adjacency);
|
||||
totalLength += encoder.prependVarNumber(totalLength);
|
||||
totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Adjacency);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
+10
-10
@@ -49,25 +49,25 @@ LsaInfo::LsaInfo(const ndn::Block& block)
|
||||
|
||||
template<bool T>
|
||||
size_t
|
||||
LsaInfo::wireEncode(ndn::EncodingImpl<T>& block) const
|
||||
LsaInfo::wireEncode(ndn::EncodingImpl<T>& encoder) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
// Absence of an ExpirationPeriod signifies non-expiration
|
||||
if (!m_hasInfiniteExpirationPeriod) {
|
||||
totalLength += ndn::prependNonNegativeIntegerBlock(block,
|
||||
ndn::tlv::nlsr::ExpirationPeriod,
|
||||
m_expirationPeriod.count());
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder,
|
||||
ndn::tlv::nlsr::ExpirationPeriod,
|
||||
m_expirationPeriod.count());
|
||||
}
|
||||
|
||||
totalLength += ndn::prependNonNegativeIntegerBlock(block,
|
||||
ndn::tlv::nlsr::SequenceNumber,
|
||||
m_sequenceNumber);
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder,
|
||||
ndn::tlv::nlsr::SequenceNumber,
|
||||
m_sequenceNumber);
|
||||
|
||||
totalLength += ndn::prependNestedBlock(block, ndn::tlv::nlsr::OriginRouter, m_originRouter);
|
||||
totalLength += prependNestedBlock(encoder, ndn::tlv::nlsr::OriginRouter, m_originRouter);
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(ndn::tlv::nlsr::LsaInfo);
|
||||
totalLength += encoder.prependVarNumber(totalLength);
|
||||
totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::LsaInfo);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ PrefixUpdateProcessor::PrefixUpdateProcessor(ndn::Face& face,
|
||||
, m_sync(sync)
|
||||
, m_keyChain(keyChain)
|
||||
, m_validator(m_face, broadcastPrefix, certificateCache, certStore)
|
||||
, m_isEnabled(false)
|
||||
, COMMAND_PREFIX(ndn::Name(Nlsr::LOCALHOST_PREFIX).append(MODULE_COMPONENT))
|
||||
{
|
||||
}
|
||||
@@ -68,6 +69,11 @@ PrefixUpdateProcessor::onInterest(const ndn::Interest& request)
|
||||
{
|
||||
_LOG_TRACE("Received Interest: " << request);
|
||||
|
||||
if (!m_isEnabled) {
|
||||
sendNack(request);
|
||||
return;
|
||||
}
|
||||
|
||||
m_validator.validate(request,
|
||||
bind(&PrefixUpdateProcessor::onCommandValidated, this, _1),
|
||||
bind(&PrefixUpdateProcessor::onCommandValidationFailed, this, _1, _2));
|
||||
@@ -185,6 +191,19 @@ PrefixUpdateProcessor::validateParameters(const ndn::nfd::ControlCommand& comman
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PrefixUpdateProcessor::sendNack(const ndn::Interest& request)
|
||||
{
|
||||
ndn::MetaInfo metaInfo;
|
||||
metaInfo.setType(ndn::tlv::ContentType_Nack);
|
||||
|
||||
shared_ptr<ndn::Data> responseData = std::make_shared<ndn::Data>(request.getName());
|
||||
responseData->setMetaInfo(metaInfo);
|
||||
|
||||
m_keyChain.sign(*responseData);
|
||||
m_face.put(*responseData);
|
||||
}
|
||||
|
||||
void
|
||||
PrefixUpdateProcessor::sendResponse(const std::shared_ptr<const ndn::Interest>& request,
|
||||
uint32_t code,
|
||||
@@ -197,7 +216,7 @@ PrefixUpdateProcessor::sendResponse(const std::shared_ptr<const ndn::Interest>&
|
||||
ndn::nfd::ControlResponse response(code, text);
|
||||
const ndn::Block& encodedControl = response.wireEncode();
|
||||
|
||||
std::shared_ptr<ndn::Data> responseData = ndn::make_shared<ndn::Data>(request->getName());
|
||||
std::shared_ptr<ndn::Data> responseData = std::make_shared<ndn::Data>(request->getName());
|
||||
responseData->setContent(encodedControl);
|
||||
|
||||
m_keyChain.sign(*responseData);
|
||||
|
||||
@@ -78,10 +78,19 @@ public:
|
||||
void
|
||||
startListening();
|
||||
|
||||
void
|
||||
enable()
|
||||
{
|
||||
m_isEnabled = true;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
onInterest(const ndn::Interest& request);
|
||||
|
||||
void
|
||||
sendNack(const ndn::Interest& request);
|
||||
|
||||
void
|
||||
sendResponse(const std::shared_ptr<const ndn::Interest>& request,
|
||||
uint32_t code,
|
||||
@@ -128,6 +137,7 @@ private:
|
||||
SyncLogicHandler& m_sync;
|
||||
ndn::KeyChain& m_keyChain;
|
||||
Validator m_validator;
|
||||
bool m_isEnabled;
|
||||
|
||||
const ndn::Name COMMAND_PREFIX; // /localhost/nlsr/prefix-update
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ protected:
|
||||
size_t totalLength = 0;
|
||||
for (int64_t i = 0; i < N; i++)
|
||||
{
|
||||
totalLength += ndn::prependNonNegativeIntegerBlock(outBuffer, ndn::tlv::Content, i);
|
||||
totalLength += prependNonNegativeIntegerBlock(outBuffer, ndn::tlv::Content, i);
|
||||
}
|
||||
m_totalPayloadLength += totalLength;
|
||||
return totalLength;
|
||||
|
||||
@@ -518,6 +518,23 @@ BOOST_AUTO_TEST_CASE(LoadCertToPublish)
|
||||
boost::filesystem::remove(CERT_PATH);
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
BOOST_CHECK(processConfigurationString(SECTION_SECURITY));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} //namespace test
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, 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 "route/routing-table-calculator.hpp"
|
||||
|
||||
#include "adjacency-list.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "lsdb.hpp"
|
||||
#include "nlsr.hpp"
|
||||
#include "test-common.hpp"
|
||||
#include "route/map.hpp"
|
||||
#include "route/routing-table.hpp"
|
||||
|
||||
#include <ndn-cxx/util/dummy-client-face.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
namespace test {
|
||||
|
||||
static const ndn::time::system_clock::TimePoint MAX_TIME =
|
||||
ndn::time::system_clock::TimePoint::max();
|
||||
|
||||
class LinkStateCalculatorFixture : public BaseFixture
|
||||
{
|
||||
public:
|
||||
LinkStateCalculatorFixture()
|
||||
: face(ndn::util::makeDummyClientFace(g_ioService))
|
||||
, nlsr(g_ioService, g_scheduler, ndn::ref(*face))
|
||||
, routingTable(nlsr.getRoutingTable())
|
||||
, lsdb(nlsr.getLsdb())
|
||||
{
|
||||
setUpTopology();
|
||||
}
|
||||
|
||||
// Triangle topology with routers A, B, C connected
|
||||
void setUpTopology()
|
||||
{
|
||||
INIT_LOGGERS("/tmp", "TRACE");
|
||||
|
||||
ConfParameter& conf = nlsr.getConfParameter();
|
||||
conf.setNetwork("/ndn");
|
||||
conf.setSiteName("/router");
|
||||
conf.setRouterName("/a");
|
||||
conf.buildRouterPrefix();
|
||||
|
||||
Adjacent a(ROUTER_A_NAME, ROUTER_A_FACE, 0, Adjacent::STATUS_ACTIVE, 0, 0);
|
||||
Adjacent b(ROUTER_B_NAME, ROUTER_B_FACE, 0, Adjacent::STATUS_ACTIVE, 0, 0);
|
||||
Adjacent c(ROUTER_C_NAME, ROUTER_C_FACE, 0, Adjacent::STATUS_ACTIVE, 0, 0);
|
||||
|
||||
// Router A
|
||||
b.setLinkCost(LINK_AB_COST);
|
||||
c.setLinkCost(LINK_AC_COST);
|
||||
|
||||
AdjacencyList& adjacencyListA = nlsr.getAdjacencyList();
|
||||
adjacencyListA.insert(b);
|
||||
adjacencyListA.insert(c);
|
||||
|
||||
AdjLsa adjA(a.getName(), AdjLsa::TYPE_STRING, 1, MAX_TIME, 2, adjacencyListA);
|
||||
lsdb.installAdjLsa(adjA);
|
||||
|
||||
// Router B
|
||||
a.setLinkCost(LINK_AB_COST);
|
||||
c.setLinkCost(LINK_BC_COST);
|
||||
|
||||
AdjacencyList adjacencyListB;
|
||||
adjacencyListB.insert(a);
|
||||
adjacencyListB.insert(c);
|
||||
|
||||
AdjLsa adjB(b.getName(), AdjLsa::TYPE_STRING, 1, MAX_TIME, 2, adjacencyListB);
|
||||
lsdb.installAdjLsa(adjB);
|
||||
|
||||
// Router C
|
||||
a.setLinkCost(LINK_AC_COST);
|
||||
b.setLinkCost(LINK_BC_COST);
|
||||
|
||||
AdjacencyList adjacencyListC;
|
||||
adjacencyListC.insert(a);
|
||||
adjacencyListC.insert(b);
|
||||
|
||||
AdjLsa adjC(c.getName(), AdjLsa::TYPE_STRING, 1, MAX_TIME, 2, adjacencyListC);
|
||||
lsdb.installAdjLsa(adjC);
|
||||
|
||||
map.createFromAdjLsdb(nlsr);
|
||||
}
|
||||
|
||||
public:
|
||||
shared_ptr<ndn::util::DummyClientFace> face;
|
||||
Nlsr nlsr;
|
||||
Map map;
|
||||
|
||||
RoutingTable& routingTable;
|
||||
Lsdb& lsdb;
|
||||
|
||||
static const ndn::Name ROUTER_A_NAME;
|
||||
static const ndn::Name ROUTER_B_NAME;
|
||||
static const ndn::Name ROUTER_C_NAME;
|
||||
|
||||
static const std::string ROUTER_A_FACE;
|
||||
static const std::string ROUTER_B_FACE;
|
||||
static const std::string ROUTER_C_FACE;
|
||||
|
||||
static const double LINK_AB_COST;
|
||||
static const double LINK_AC_COST;
|
||||
static const double LINK_BC_COST;
|
||||
};
|
||||
|
||||
const ndn::Name LinkStateCalculatorFixture::ROUTER_A_NAME = "/ndn/router/a";
|
||||
const ndn::Name LinkStateCalculatorFixture::ROUTER_B_NAME = "/ndn/router/b";
|
||||
const ndn::Name LinkStateCalculatorFixture::ROUTER_C_NAME = "/ndn/router/c";
|
||||
|
||||
const std::string LinkStateCalculatorFixture::ROUTER_A_FACE = "face-a";
|
||||
const std::string LinkStateCalculatorFixture::ROUTER_B_FACE = "face-b";
|
||||
const std::string LinkStateCalculatorFixture::ROUTER_C_FACE = "face-c";
|
||||
|
||||
const double LinkStateCalculatorFixture::LINK_AB_COST = 5;
|
||||
const double LinkStateCalculatorFixture::LINK_AC_COST = 10;
|
||||
const double LinkStateCalculatorFixture::LINK_BC_COST = 17;
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(TestLinkStateRoutingCalculator, LinkStateCalculatorFixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Basic)
|
||||
{
|
||||
LinkStateRoutingTableCalculator calculator(map.getMapSize());
|
||||
calculator.calculatePath(map, routingTable, nlsr);
|
||||
|
||||
RoutingTableEntry* entryB = routingTable.findRoutingTableEntry(ROUTER_B_NAME);
|
||||
BOOST_REQUIRE(entryB != nullptr);
|
||||
|
||||
// Router A should be able to get to B through B and to B through C
|
||||
NexthopList& bHopList = entryB->getNexthopList();
|
||||
BOOST_REQUIRE_EQUAL(bHopList.getNextHops().size(), 2);
|
||||
|
||||
for (const NextHop& hop : bHopList) {
|
||||
std::string faceUri = hop.getConnectingFaceUri();
|
||||
uint64_t cost = hop.getRouteCostAsAdjustedInteger();
|
||||
|
||||
BOOST_CHECK((faceUri == ROUTER_B_FACE && cost == LINK_AB_COST) ||
|
||||
(faceUri == ROUTER_C_FACE && cost == LINK_AC_COST + LINK_BC_COST));
|
||||
|
||||
}
|
||||
|
||||
RoutingTableEntry* entryC = routingTable.findRoutingTableEntry(ROUTER_C_NAME);
|
||||
BOOST_REQUIRE(entryC != nullptr);
|
||||
|
||||
// Router A should be able to get to C through C and to C through B
|
||||
NexthopList& cHopList = entryC->getNexthopList();
|
||||
BOOST_REQUIRE_EQUAL(cHopList.getNextHops().size(), 2);
|
||||
|
||||
for (const NextHop& hop : cHopList) {
|
||||
std::string faceUri = hop.getConnectingFaceUri();
|
||||
uint64_t cost = hop.getRouteCostAsAdjustedInteger();
|
||||
|
||||
BOOST_CHECK((faceUri == ROUTER_C_FACE && cost == LINK_AC_COST) ||
|
||||
(faceUri == ROUTER_B_FACE && cost == LINK_AB_COST + LINK_BC_COST));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Asymmetric)
|
||||
{
|
||||
// Asymmetric link cost between B and C
|
||||
ndn::Name key = ndn::Name(ROUTER_B_NAME).append(AdjLsa::TYPE_STRING);
|
||||
AdjLsa* lsa = nlsr.getLsdb().findAdjLsa(key);
|
||||
BOOST_REQUIRE(lsa != nullptr);
|
||||
|
||||
Adjacent* c = lsa->getAdl().findAdjacent(ROUTER_C_NAME);
|
||||
BOOST_REQUIRE(c != nullptr);
|
||||
|
||||
double higherLinkCost = LINK_BC_COST + 1;
|
||||
c->setLinkCost(higherLinkCost);
|
||||
|
||||
// Calculation should consider the link between B and C as having cost = higherLinkCost
|
||||
LinkStateRoutingTableCalculator calculator(map.getMapSize());
|
||||
calculator.calculatePath(map, routingTable, nlsr);
|
||||
|
||||
RoutingTableEntry* entryB = routingTable.findRoutingTableEntry(ROUTER_B_NAME);
|
||||
BOOST_REQUIRE(entryB != nullptr);
|
||||
|
||||
// Router A should be able to get to B through B and to B through C
|
||||
NexthopList& bHopList = entryB->getNexthopList();
|
||||
BOOST_REQUIRE_EQUAL(bHopList.getNextHops().size(), 2);
|
||||
|
||||
for (const NextHop& hop : bHopList) {
|
||||
std::string faceUri = hop.getConnectingFaceUri();
|
||||
uint64_t cost = hop.getRouteCostAsAdjustedInteger();
|
||||
|
||||
BOOST_CHECK((faceUri == ROUTER_B_FACE && cost == LINK_AB_COST) ||
|
||||
(faceUri == ROUTER_C_FACE && cost == LINK_AC_COST + higherLinkCost));
|
||||
|
||||
}
|
||||
|
||||
RoutingTableEntry* entryC = routingTable.findRoutingTableEntry(ROUTER_C_NAME);
|
||||
BOOST_REQUIRE(entryC != nullptr);
|
||||
|
||||
// Router A should be able to get to C through C and to C through B
|
||||
NexthopList& cHopList = entryC->getNexthopList();
|
||||
BOOST_REQUIRE_EQUAL(cHopList.getNextHops().size(), 2);
|
||||
|
||||
for (const NextHop& hop : cHopList) {
|
||||
std::string faceUri = hop.getConnectingFaceUri();
|
||||
uint64_t cost = hop.getRouteCostAsAdjustedInteger();
|
||||
|
||||
BOOST_CHECK((faceUri == ROUTER_C_FACE && cost == LINK_AC_COST) ||
|
||||
(faceUri == ROUTER_B_FACE && cost == LINK_AB_COST + higherLinkCost));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AsymmetricZeroCost)
|
||||
{
|
||||
// Asymmetric link cost between B and C
|
||||
ndn::Name key = ndn::Name(ROUTER_B_NAME).append(AdjLsa::TYPE_STRING);
|
||||
AdjLsa* lsa = nlsr.getLsdb().findAdjLsa(key);
|
||||
BOOST_REQUIRE(lsa != nullptr);
|
||||
|
||||
Adjacent* c = lsa->getAdl().findAdjacent(ROUTER_C_NAME);
|
||||
BOOST_REQUIRE(c != nullptr);
|
||||
|
||||
c->setLinkCost(0);
|
||||
|
||||
// Calculation should consider the link between B and C as down
|
||||
LinkStateRoutingTableCalculator calculator(map.getMapSize());
|
||||
calculator.calculatePath(map, routingTable, nlsr);
|
||||
|
||||
// Router A should be able to get to B through B but not through C
|
||||
RoutingTableEntry* entryB = routingTable.findRoutingTableEntry(ROUTER_B_NAME);
|
||||
BOOST_REQUIRE(entryB != nullptr);
|
||||
|
||||
NexthopList& bHopList = entryB->getNexthopList();
|
||||
BOOST_REQUIRE_EQUAL(bHopList.getNextHops().size(), 1);
|
||||
|
||||
NextHop& nextHopForB = bHopList.getNextHops().front();
|
||||
|
||||
BOOST_CHECK(nextHopForB.getConnectingFaceUri() == ROUTER_B_FACE &&
|
||||
nextHopForB.getRouteCostAsAdjustedInteger() == LINK_AB_COST);
|
||||
|
||||
// Router A should be able to get to C through C but not through B
|
||||
RoutingTableEntry* entryC = routingTable.findRoutingTableEntry(ROUTER_C_NAME);
|
||||
BOOST_REQUIRE(entryC != nullptr);
|
||||
|
||||
NexthopList& cHopList = entryC->getNexthopList();
|
||||
BOOST_REQUIRE_EQUAL(cHopList.getNextHops().size(), 1);
|
||||
|
||||
NextHop& nextHopForC = cHopList.getNextHops().front();
|
||||
|
||||
BOOST_CHECK(nextHopForC.getConnectingFaceUri() == ROUTER_C_FACE &&
|
||||
nextHopForC.getRouteCostAsAdjustedInteger() == LINK_AC_COST);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} //namespace test
|
||||
} //namespace nlsr
|
||||
+83
-19
@@ -19,14 +19,19 @@
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
#include "test-common.hpp"
|
||||
|
||||
#include "adjacent.hpp"
|
||||
#include "lsa.hpp"
|
||||
#include "name-prefix-list.hpp"
|
||||
#include "adjacent.hpp"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace nlsr {
|
||||
namespace test {
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(TestLsa)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(NameLsaBasic)
|
||||
@@ -52,28 +57,43 @@ BOOST_AUTO_TEST_CASE(NameLsaBasic)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AdjacentLsaConstructorAndGetters)
|
||||
{
|
||||
Adjacent adj1("adjacent");
|
||||
Adjacent adj2("adjacent2");
|
||||
|
||||
AdjacencyList adjList;
|
||||
adjList.insert(adj1);
|
||||
ndn::Name routerName("/ndn/site/router");
|
||||
ndn::Name adjacencyName("/ndn/site/adjacency");
|
||||
ndn::time::system_clock::TimePoint testTimePoint = ndn::time::system_clock::now();
|
||||
//For AdjLsa, lsType is 2.
|
||||
//1 is the number of adjacent in adjacent list.
|
||||
AdjLsa alsa1("router1", AdjLsa::TYPE_STRING, 12, testTimePoint, 1, adjList);
|
||||
AdjLsa alsa2("router1", AdjLsa::TYPE_STRING, 12, testTimePoint, 1, adjList);
|
||||
uint32_t seqNo = 12;
|
||||
|
||||
// An AdjLsa initialized with ACTIVE adjacencies should copy the adjacencies
|
||||
AdjacencyList activeAdjacencies;
|
||||
Adjacent activeAdjacency(adjacencyName);
|
||||
activeAdjacency.setStatus(Adjacent::STATUS_ACTIVE);
|
||||
activeAdjacencies.insert(activeAdjacency);
|
||||
|
||||
AdjLsa alsa1(routerName, AdjLsa::TYPE_STRING, seqNo, testTimePoint,
|
||||
activeAdjacencies.getSize(), activeAdjacencies);
|
||||
BOOST_CHECK_EQUAL(alsa1.getAdl().getSize(), 1);
|
||||
BOOST_CHECK_EQUAL(alsa1.getLsType(), AdjLsa::TYPE_STRING);
|
||||
BOOST_CHECK_EQUAL(alsa1.getLsSeqNo(), (uint32_t)12);
|
||||
BOOST_CHECK_EQUAL(alsa1.getLsSeqNo(), seqNo);
|
||||
BOOST_CHECK_EQUAL(alsa1.getExpirationTimePoint(), testTimePoint);
|
||||
BOOST_CHECK_EQUAL(alsa1.getNoLink(), (uint32_t)1);
|
||||
BOOST_CHECK_EQUAL(alsa1.getNoLink(), 1);
|
||||
BOOST_CHECK(alsa1.getAdl().isNeighbor(activeAdjacency.getName()));
|
||||
|
||||
BOOST_CHECK(alsa1.isEqualContent(alsa2));
|
||||
// An AdjLsa initialized with INACTIVE adjacencies should not copy the adjacencies
|
||||
AdjacencyList inactiveAdjacencies;
|
||||
Adjacent inactiveAdjacency(adjacencyName);
|
||||
inactiveAdjacency.setStatus(Adjacent::STATUS_INACTIVE);
|
||||
inactiveAdjacencies.insert(inactiveAdjacency);
|
||||
|
||||
alsa1.addAdjacent(adj2);
|
||||
AdjLsa alsa2(routerName, AdjLsa::TYPE_STRING, seqNo, testTimePoint,
|
||||
inactiveAdjacencies.getSize(), inactiveAdjacencies);
|
||||
BOOST_CHECK_EQUAL(alsa2.getAdl().getSize(), 0);
|
||||
|
||||
const std::string ADJACENT_1 = "adjacent2";
|
||||
BOOST_CHECK(alsa1.getAdl().isNeighbor(ADJACENT_1));
|
||||
// Thus, the two LSAs should not have equal content
|
||||
BOOST_CHECK_EQUAL(alsa1.isEqualContent(alsa2), false);
|
||||
|
||||
// Create a duplicate of alsa1 which should have equal content
|
||||
AdjLsa alsa3(routerName, AdjLsa::TYPE_STRING, seqNo, testTimePoint,
|
||||
activeAdjacencies.getSize(), activeAdjacencies);
|
||||
BOOST_CHECK(alsa1.isEqualContent(alsa3));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CoordinateLsaConstructorAndGetters)
|
||||
@@ -91,7 +111,51 @@ BOOST_AUTO_TEST_CASE(CoordinateLsaConstructorAndGetters)
|
||||
BOOST_CHECK_EQUAL(clsa1.getData(), clsa2.getData());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(IncrementAdjacentNumber)
|
||||
{
|
||||
Adjacent adj1("adjacent1");
|
||||
Adjacent adj2("adjacent2");
|
||||
|
||||
adj1.setStatus(Adjacent::STATUS_ACTIVE);
|
||||
adj2.setStatus(Adjacent::STATUS_ACTIVE);
|
||||
|
||||
AdjacencyList adjList;
|
||||
adjList.insert(adj1);
|
||||
adjList.insert(adj2);
|
||||
|
||||
ndn::time::system_clock::TimePoint testTimePoint = ndn::time::system_clock::now();
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << testTimePoint;
|
||||
|
||||
const std::string TEST_TIME_POINT_STRING = ss.str();
|
||||
|
||||
AdjLsa lsa("router1", AdjLsa::TYPE_STRING, 12, testTimePoint, 1, adjList);
|
||||
|
||||
std::string EXPECTED_OUTPUT =
|
||||
"Adj Lsa:\n"
|
||||
" Origination Router: /router1\n"
|
||||
" Ls Type: adjacency\n"
|
||||
" Ls Seq No: 12\n"
|
||||
" Ls Lifetime: " + TEST_TIME_POINT_STRING + "\n"
|
||||
" Adjacents: \n"
|
||||
" Adjacent 1:\n"
|
||||
" Adjacent Name: /adjacent1\n"
|
||||
" Connecting FaceUri: \n"
|
||||
" Link Cost: 10\n"
|
||||
" Adjacent 2:\n"
|
||||
" Adjacent Name: /adjacent2\n"
|
||||
" Connecting FaceUri: \n"
|
||||
" Link Cost: 10\n"
|
||||
"adj_lsa_end";
|
||||
|
||||
std::ostringstream os;
|
||||
os << lsa;
|
||||
|
||||
BOOST_CHECK_EQUAL(os.str(), EXPECTED_OUTPUT);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} //namespace test
|
||||
} //namespace nlsr
|
||||
} // namespace test
|
||||
} // namespace nlsr
|
||||
@@ -0,0 +1,147 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2015, 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 "nlsr.hpp"
|
||||
#include "test-common.hpp"
|
||||
|
||||
#include <ndn-cxx/util/dummy-client-face.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
namespace test {
|
||||
|
||||
class NamePrefixTableFixture : public UnitTestTimeFixture
|
||||
{
|
||||
public:
|
||||
NamePrefixTableFixture()
|
||||
: face(ndn::util::makeDummyClientFace(g_ioService))
|
||||
, nlsr(g_ioService, g_scheduler, ndn::ref(*face))
|
||||
, lsdb(nlsr.getLsdb())
|
||||
, npt(nlsr.getNamePrefixTable())
|
||||
{
|
||||
INIT_LOGGERS("/tmp", "DEBUG");
|
||||
}
|
||||
|
||||
public:
|
||||
shared_ptr<ndn::util::DummyClientFace> face;
|
||||
Nlsr nlsr;
|
||||
|
||||
Lsdb& lsdb;
|
||||
NamePrefixTable& npt;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(TestNamePrefixTable)
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(Bupt, NamePrefixTableFixture)
|
||||
{
|
||||
ConfParameter& conf = nlsr.getConfParameter();
|
||||
conf.setNetwork("/ndn");
|
||||
conf.setSiteName("/router");
|
||||
conf.setRouterName("/a");
|
||||
conf.buildRouterPrefix();
|
||||
|
||||
RoutingTable& routingTable = nlsr.getRoutingTable();
|
||||
routingTable.setRoutingCalcInterval(0);
|
||||
|
||||
NamePrefixTable& npt = nlsr.getNamePrefixTable();
|
||||
|
||||
Adjacent thisRouter(conf.getRouterPrefix(), "udp://face", 0, Adjacent::STATUS_ACTIVE, 0, 0);
|
||||
|
||||
ndn::Name buptRouterName("/ndn/cn/edu/bupt/%C1.Router/bupthub");
|
||||
Adjacent bupt(buptRouterName, "udp://bupt", 0, Adjacent::STATUS_ACTIVE, 0, 0);
|
||||
|
||||
// This router's Adjacency LSA
|
||||
nlsr.getAdjacencyList().insert(bupt);
|
||||
AdjLsa thisRouterAdjLsa(thisRouter.getName(),
|
||||
AdjLsa::TYPE_STRING,
|
||||
1,
|
||||
ndn::time::system_clock::now() + ndn::time::seconds::max(),
|
||||
2,
|
||||
nlsr.getAdjacencyList());
|
||||
|
||||
lsdb.installAdjLsa(thisRouterAdjLsa);
|
||||
|
||||
// BUPT Adjacency LSA
|
||||
AdjacencyList buptAdjacencies;
|
||||
buptAdjacencies.insert(thisRouter);
|
||||
AdjLsa buptAdjLsa(buptRouterName,
|
||||
AdjLsa::TYPE_STRING,
|
||||
1,
|
||||
ndn::time::system_clock::now() + ndn::time::seconds(5),
|
||||
0 , buptAdjacencies);
|
||||
|
||||
lsdb.installAdjLsa(buptAdjLsa);
|
||||
|
||||
// BUPT Name LSA
|
||||
ndn::Name buptAdvertisedName("/ndn/cn/edu/bupt");
|
||||
|
||||
NamePrefixList buptNames;
|
||||
buptNames.insert(buptAdvertisedName);
|
||||
|
||||
NameLsa buptNameLsa(buptRouterName,
|
||||
NameLsa::TYPE_STRING,
|
||||
1,
|
||||
ndn::time::system_clock::now(),
|
||||
buptNames);
|
||||
|
||||
lsdb.installNameLsa(buptNameLsa);
|
||||
|
||||
// Advance clocks to expire LSAs
|
||||
this->advanceClocks(ndn::time::seconds(15));
|
||||
|
||||
// LSA expirations should cause NPT entries to be completely removed
|
||||
NamePrefixTable::const_iterator it = npt.begin();
|
||||
BOOST_REQUIRE(it == npt.end());
|
||||
|
||||
// Install new name LSA
|
||||
NameLsa buptNewNameLsa(buptRouterName, NameLsa::TYPE_STRING,
|
||||
12,
|
||||
ndn::time::system_clock::now() + ndn::time::seconds(3600),
|
||||
buptNames);
|
||||
|
||||
lsdb.installNameLsa(buptNewNameLsa);
|
||||
|
||||
this->advanceClocks(ndn::time::seconds(1));
|
||||
|
||||
// Install new adjacency LSA
|
||||
AdjLsa buptNewAdjLsa(buptRouterName, AdjLsa::TYPE_STRING,
|
||||
12,
|
||||
ndn::time::system_clock::now() + ndn::time::seconds(3600),
|
||||
0, buptAdjacencies);
|
||||
lsdb.installAdjLsa(buptNewAdjLsa);
|
||||
|
||||
this->advanceClocks(ndn::time::seconds(1));
|
||||
|
||||
// Each NPT entry should have a destination router
|
||||
it = npt.begin();
|
||||
BOOST_REQUIRE_EQUAL(it->getNamePrefix(), buptRouterName);
|
||||
BOOST_REQUIRE_EQUAL(it->getRteList().size(), 1);
|
||||
BOOST_CHECK_EQUAL(it->getRteList().begin()->getDestination(), buptRouterName);
|
||||
|
||||
++it;
|
||||
BOOST_REQUIRE_EQUAL(it->getNamePrefix(), buptAdvertisedName);
|
||||
BOOST_REQUIRE_EQUAL(it->getRteList().size(), 1);
|
||||
BOOST_CHECK_EQUAL(it->getRteList().begin()->getDestination(), buptRouterName);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // namespace test
|
||||
} // namespace nlsr
|
||||
+54
-5
@@ -113,6 +113,7 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
|
||||
{
|
||||
shared_ptr<ndn::util::DummyClientFace> face = ndn::util::makeDummyClientFace(g_ioService);
|
||||
Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
|
||||
Lsdb& lsdb = nlsr.getLsdb();
|
||||
|
||||
// Simulate loading configuration file
|
||||
ConfParameter& conf = nlsr.getConfParameter();
|
||||
@@ -133,23 +134,50 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
|
||||
neighbors.insert(failNeighbor);
|
||||
|
||||
// Create an additional neighbor so an adjacency LSA can be built after the face is destroyed
|
||||
Adjacent otherNeighbor("/ndn/neighborB", "uri://faceB", 25, Adjacent::STATUS_ACTIVE, 0, 256);
|
||||
Adjacent otherNeighbor("/ndn/neighborB", "uri://faceB", 10, Adjacent::STATUS_ACTIVE, 0, 256);
|
||||
neighbors.insert(otherNeighbor);
|
||||
|
||||
nlsr.initialize();
|
||||
|
||||
// Simulate successful HELLO responses
|
||||
nlsr.getLsdb().scheduleAdjLsaBuild();
|
||||
lsdb.scheduleAdjLsaBuild();
|
||||
|
||||
// Set up adjacency LSAs
|
||||
// This router
|
||||
Adjacent thisRouter(conf.getRouterPrefix(), "uri://faceB", 10, Adjacent::STATUS_ACTIVE, 0, 256);
|
||||
|
||||
AdjLsa ownAdjLsa(conf.getRouterPrefix(), AdjLsa::TYPE_STRING, 10, ndn::time::system_clock::now(),
|
||||
1, neighbors);
|
||||
lsdb.installAdjLsa(ownAdjLsa);
|
||||
|
||||
// Router that will fail
|
||||
AdjacencyList failAdjacencies;
|
||||
failAdjacencies.insert(thisRouter);
|
||||
|
||||
AdjLsa failAdjLsa("/ndn/neighborA", AdjLsa::TYPE_STRING, 10,
|
||||
ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, failAdjacencies);
|
||||
|
||||
lsdb.installAdjLsa(failAdjLsa);
|
||||
|
||||
// Other router
|
||||
AdjacencyList otherAdjacencies;
|
||||
otherAdjacencies.insert(thisRouter);
|
||||
|
||||
AdjLsa otherAdjLsa("/ndn/neighborB", AdjLsa::TYPE_STRING, 10,
|
||||
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));
|
||||
|
||||
// Make sure an adjacency LSA was built
|
||||
ndn::Name key = ndn::Name(nlsr.getConfParameter().getRouterPrefix()).append(AdjLsa::TYPE_STRING);
|
||||
AdjLsa* lsa = nlsr.getLsdb().findAdjLsa(key);
|
||||
AdjLsa* lsa = lsdb.findAdjLsa(key);
|
||||
BOOST_REQUIRE(lsa != nullptr);
|
||||
|
||||
uint32_t lastAdjLsaSeqNo = nlsr.getSequencingManager().getAdjLsaSeq();
|
||||
uint32_t lastAdjLsaSeqNo = lsa->getLsSeqNo();
|
||||
nlsr.getSequencingManager().setAdjLsaSeq(lastAdjLsaSeqNo);
|
||||
|
||||
// Make sure the routing table was calculated
|
||||
RoutingTableEntry* rtEntry = nlsr.getRoutingTable().findRoutingTableEntry(failNeighbor.getName());
|
||||
@@ -176,7 +204,11 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
|
||||
BOOST_CHECK_EQUAL(updatedNeighbor.getInterestTimedOutNo(),
|
||||
nlsr.getConfParameter().getInterestRetryNumber());
|
||||
BOOST_CHECK_EQUAL(updatedNeighbor.getStatus(), Adjacent::STATUS_INACTIVE);
|
||||
BOOST_CHECK_EQUAL(nlsr.getSequencingManager().getAdjLsaSeq(), lastAdjLsaSeqNo + 1);
|
||||
|
||||
lsa = lsdb.findAdjLsa(key);
|
||||
BOOST_REQUIRE(lsa != nullptr);
|
||||
|
||||
BOOST_CHECK_EQUAL(lsa->getLsSeqNo(), lastAdjLsaSeqNo + 1);
|
||||
|
||||
// Make sure the routing table was recalculated
|
||||
rtEntry = nlsr.getRoutingTable().findRoutingTableEntry(failNeighbor.getName());
|
||||
@@ -232,6 +264,23 @@ BOOST_FIXTURE_TEST_CASE(FaceDestroyEventInactive, UnitTestTimeFixture)
|
||||
// Simulate successful HELLO responses from neighbor B
|
||||
lsdb.scheduleAdjLsaBuild();
|
||||
|
||||
// Set up adjacency LSAs
|
||||
// This router
|
||||
Adjacent thisRouter(conf.getRouterPrefix(), "uri://faceB", 25, Adjacent::STATUS_ACTIVE, 0, 256);
|
||||
|
||||
AdjLsa ownAdjLsa(conf.getRouterPrefix(), AdjLsa::TYPE_STRING, 10, ndn::time::system_clock::now(),
|
||||
1, neighbors);
|
||||
lsdb.installAdjLsa(ownAdjLsa);
|
||||
|
||||
// Other ACTIVE router
|
||||
AdjacencyList otherAdjacencies;
|
||||
otherAdjacencies.insert(thisRouter);
|
||||
|
||||
AdjLsa otherAdjLsa("/ndn/neighborB", AdjLsa::TYPE_STRING, 10,
|
||||
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));
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/management/nfd-control-parameters.hpp>
|
||||
#include <ndn-cxx/management/nfd-control-response.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
#include <ndn-cxx/util/dummy-client-face.hpp>
|
||||
|
||||
@@ -167,6 +168,20 @@ public:
|
||||
return (it != face->sentDatas.end());
|
||||
}
|
||||
|
||||
void
|
||||
checkResponseCode(const Name& commandPrefix, uint64_t expectedCode)
|
||||
{
|
||||
std::vector<Data>::iterator it = std::find_if(face->sentDatas.begin(),
|
||||
face->sentDatas.end(),
|
||||
[commandPrefix] (const Data& data) {
|
||||
return commandPrefix.isPrefixOf(data.getName());
|
||||
});
|
||||
BOOST_REQUIRE(it != face->sentDatas.end());
|
||||
|
||||
ndn::nfd::ControlResponse response(it->getContent().blockFromValue());
|
||||
BOOST_CHECK_EQUAL(response.getCode(), expectedCode);
|
||||
}
|
||||
|
||||
~PrefixUpdateFixture()
|
||||
{
|
||||
keyChain.deleteIdentity(siteIdentity);
|
||||
@@ -198,6 +213,8 @@ BOOST_FIXTURE_TEST_SUITE(TestPrefixUpdateProcessor, PrefixUpdateFixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Basic)
|
||||
{
|
||||
updateProcessor.enable();
|
||||
|
||||
// Advertise
|
||||
ndn::nfd::ControlParameters parameters;
|
||||
parameters.setName("/prefix/to/advertise/");
|
||||
@@ -234,6 +251,38 @@ BOOST_AUTO_TEST_CASE(Basic)
|
||||
BOOST_CHECK(wasRoutingUpdatePublished());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DisabledAndEnabled)
|
||||
{
|
||||
ndn::nfd::ControlParameters parameters;
|
||||
parameters.setName("/prefix/to/advertise/");
|
||||
|
||||
ndn::Name advertiseCommand("/localhost/nlsr/prefix-update/advertise");
|
||||
advertiseCommand.append(parameters.wireEncode());
|
||||
|
||||
shared_ptr<Interest> advertiseInterest = make_shared<Interest>(advertiseCommand);
|
||||
keyChain.signByIdentity(*advertiseInterest, opIdentity);
|
||||
|
||||
// Command should be rejected
|
||||
face->receive(*advertiseInterest);
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
|
||||
BOOST_REQUIRE(!face->sentDatas.empty());
|
||||
|
||||
const ndn::MetaInfo& metaInfo = face->sentDatas.front().getMetaInfo();
|
||||
BOOST_CHECK_EQUAL(metaInfo.getType(), ndn::tlv::ContentType_Nack);
|
||||
|
||||
face->sentDatas.clear();
|
||||
|
||||
// Enable PrefixUpdateProcessor so commands will be processed
|
||||
updateProcessor.enable();
|
||||
|
||||
// Command should be accepted
|
||||
face->receive(*advertiseInterest);
|
||||
face->processEvents(ndn::time::milliseconds(1));
|
||||
|
||||
checkResponseCode(advertiseCommand, 200);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // namespace test
|
||||
|
||||
@@ -163,6 +163,11 @@ Nlsrc::sendNamePrefixUpdate(const ndn::Name& name,
|
||||
void
|
||||
Nlsrc::onControlResponse(const std::string& info, const ndn::Data& data)
|
||||
{
|
||||
if (data.getMetaInfo().getType() == ndn::tlv::ContentType_Nack) {
|
||||
std::cerr << "ERROR: Run-time advertise/withdraw disabled" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ndn::nfd::ControlResponse response;
|
||||
|
||||
try {
|
||||
|
||||
@@ -32,13 +32,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import os, sys, inspect
|
||||
|
||||
VERSION="1.8.8"
|
||||
REVISION="9fc5c9b7f01f62d3f97fff52443b345d"
|
||||
GIT="8f714a523d3b8c66f2949aaa8db91d6f7be55e55"
|
||||
VERSION="1.8.9"
|
||||
REVISION="8a9ccbc1c5d3936b0b08e972e4883a9a"
|
||||
GIT="2a098b1e9bc626c19cbd47c1f670758c17edf54c"
|
||||
INSTALL=''
|
||||
C1='#1'
|
||||
C2='#0'
|
||||
C3='#/'
|
||||
C1='#-'
|
||||
C2='#+'
|
||||
C3='#)'
|
||||
cwd = os.getcwd()
|
||||
join = os.path.join
|
||||
|
||||
@@ -165,5 +165,5 @@ if __name__ == '__main__':
|
||||
Scripting.waf_entry_point(cwd, VERSION, wafdir)
|
||||
|
||||
#==>
|
||||
#BZh91AY&SY7SW‘-8ÿÿÿ¼@ÿÿÿÿÿÿÿÿÿÿÿ ††"¦D€ @¨²#/Hað>÷Þ_gxö#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/�D#0²R‡¯¾Àx‰{f�¾îe‹ìnÞíT!Ò�GT¨4a:-�a�H>àÐ<>Îu#_m]¶è¯.”héé¶z´ÑèÙè:;šö§ èÒßvBA>Û§º{Ž}5zÐ-4ô÷³½ß^àôÚ›Æíf±.õ´ÀwaÍYÝž»°#/#/#0@}€#/)#/ì#/#/˜ÞÎSJ#1©©�í»¸9nÙÄ #/B»w§¯MØ2”#/)R(#/l#/42% %P ݹAJ#1½˜#1*R $¥P6÷Þíz{cí‡Þ½kË™ëvÎzn{¨æ¥;Ý˦¤ªí¯}sO�£+ãÍ>ø÷¾ë¾ç¯½]pµ÷ÛÁY¾îöû·ÜÛë§ÛÝónîèÜÚ9õî<}nqnî½Úûa÷ÖôÓžÀhvÄÓ'`À@쀚zç˜nç{^äÐhÐ=Í™ •å�{� #/ª¡)T�¡Ji›>Ï»_˜ÝŸ{yÕ).Ýä·zÏ{íó}õÚSfÛ6Ì—¶¯Ÿp|ç·zï½ôñO|{w»4n[éËì÷}¬£Ÿtç;{±»žÏ¯¾÷½ïµ×w¾Ï¾×GpyÇYy ÑÐåP}Îp·³‡sîyÕ+Û·^^–7;Ÿ7½z]ñw‚¯[Ûœ{¦o»INìî÷ÛËÅM²vã‹Çw»zÞ¢î½ÞDàõnò7®NÓ¸óŽ—m·6=ìã«}Ûŵ¯z€B³F–m|öú÷¹åæMöﻳ»·½»·³míìûµí6ÙžïA÷i}Øù{`Ÿ^õ�;åÝp}÷·Þ÷Ëçyßy ö¹(÷€#/D#1#1…H#1R¹=É {zª¨2¾ÍÞn=´ÓOrw-/GyoJŠæB»‡%;zÖ[:µ\ËÓ—wjð#/Õ†€#/9õ÷Ý{ï�÷muæû½Íè×{ŸoG°£zjáGڤǦvìÚvûg½ÇOz¼â{{€è7wq‹—Û½W²®}ö|XùŸw9»x jÕí¶Ïsì÷½{¸]½[«ì½Aô§}õÕ¸Mõ ¾û|]ï|óJj›4ï]É|lå›Ü»>d÷¹ò7½Ý»ïSµö÷¾w×Ðm�¨#/û¾n.þÚxõ{êvj ×Ðxo‰ö½ó�G½�»Ë�±÷¢†ú†îÙÛV몳ç¾û{>ïwµíÝ®ö[ïl|Mt¯=×{}qèy÷H³ol÷]ζ/�½óç|ð¯OZ#/ÐМ]=Ü혯]Ëì¯}öóSnìp['³Þ›ŸEÓ{#/èô#/I»sºí�{܆îæ9ÙÃëïnì#/#/#/è#/_o•Ó÷ÐogÝåð#1½³w.4{=}ô·Úæwn³UDJ.�œ£’°»¸Ö²Úæ][\á·[äkç¹ËÜ÷}wÛwǽ_y÷¶îÉ÷›Ÿ=o{‡lÌ•½½÷}ïŒÚnw`Ò³íí/;»ÆÇ€}›×˜æÖë¯.®õ+˯k“|OŽîšA#/#/™#/#/h#/&M44M#1j?T=&€Ð#/#/) B &€ÐM4Å6Bi¦ŒÊA¦�#/#/#/#/#/i! ”Í=e‰´£Êiú õ4y&56§’ª#/#/#/#/IꔑFMLÈÚ©šO*~¨ý)£FhÐ2#/4#/€22#/#/0Dˆ…0“#&Š~€MFh#1f¦Ê4i=dĘF#0)é='¨€h4zO#MABÐF@M#/žMODz©íO5'¨Ò‡”¨4#/#/È#/#/#/ÿÒIþ�T*™d„"¤ªDh(ó««»1Œ·Çm©ÈˆBP�b,&J#/§ÛU=(}ÿ—âéôâü£ó‘Þô²}=>‘ŒbSÜ̽TR‰š¼æVJºËº�ë0QŸ��ù'÷<.j j¬h@x&ëlY1#1!ÂÖ’¹MÛOƒrR¸ü2í–õqãs\4u%ë™bæêàuIâÔTc•€xW7EÓ¼UÔÆÄÑF-F X¨Æ4&�åæ×ÈçDÃÕ›XÒWuÛmM[h¶«�‘AaS#1¡¤U9‚ƒR#1#/b „†`¨Ø!"ŠBé‚E‚ ¨‘DdTÊ #1vA@#/„‚@(0f%!™¦$BdCF3hÙš"JjE,dL”¢˜¥´•#0L’X XMR¢²Pa(f‰²…²c%fPE™¢XКaJH¤Ø‹F(ŠIJ”ÍQ Á,´�T’ ƒ)"E¶“T,–libjF()%Ò$aflZ5¦Õ¥µR’mDÉ’d�E±µ+XÍ0Í™¦j’É”ÛbTÛ5I&¦EME³#R3Z6��“LÐS$£AIi ´R•IØÄÁ4¦&›Á*S`˜@1f#1™&D¢$¡dªH)bY42DJB)%%,Rdƒh¦2R“jÔcPÙX˜QE),J$Ò)DÆ,LT&Sh¤™i¤‰ Å‘¤Œ’¥S0Ö�¨dQ,1&$$�MˆÔ•#0–‰ ²#1D”TTDJB™±‚I5&"’2!"fDf�$Ìfc%fY�¡*1$&¤ØB@’M4´“&‹)L6ˆÓH£B(…) e Ò$ÍRË,¥”†M,“f™F€Ô±IfFÆŒ¬“1$Š-#/ÍŒ²B¢K l¨)fhÆÑf‘²Q™Mš$¦¶›†!2˜Æ˜#Rd¤Ì4ÉK5K*TlQ0‚ŠMDLI‘” ¦�#/ÂHÉ#02(H4–Ö‘C5�†RȲf¤)´›%É�$É$¡(²PÒ5€Ñ°02eˆ¡²I³YŒšŒb0JT2™¥˜„†Â¦MRÆ,ÔØ¤Ê,Œ˜’…6I!e2,DÍ0P1¢6ƒ™4¤™†É²hÉ�¨d¬$ÊÊL6‚ɲR„I,™FB)¦ƒ$e2‘–#¤¥SfŠ�£Q ”"RDVŒm�$ÍdPÒcFCÊ�!ˆ bZ6�JF(¬L´™4Ra%‘„1K F“!Œ£4†Íª›[h(ª(É© k%ÊHÚ)’™&1¬–‹4ic)ši²R”Z™Ù¶%6c) B…-~†·F�²´†BYFJkZ+Š� ™QLQ²Z#0S$ÕLE#0ƒKCJRIÌld ¨e¨KQdSY2E¥F‘hX™3––c$Š‹Ì¦«4i�«#dU6±M”IeFR«Õ¤ÚB³ek5)Ji†Úb…2"Æ´i©Q%¦Q¢2ÆÑXÛ3FØJ¬ÍQªÂEIFÛFÁd£Tfˆ…QHT-cTl3RX„ÖHQi¢J$¢�Maš”JmJ£Q²I´cR5L™kk64bÃSj6Y*k"LÌÔÒ‘I2Ú¥¨¥¤¦jiS+J¥dª”!1¶•2”›SJÓf-&†¶k32IYb†l’Ú[K!bÔÒ��š�%D"�€�Œ‚!ˆBÐS$À¦ÔmI�Še6ÆÒ“M2h4”Â…ŠR¢6)¥˜Ò!š)’™1¬¦ÍX�”*6,Éb•š’ÀclË&–c)‚¤"¢aJQ&,M˜›j6$¤£#A¤Y”Z™�˜…%cL&l2lX˜cfZ�M%Š )Ô¦Ñ�³6Š‹hFˆÒZhH¤ÁXRËA„‘&+!4”Œ¦Á’Ø…&¥$›5(„ª�*™˜ØlT¦“dm&Qf’Ö �ÈQ%$›)&„©-&dlÍ1*[,ØÚ#1ÊlÑDlblRi©&S&Š™HÉ”´l””fÀ‰& b&4cL£E5–M’˜˜‰©!"ÑX�°›Š�mˆ4˜d™¢J#1M"ÑLlRD bÁl´¤“R#1�dÌ4”³!¦£FÂF¢¶M,+AI’ب1Œ0 h¤Õ)DÕ�c)™¡#0FÉ%fEID–��ÑYkSdÔZ1‰•’ÐÒ”,iIMT²J’™JQ«b#0REJ4•FFÉcY4•5TÌS(©Kd-b¡¤™²E&ņ�B"Å‹LÉC4`ÚL‰3DŠ©Di„Ê[1£QZ-Ф„*%0c)Q¨Ö6™% QI„I«J#1-)ªSi5±¬Vɬ–³H#1Ñlš’‹Å(#(1³B$„ÆÉL0f¨‚�±±mSm¤¡–ˆ+šŠ‰#1Ñ3l³j6ŠÅE¬I&Ú”fÍ�ÒÊĪ1h¦Xªš“M¥FŠQ,˜²¥E¡*(¬•’Ù(Û&¬Rm)™E“hФj)(Ñh¶Ûfµ¦ŒÔ,–"J™FÑQ¬(ƒI©lÕ“±VŠ"Ú+F¶-ÛFÕ²mlEªjVmDÙH6’cÊÂÊQd�šTEÌlII”“"!jKb̵L|ÔÿÚgâ†uOýÔeMTŸövÎ#0JÎçü™Û¡1Ÿêÿäÿkè¼d•‘}["lÜ:Oꄎ&'ôÿM²CPªt¢U3û+�…’ÓÚT1é>˜X>=›ÞÓª˜ƒá)Õ¹IWUÌ9 —KªXM«ú¦ßW†îtäª�ÿ7Iü‹~þ?Õ´‘�ã{uETI9ëž6Bœa°H0�¤9ÞI„ÝŸUï‰íÍm¤¦C¢êj”¦9Ƹƒ–f#0%d>?1ˆõjòÊÚtâô3S-ºar"®7³ÚübÁË+¥ˆÝ´U|!Ö%áiÄÖ³R<,‘¿{€ËI*ª118†3¶ªhqÕÿ©MÔœb©YX"$#D“ئåH#õ™2–/;ª'øÝ^þv̽›šLh"‰r˜ƒÆËæÌþå?áÀ5PöÉdíü’xfDTüéÄÁ‘dUýŸêÃ$ùý/LÐTø¥™ç1#0´üD1#10ûyÑåç½^Õ$ÄL,†Çöóy¡þ¡™ó£º6‰"�šƒ—™—–f&U¤qœ¢O$£òùáãþµþqêúìÐXuë1A3L™ç·›Â)®ît]ÆŠææM!I$-Ž_‚Pã#/Ô‚Ÿ÷dûÒDãXAOÎ… ‚U=úÂðÃ6žþøt [;^½¹·¥Ëཉr÷Ð$¤<Uþ+[Þu:`N2ŒË+#0²�oŽºy6¥�œ¦?6cB”ã&…êõ;¨é\¹&î»ë¦Š‚v�3/ý³ÑpQ ¢ÃðKÊ4”DO#0ð¥ò bEŠÿQýT½ÿ}ë#1ÿÖ~:N0æµ<%·ß—PDT(Y1Û Pd+R_óÀgÕý9¬±NÎlÀ%$“¡œü�ñÞ: ³ú�³õôÔÍ»šƒzcõænÈŸ)Mq+c¾/¿ú¬ú'ièBûXf±Ä©F‹(‡"$ Þ‡B]oÕÔúÒÎ;ÉòµÞ#0šÓÍ,€ d^ �~bu”(¤å~yAŽ4<üîI¢LÁ)ï†cÃ*‡ü®¤÷CR.$û#1°X&uòÍÿû¶šü�,O—tÃÃ`àÕoܙ˸öõ™üyÍ‘C—0®`ßøí'Òӊňϓ`Ȉ‚ÄYöÒÃæZ,Œzí…'òü ›aï…T_þ–¯ØZŸ|Ó½[v¥2â±�öy¦“l±÷µzRÐd��ã™–Mâ¹®V5_¼òš�>·�½7}�_'„Íÿo«øý¯¢ö»F9nk]ÕÛ�e*0Ö¥Cóß—6BL$S )òø]MH¾èQ>ñ#1$Ä•!ÔÁüv‘ðÔP>�±TÄã(ߢk�ø¸Ò[&·[¯�|<ï8ìXÖ,•}3þâ÷W#[íh*,2ÒwO®v!ùòœþq³(TÓ¦l{83P/ÚãsC±(BóSz Þ¦‰_ýÇ‘¹·S|eÔ�Z¢Eáh²x#1ž-¼C °z ~¤0QâXÄjBˆ'ÒÂv÷jŒ¦,MbÉÜ„é$"ûÄ0(û=¸’˜0½0Äú|®$áj0Õùd;C8ZŠGÚÔÇÄOƒ°K™¿`t˜Î™8ÔËnÒœ²½Ú§Í§LóÍ1ˆ*z¿†QY÷t¤ñ�ÂBm#/ÖÜ·Ñu‡uT·jmßTt…0æƒÛdðßi¨g±ÃfqíDU‰ê£ºeFˆT|Îmž`sè²�,QôC@pãšöùÄK´šÐ2{¥$R”(¢ õw%?°¿>¥Ø!KQb‡µ,Cç·äïÿCç>üãÛëÎ}>HR(Øø&ŠôÜö¦œ� Ð$Ƥà‘zî«Òo.žø=i¬Ù‡F©0†P:R@„”3¹}ÊÌErÙ¹(ë·2ÑŸu‚˜’纓‡òX—dÈq3%8¯æ¢¦ÜHÇ«åG¹#0…ä’9^ñ'i#1L}¤8²œ—ç8ú^ðïžÛ†ÙŒÅC¾Üc}¼±•ŒW}¦¤Ï¢¦ˆ§?—›é€àÏéO¤˜¢T%Û$Á!é’!=¥/\M‰àR�#0H71#¾.Ði‡ßèì±Ì½Ã¸…Þ™pLine truncated
|
||||
#BZh91AY&SYüÆ6*Zÿÿ´�AÿÿÿÿÿÿÿÿÿÿÿD #)†Ž"¢D˜ @ ¨8aðœ÷½p€#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)ùçÛµ‡>ÞJí}iÛeHÛCWmk^|ã½dm}šª¥ë×Ujï<÷x]“©¶“+jÝpâ�o}=×Îvºîí°W–$�¢¯g»=fv:z=ë:uë]»v]==(ßvCÛÝÝ›½é÷Þ{é+îûš«ÇAëÓßw}÷ß}žðúêvø_mÛ—Û}ƒàwc{©Å=åî#)#)#)#)€–Èoµ)ôt<t;}°—0ÓºX,ß@÷™ž�ÆÐwgF†3¾¯oG¡ï5 ÜÂT¡@¢†½A¡ŠP‰A{·Hz4%šJTë#)®Ë^ºw@éÓÞúízïwnáíZÀî½íç•2Ôwv”ìÜÍ]šqkî÷m•‘XúWs|põ·¾óëØ×Õ½Öóww>æ›{»·Û3<ßw¹ßnöU§váíõßHõŸ%‹=>¼Jîæžöw6¾ïpÈ*T;(¦Œ†^ë;™Û±žw¦v#)t=]î3¬h¥´H+{½ç¶ávÐ#)¢„ô3Ó@ô={4Ð7¯qZ�¼Ý'œ×nîÝAí¨Þ‹3îù½�€Ð.Í#-úxJ6aά¼{€;¹ç�S¾ÝAÖÏxó½”Snï@9›îÏÞoP¼÷x×v=ªù{°sm:4$ºzû¾ùãì,8÷^WTžµÊž�»ìåÛ¶chúÖûÞÏ×¾÷·¼ªç»;}{Ë=³_wÜ{L|ów®çΰ<׸i=àÏW�väžG§M9{kExEÙ®ú…¬Ûx·ñ¾ï‰Ý�µ›Îî·]Ï·÷rõ÷Ù[,÷hC7}¼¶òö¯v>÷ ïMòu€ï,ûϾó×¾÷È/¸}ÑÏ$€*#-:-„…˜�kjNjºÐ/²ã½+ì˜äê»[{±v–(åpa넨Žío`ÓXû·×Ýßo¾úú=ð#)öåÚ€�·_a—ÞÞ»ßol÷½´9wÝ�¹ºõéË}‡Ýë§Í>ÙãÕÝÃ�ºÅt#+í}o/¾÷gc=Ýn†ë±×·¼{kzsï·Šm¾öøm#)hŸ_}ç«kkP/£�UªÑàWo\íÖŽÞÞ'Ý÷Þu6MnûnÔ’âuÚöáðñ³ò>özÛ}öåöÜZÔÐÖÁU÷ÝÓ¡}ºx§]wŽø9uÐWÝ„éx_ZÛ¼žºìGϾ^÷wsï@0kD¬ÀÚϼ¶ß[ìz7;Gí¾ööÏ�Ö¶Òë³íËÐ÷ÜϽ÷¾fû·:Ëç»ÞßwÕwŸTÛÜåÑ W b¶Ð—«op;º·�îŠsƒTwnØtËxduŸ@:(5sC×·#)ôG³ÈÙ¼|_{½î‚@�ô+UAOoOo¾ûîõw@c}}w—K[.×Þx{Ûíç¶ùöݳwW=9t*ŠHÞíq»;[ë”'bõV_w¹î[GÙ[Ó/}gmô4»œ}Þ¯ºõ|CŸ+îÝavù>zn°§°£O¾Î=›k¢ëY[¯¢÷wÛÕ·½0W‹ï{“}™`éÙ+ͯêòð6û¡^>îšA#)#)™#)#)& #)&™�2dÑ“ô‘£ô ¦ž 4z<”ýPJhDL€&§¦ˆõ12i¨<S2!µ#+#+#)#)Ð#)#)#)#) &"`€#LMI´Töž©”óTñ=)êmªhhÚŸ©4Éä€hÐ#)#+#)#)#)Iꔑ4‚hj§á¢žQµOOJzžž¨Ñ£z†�£@4È#)4#)#+#)#+#)#)#)D�„Ð#)F�4È#)™a0#-yÓ&¦�#)#) #)#)j"4ja �MOjjhõOÒf©“õOÕ=ª‡éG¨~¨È€#)ÿï¢ÿRÛjîßì›Rmlº'êÛjîR3GÆÛS�²L’�„F@«„O|QRÑ@B±#)�ÝÇåù~–µd³óÍæö;…ß[Ç3YuŒ™‹qâ±W/V÷iÌ(ÃЦÞáó3ýD7ÌÿCà1)ìH@lðbê¼0ΦV›Ê[Úl’:eª²Jܶ(d•¹qÓ+˜ëß-ð´ãy½n“Wy5xàÖ¶JëÂfä·pø¹Â³êÓT;Ä+›Iêqþ~Žß· ÷ÞmY«6±’¹ºUiZ¤²¨H„‚€B 2(�ÕB©b€<‚ƒ2#-#)^ „† ¨Ø€�ˆ¢�€{ …BÊ‚�A Õ HŒŠ¢�(UI€P`ÌJC3LH„ȆŒfѳ4D”ÔŠXÈ™)E1M´•#+L’X XMR¢²Pa(f‰²…²c%fPE™¢XКaJH¤Ø‹F(ŠIJ”ÍQ Á,´�T’ ƒ)"E¶“T,–libjF()%Ò$aflZ5¦Õ¦µR’mDÉ’d�E±µ+XÍ0Í™Lµ%“)¶Ä©¶&6j’ML,Š$š‹fF¤f´m!&™ ¦IF‚’ÒAh¥*’±‰‚#-34¦&›Á*S`˜@1f#-™&D¢$¡dªH)bY42DJB)%%,Rdƒh¦2R“jÔcPÙX˜QE),J$Ò)DÆ,LT&Sh¤™i¤‰ Å‘¤Œ’¥S0Ö�¨dQ,1&$$�MˆÔ–ËD�l‚‘%Æ’�¦l`’MIˆ¤ŒˆH™‘¤ 3„d¬Ë04%F"B$„©6�$“M-$É¢ÊSÍ¢4Ò(Њ!JHFh4‰3T²À‹)E%!“K$Ù¦Q 5,RY‘±£+$ÌI"‹@3c,�¨’È*#-Yš1´Y¤l”fSf‰)¦Á¡ˆL¦1¦Ô™)3#+4”³Q¤²¥FÅ(¤ÔDÄ™IJ#-hÐ$Œ�Ó"„ƒA `Íi´3Ye,‹&aJB›I²Ql‘hÒL’J‹%#+#X#+&QCd“f³5Ä`”¨e3Jb#-™4EK³Sb“(²2bJÙ$…”Tȱ4Á@ƈÚRdÒ’f&É£&B¡�F°“+)0Ú&ÉH$²e¦š‘”ÊFXŒ’•Mš*6�D&PL‰IZ1¶4“5‘CI�I#*4† %‰hÚ5)3V&ZL‰š)0’ȉB¥�£I�ÆQšCfÕM´UdÔÐ5’ƒe$mÉL“ÖKEš4�1”Í4Ù)J-LŒlÛ�#-›(ÊFh¡K_Ѥ,!�–Q’šÆÖŠÅ¢£BfTDÓl–ƒTÅI-SC`ÒÄPÒ”„ÒF³*jÔYÖL†ÆQiQ¤Z&LÆ¥¥˜É"¢Ã3)ªÍd5dlЦØV)²‰,¨ÊUbš´›HVlf¥)M0ÛLP¦DXÖ�5*$´Ê4FXÚ+fhÛ U™ª5XHÔ”m±´lJ5FhˆU…A¢Ö5FÃ5!µˆMd…¶š!”¢J)ÑF©D¦Ôª5$›F5!b´Éš¶³jÓA,56£e‘2¦²$ÌÍM)“-ªZŠZJf¦›3ZU+%T¡ �´©”¤ÚšV›1i45³Y™’JË3`Ô–ÒÚY¦”hˆÔi(Ò!l„dB‚™&6£jH”›Êm�¥&š*2dÐi)…#-)¥DlRK1¤B#+4S%2cYMš±!(TlY’Å+5%€ÆÙ–M,ÆSHED”¢LX0›16"(ÔlIIFFƒH³(µ31#-JƘLØ4dر0ÆÌµš(K@R!©M£!fm66(Ð�¤´Ð‘I‚°¥–ƒ "LVBi)Mƒ%±#-MJ"I6jQ UU31°Ø©M&ÈÚL¢Í%¬A!�¢J$L›)&„©-&dlÍ1*[,ØÚ#-ÊlÑDlblRi©&S&Š™mHÉ”´l””fÀ‰& b&4cL£E5–M’”11RBE¢±a6-(ÛZi0É3D”šE¢˜Ø¤ˆÅ‚ÙiI&¤0ɘi)fCL+F�„6�Elš4&XV‚ ’-%±Pca@ÑIªR‰«ÆS3B�’JÌŠ’‰-!¢,²Ö¦,ɨ´c+%¡¥(TiIMT²J’™JQ«b#+REJ4•FFÉcY4•5TÌS(©Kd-b¡¤™²E&ņ�B"Å‹LÉC4`ÚL‰3DŠ©Di„Ê[1¢ÑZ-Ф„*%0c)Q¨Ú6™% QI„I«J#--)ªSi5±¬Vɬ–³H#-Ñlš’‹Å(#(1³B$„ÆÉL0f¨‚�±±mSm¤¡–ˆ+šŠ‰#-Ñ3l³j6ŠÅE¬I&Ú”fÍ�ÒÊĪ1h¦Xªš“M¥FŠQ,˜²¥E ’¢ŠÉY-’�²jÅ&Ò™”Y6�#-F¢’�‹m¶kZhÍBÉb$©”mÂ�h4š–ÍY1‘‹´QÑZ5±h¶Ú6¨e“kb-SR³j&Ê@Ø‘´“6VR‹$lÒ¢(&cbH’L¤™Rm‹2Õ1òþ‹ýWô[î[Ï—_Î`¹z~*di)›ÿÓ¸[5BÓüåÕ¤\2#-Jd]ê¢$LLY”ÿ°‹0áÿWú¨Ö*j-ÁÈŸûó Ê6½õížÊD>{9ÆCp<X«šå�Ü–#-Y�3£XÇ]Ù�©ñTüZ¡�~‡tõê?�æ²Ë¿Æ”“&„lh;•L³¶»Yb"<ŽÂXA"!¢vÍÜ#®¿eìÑûõ9Û‰„g¥‹üHWt㬊ÑÁF‘ãàíi�r7¨£�Ûìkd˜RTÆÛ®W]§ƒmÅ1Ì”*»!¥¥dª2˜`qi#’¤�y6ª$¥TbZef*¨eÂÿméof›š�’Ö`–ßM׃ŒC »U„MÙ#)l×v$Ó½›šJ,Fï:ñOgnùöòŸøhþ˘C�Ê�5ªôI³,b"§ºŒ¥Œ‹"¯Ùþ\��µ£0#-�¥ïv†*�6P…¡COèW÷ç$Æ•ª¤–‰eHb?ã8ð}”N¶ ŽÃËÀË»3*Ò8‡¶Q#+ƒDãÊÆŸé¯‹2B<¸´#+8]¨"D`Äcy¹j)5Ý΋¸Ñ\Üɤ)5¤Š )‚ø ÌHe€a §Jñ¹ä�²&Z`E=ÔÄ¥:ð²ßKœó‚;a+⤔:0ŠHC¢Ø”‡Š¿šÖ÷ž—»UÔ¶önšv(Ñ‘AðùÞÞ–FDP£GäU£–�Å#+4©XMÈ@n##Ý×aÝtÑPo’ç�þåô]äKDkò.öéÖé5ßß9W‹mþ1üa8þy¼÷Çý�Ǧ‡þ‰Ë$�õ1ÒBº»oç®Õʺ›\å»ù3ëÜûóK¨ˆ¦¦q,*´’�¾«^Û—â5Ïé?o�LÍÄV«8;B¿M\ę䡎²5m\¿Â§jjœ+�C»�²xqÖýé;Q#+èt%Öý]O,㱌Ÿ+]ðq P튀€ …?N`g{„3«BŠLÓÙtm éì•,XZ2ékÑcaþëÆ.ì1‰¶“¼°¥‚Á/N·�½øâŒ=P*']h³f ØÒ‚ˆµâ—šÅºº]ý¹Î$PÍ]œóÉßÏî·à2o±Úl’Œ…í„G°�m&žÆ»RO‹<†\ˆïHÔ_ûÍ/yT�6·£\-V)(ºµcÇz.KzíÙõwåÝM¢Œh¯Ì²oÍr±ªý·”Ôi÷ÜY0Êî ÷6£ÿn§_ñT8™*’S#+wWlF4X1ˆÂjOJJCÝŽ¹Ä„–4$RÚg^u„ÂEä… ä!BKII¦ÇÙŠ" ³•_�ìòcâã(ß®k�øq¤¶L/n·_òó¼ã±cX²UõOö‹Ý\�¯Æê¯;ò‡¥àaóÔ4ý#ŠÀŒ8Òãß#)ñçT¦‰Ï%Cˆ.•µ›3É �‚ˆ©#+{öžFæÝMñ.¤h®q,Uõõ&Ã!IµP]e‚ÁÒ€ö¤±G)QˆÒB„¶¡5uªSfÐ@ïª-¥Q4í»€ßËÏ–ÀÕàÂÓ·YRL•HÀ^Ö᪒©�¤·hœÜC%¨ú1ÙXm¥§d™j(ø‘³±£FoœÄ8W�Ьñí¨y³#)£É¥òíIžÙõŠû¤<Ù>Û;öß—Ï5îè)ÚÌãÚˆ«ÕF1tÊ� ¨ù\Û 9Ê©EJ‰©,9QFþ~·‡|T°ðIHDä”H¤&h ØÁž�*‡æOfÔÄ0„Œm6¡4‡f+«�û®÷åyaðá½ö²uCaÇêÌ!ýþ•jiÈ�LjN ¡Îê½&òéïƒÖšÍ˜tjɬ!H#-©K”[ï¢åbé–‹v#W*ƒÆ‰’Ù7¯tCefCáPoZïtÅF%‹�3ü2gP¦þU³|¸ÑsW½P‘Ñz×NÒ˜ûÈqe9/Ó8û/ùxÏ~yŒÅC¾ù$ǶóÆV1^75&}U4E9ùiö˜UˆüÔs[HB 5z¯lX?tB|å/tM Ø¥µ Line truncated
|
||||
#<==
|
||||
@@ -20,7 +20,7 @@ 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/>.
|
||||
"""
|
||||
|
||||
VERSION = '0.2.0'
|
||||
VERSION = '0.2.1'
|
||||
APPNAME = "nlsr"
|
||||
BUGREPORT = "http://redmine.named-data.net/projects/nlsr"
|
||||
URL = "http://named-data.net/doc/NLSR/"
|
||||
|
||||
Reference in new issue
Block a user