table: Offload the implicit digest calculation to the library
Change-Id: I8577ec3ee194d639cce74b53fb5f02c7e718cbc3
Refs: #1678
diff --git a/daemon/table/cs-entry.cpp b/daemon/table/cs-entry.cpp
index 447c710..1262065 100644
--- a/daemon/table/cs-entry.cpp
+++ b/daemon/table/cs-entry.cpp
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014 Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology
+ * Copyright (c) 2014, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -21,7 +22,9 @@
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
- * \author Ilya Moiseenko <iliamo@ucla.edu>
+ * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
+ * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
+ * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#include "cs-entry.hpp"
@@ -38,8 +41,6 @@
BOOST_ASSERT(m_layerIterators.empty());
m_dataPacket.reset();
- m_digest.reset();
- m_nameWithDigest.clear();
}
void
@@ -47,24 +48,8 @@
{
m_isUnsolicited = isUnsolicited;
m_dataPacket = data.shared_from_this();
- m_digest.reset();
updateStaleTime();
-
- m_nameWithDigest = data.getName();
- m_nameWithDigest.append(ndn::name::Component(getDigest()));
-}
-
-void
-Entry::setData(const Data& data, bool isUnsolicited, const ndn::ConstBufferPtr& digest)
-{
- m_dataPacket = data.shared_from_this();
- m_digest = digest;
-
- updateStaleTime();
-
- m_nameWithDigest = data.getName();
- m_nameWithDigest.append(ndn::name::Component(getDigest()));
}
void
@@ -73,18 +58,6 @@
m_staleAt = time::steady_clock::now() + m_dataPacket->getFreshnessPeriod();
}
-const ndn::ConstBufferPtr&
-Entry::getDigest() const
-{
- if (!static_cast<bool>(m_digest))
- {
- const Block& block = m_dataPacket->wireEncode();
- m_digest = ndn::crypto::sha256(block.wire(), block.size());
- }
-
- return m_digest;
-}
-
void
Entry::setIterator(int layer, const Entry::LayerIterators::mapped_type& layerIterator)
{
diff --git a/daemon/table/cs-entry.hpp b/daemon/table/cs-entry.hpp
index 2150b32..0373e60 100644
--- a/daemon/table/cs-entry.hpp
+++ b/daemon/table/cs-entry.hpp
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014 Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology
+ * Copyright (c) 2014, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -21,17 +22,17 @@
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
- * \author Ilya Moiseenko <iliamo@ucla.edu>
+ * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
+ * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
+ * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#ifndef NFD_DAEMON_TABLE_CS_ENTRY_HPP
#define NFD_DAEMON_TABLE_CS_ENTRY_HPP
#include "common.hpp"
-#include <ndn-cxx/util/crypto.hpp>
namespace nfd {
-
namespace cs {
class Entry;
@@ -56,6 +57,13 @@
const Name&
getName() const;
+ /** \brief returns the full name (including implicit digest) of the Data packet stored
+ * in the CS entry
+ * \return{ NDN name }
+ */
+ const Name&
+ getFullName() const;
+
/** \brief Data packet is unsolicited if this particular NDN node
* did not receive an Interest packet for it, or the Interest packet has already expired
* \return{ True if the Data packet is unsolicited; otherwise False }
@@ -79,22 +87,12 @@
void
setData(const Data& data, bool isUnsolicited);
- /** \brief changes the content of CS entry and modifies digest
- */
- void
- setData(const Data& data, bool isUnsolicited, const ndn::ConstBufferPtr& digest);
-
/** \brief refreshes the time when Data becomes expired
* according to the current absolute time.
*/
void
updateStaleTime();
- /** \brief returns the digest of the Data packet stored in the CS entry.
- */
- const ndn::ConstBufferPtr&
- getDigest() const;
-
/** \brief saves the iterator pointing to the CS entry on a specific layer of skip list
*/
void
@@ -121,9 +119,6 @@
shared_ptr<const Data> m_dataPacket;
bool m_isUnsolicited;
- Name m_nameWithDigest;
-
- mutable ndn::ConstBufferPtr m_digest;
LayerIterators m_layerIterators;
};
@@ -136,7 +131,13 @@
inline const Name&
Entry::getName() const
{
- return m_nameWithDigest;
+ return m_dataPacket->getName();
+}
+
+inline const Name&
+Entry::getFullName() const
+{
+ return m_dataPacket->getFullName();
}
inline const Data&
diff --git a/daemon/table/cs.cpp b/daemon/table/cs.cpp
index f1bbb0f..2c1b657 100644
--- a/daemon/table/cs.cpp
+++ b/daemon/table/cs.cpp
@@ -22,14 +22,18 @@
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
- * \author Ilya Moiseenko <iliamo@ucla.edu>
+ * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
+ * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
+ * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#include "cs.hpp"
#include "core/logger.hpp"
#include "core/random.hpp"
+
#include <ndn-cxx/util/crypto.hpp>
#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>
+
#include <boost/random/bernoulli_distribution.hpp>
/// max skip list layers
@@ -106,7 +110,7 @@
std::pair<cs::Entry*, bool>
Cs::insertToSkipList(const Data& data, bool isUnsolicited)
{
- NFD_LOG_TRACE("insertToSkipList() " << data.getName() << ", "
+ NFD_LOG_TRACE("insertToSkipList() " << data.getFullName() << ", "
<< "skipList size " << size());
BOOST_ASSERT(m_cleanupIndex.size() <= size());
@@ -139,7 +143,7 @@
if (head != (*rit)->end())
{
// it can happen when begin() contains the element in front of which we need to insert
- if (!isIterated && ((*head)->getName() >= entry->getName()))
+ if (!isIterated && ((*head)->getFullName() >= entry->getFullName()))
{
--updateTable[layer];
insertInFront = true;
@@ -148,7 +152,7 @@
{
SkipListLayer::iterator it = head;
- while ((*it)->getName() < entry->getName())
+ while ((*it)->getFullName() < entry->getFullName())
{
head = it;
updateTable[layer] = it;
@@ -180,7 +184,7 @@
bool isNameIdentical = false;
if (!isCsEmpty && isInBoundaries)
{
- isNameIdentical = (*head)->getName() == entry->getName();
+ isNameIdentical = (*head)->getFullName() == entry->getFullName();
}
//check if this is a duplicate packet
@@ -188,7 +192,7 @@
{
NFD_LOG_TRACE("Duplicate name (with digest)");
- (*head)->setData(data, isUnsolicited, entry->getDigest()); //updates stale time
+ (*head)->setData(data, isUnsolicited); //updates stale time
// new entry not needed, returning to the pool
entry->release();
@@ -246,7 +250,7 @@
bool
Cs::insert(const Data& data, bool isUnsolicited)
{
- NFD_LOG_TRACE("insert() " << data.getName());
+ NFD_LOG_TRACE("insert() " << data.getFullName());
if (isFull())
{
@@ -292,7 +296,7 @@
bool
Cs::eraseFromSkipList(cs::Entry* entry)
{
- NFD_LOG_TRACE("eraseFromSkipList() " << entry->getName());
+ NFD_LOG_TRACE("eraseFromSkipList() " << entry->getFullName());
NFD_LOG_TRACE("SkipList size " << size());
bool isErased = false;
@@ -399,7 +403,7 @@
if (head != (*rit)->end())
{
// it happens when begin() contains the element we want to find
- if (!isIterated && (interest.getName().isPrefixOf((*head)->getName())))
+ if (!isIterated && (interest.getName().isPrefixOf((*head)->getFullName())))
{
if (layer > 0)
{
@@ -415,9 +419,9 @@
{
SkipListLayer::iterator it = head;
- while ((*it)->getName() < interest.getName())
+ while ((*it)->getFullName() < interest.getName())
{
- NFD_LOG_TRACE((*it)->getName() << " < " << interest.getName());
+ NFD_LOG_TRACE((*it)->getFullName() << " < " << interest.getName());
head = it;
isIterated = true;
@@ -452,11 +456,11 @@
if (startingPoint != (*m_skipList.begin())->begin())
{
- BOOST_ASSERT((*startingPoint)->getName() < interest.getName());
+ BOOST_ASSERT((*startingPoint)->getFullName() < interest.getName());
}
NFD_LOG_TRACE("selectChild() " << interest.getChildSelector() << " "
- << (*startingPoint)->getName());
+ << (*startingPoint)->getFullName());
bool hasLeftmostSelector = (interest.getChildSelector() <= 0);
bool hasRightmostSelector = !hasLeftmostSelector;
@@ -468,11 +472,11 @@
if (doesInterestContainDigest)
{
- isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getName());
+ isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getFullName());
}
else
{
- isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getName());
+ isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getFullName());
}
if (isInPrefix)
@@ -506,11 +510,11 @@
if (doesInterestContainDigest)
{
isInPrefix = interest.getName().getPrefix(-1)
- .isPrefixOf((*rightmostCandidate)->getName());
+ .isPrefixOf((*rightmostCandidate)->getFullName());
}
else
{
- isInPrefix = interest.getName().isPrefixOf((*rightmostCandidate)->getName());
+ isInPrefix = interest.getName().isPrefixOf((*rightmostCandidate)->getFullName());
}
}
@@ -529,7 +533,7 @@
{
// get prefix which is one component longer than Interest name
// (without digest)
- const Name& childPrefix = (*rightmostCandidate)->getName()
+ const Name& childPrefix = (*rightmostCandidate)->getFullName()
.getPrefix(interest.getName().size());
NFD_LOG_TRACE("Child prefix" << childPrefix);
@@ -542,7 +546,7 @@
else
{
// get prefix which is one component longer than Interest name
- const Name& childPrefix = (*rightmostCandidate)->getName()
+ const Name& childPrefix = (*rightmostCandidate)->getFullName()
.getPrefix(interest.getName().size() + 1);
NFD_LOG_TRACE("Child prefix" << childPrefix);
@@ -572,11 +576,11 @@
if (doesInterestContainDigest)
{
- isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getName());
+ isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getFullName());
}
else
{
- isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getName());
+ isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getFullName());
}
if (isInPrefix)
@@ -599,19 +603,14 @@
NFD_LOG_TRACE("doesComplyWithSelectors()");
/// \todo The following detection is not correct
- /// 1. If data name ends with 32-octet component doesn't mean that this component is digest
+ /// 1. If Interest name ends with 32-octet component doesn't mean that this component is
+ /// digest
/// 2. Only min/max selectors (both 0) can be specified, all other selectors do not
/// make sense for interests with digest (though not sure if we need to enforce this)
if (doesInterestContainDigest)
{
- const ndn::name::Component& last = interest.getName().get(-1);
- const ndn::ConstBufferPtr& digest = entry->getDigest();
-
- BOOST_ASSERT(digest->size() == last.value_size());
- BOOST_ASSERT(digest->size() == ndn::crypto::SHA256_DIGEST_SIZE);
-
- if (std::memcmp(digest->buf(), last.value(), ndn::crypto::SHA256_DIGEST_SIZE) != 0)
+ if (interest.getName().get(-1) != entry->getFullName().get(-1))
{
NFD_LOG_TRACE("violates implicit digest");
return false;
@@ -624,7 +623,7 @@
{
size_t minDataNameLength = interest.getName().size() + interest.getMinSuffixComponents();
- bool isSatisfied = (minDataNameLength <= entry->getName().size());
+ bool isSatisfied = (minDataNameLength <= entry->getFullName().size());
if (!isSatisfied)
{
NFD_LOG_TRACE("violates minComponents");
@@ -636,7 +635,7 @@
{
size_t maxDataNameLength = interest.getName().size() + interest.getMaxSuffixComponents();
- bool isSatisfied = (maxDataNameLength >= entry->getName().size());
+ bool isSatisfied = (maxDataNameLength >= entry->getFullName().size());
if (!isSatisfied)
{
NFD_LOG_TRACE("violates maxComponents");
@@ -671,7 +670,7 @@
if (doesInterestContainDigest)
{
- const ndn::name::Component& lastComponent = entry->getName().get(-1);
+ const ndn::name::Component& lastComponent = entry->getFullName().get(-1);
if (!lastComponent.empty())
{
@@ -684,9 +683,9 @@
}
else
{
- if (entry->getName().size() >= interest.getName().size() + 1)
+ if (entry->getFullName().size() >= interest.getName().size() + 1)
{
- const ndn::name::Component& nextComponent = entry->getName()
+ const ndn::name::Component& nextComponent = entry->getFullName()
.get(interest.getName().size());
if (!nextComponent.empty())
{
@@ -709,7 +708,7 @@
// only when min selector is not specified or specified with value of 0
// and Interest's name length is exactly the length of the name of CS entry
if (interest.getMinSuffixComponents() <= 0 &&
- interest.getName().size() == (entry->getName().size()))
+ interest.getName().size() == (entry->getFullName().size()))
{
const ndn::name::Component& last = interest.getName().get(-1);
if (last.value_size() == ndn::crypto::SHA256_DIGEST_SIZE)
@@ -748,7 +747,7 @@
if (head != (*rit)->end())
{
// it can happen when begin() contains the element we want to remove
- if (!isIterated && ((*head)->getName() == exactName))
+ if (!isIterated && ((*head)->getFullName() == exactName))
{
eraseFromSkipList(*head);
return;
@@ -757,7 +756,7 @@
{
SkipListLayer::iterator it = head;
- while ((*it)->getName() < exactName)
+ while ((*it)->getFullName() < exactName)
{
head = it;
updateTable[layer] = it;
@@ -789,13 +788,13 @@
bool isNameIdentical = false;
if (!isCsEmpty && isInBoundaries)
{
- NFD_LOG_TRACE("Identical? " << (*head)->getName());
- isNameIdentical = (*head)->getName() == exactName;
+ NFD_LOG_TRACE("Identical? " << (*head)->getFullName());
+ isNameIdentical = (*head)->getFullName() == exactName;
}
if (isNameIdentical)
{
- NFD_LOG_TRACE("Found target " << (*head)->getName());
+ NFD_LOG_TRACE("Found target " << (*head)->getFullName());
eraseFromSkipList(*head);
}
}
@@ -810,7 +809,7 @@
{
for (SkipListLayer::iterator it = (*rit)->begin(); it != (*rit)->end(); ++it)
{
- NFD_LOG_TRACE("Layer " << layer << " " << (*it)->getName());
+ NFD_LOG_TRACE("Layer " << layer << " " << (*it)->getFullName());
}
layer--;
}
diff --git a/daemon/table/cs.hpp b/daemon/table/cs.hpp
index c523293..67cc611 100644
--- a/daemon/table/cs.hpp
+++ b/daemon/table/cs.hpp
@@ -22,7 +22,9 @@
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
- * \author Ilya Moiseenko <iliamo@ucla.edu>
+ * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
+ * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
+ * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
#ifndef NFD_DAEMON_TABLE_CS_HPP
diff --git a/tests/daemon/table/cs.cpp b/tests/daemon/table/cs.cpp
index 3e41781..3592290 100644
--- a/tests/daemon/table/cs.cpp
+++ b/tests/daemon/table/cs.cpp
@@ -165,11 +165,13 @@
Name name2("/insert/fresh");
shared_ptr<Data> data2 = makeData(name2);
data2->setFreshnessPeriod(time::milliseconds(5000));
+ signData(data2);
cs.insert(*data2);
Name name("/insert/expire");
shared_ptr<Data> data = makeData(name);
data->setFreshnessPeriod(time::milliseconds(500));
+ signData(data);
cs.insert(*data);
BOOST_CHECK_EQUAL(cs.size(), 2);
@@ -264,7 +266,8 @@
entry->setData(*data, false);
BOOST_CHECK_EQUAL_COLLECTIONS(digest1->begin(), digest1->end(),
- entry->getDigest()->begin(), entry->getDigest()->end());
+ entry->getFullName()[-1].value_begin(),
+ entry->getFullName()[-1].value_end());
}
BOOST_AUTO_TEST_CASE(InsertCanonical)
@@ -429,6 +432,7 @@
Name name("/insert/nonfresh");
shared_ptr<Data> data = makeData(name);
data->setFreshnessPeriod(time::milliseconds(500));
+ signData(data);
cs.insert(*data);
sleep(1);
@@ -477,6 +481,7 @@
fakeSignature.setKeyLocator(locator);
data2->setSignature(fakeSignature);
+ data2->wireEncode();
cs.insert(*data2);
@@ -602,6 +607,7 @@
shared_ptr<Data> data = makeData(name);
data->setFreshnessPeriod(time::milliseconds(99999));
data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
+ signData(data);
m_cs.insert(*data);
}
diff --git a/tests/test-common.hpp b/tests/test-common.hpp
index 6b67f2f..9c60c77 100644
--- a/tests/test-common.hpp
+++ b/tests/test-common.hpp
@@ -67,10 +67,8 @@
}
inline shared_ptr<Data>
-makeData(const Name& name)
+signData(const shared_ptr<Data>& data)
{
- shared_ptr<Data> data = make_shared<Data>(name);
-
ndn::SignatureSha256WithRsa fakeSignature;
fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
reinterpret_cast<const uint8_t*>(0), 0));
@@ -80,6 +78,15 @@
return data;
}
+inline shared_ptr<Data>
+makeData(const Name& name)
+{
+ shared_ptr<Data> data = make_shared<Data>(name);
+
+ return signData(data);
+}
+
+
} // namespace tests
} // namespace nfd