interest: refactor nonce handling
Nonce is a sequence of 4 bytes, not a 32-bit unsigned integer.
This also fixes various endianness bugs in unit tests.
Refs: #3294
Change-Id: I057b7b771fecb0bc997b0b11a03e6660c9b7a826
diff --git a/.travis.yml b/.travis.yml
index a240836..f991bb9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,14 +10,10 @@
- s390x
env:
- global:
- - JOB_NAME=limited-build
- - WAF_JOBS=2
- jobs:
- - COMPILER=g++-7
- - COMPILER=g++-9
- - COMPILER=clang++-6.0
- - COMPILER=clang++-9
+ - COMPILER=g++-7
+ - COMPILER=g++-9
+ - COMPILER=clang++-6.0
+ - COMPILER=clang++-9
jobs:
include:
@@ -76,13 +72,15 @@
before_script:
- |
: Setting environment variables
+ if [[ -n ${COMPILER} ]]; then
+ export CXX=${COMPILER}
+ fi
case ${TRAVIS_OS_NAME} in
linux) export NODE_LABELS="Linux Ubuntu Ubuntu-18.04" ;;
osx) export NODE_LABELS="OSX OSX-$(sw_vers -productVersion | cut -d . -f -2)" ;;
esac
- if [[ -n ${COMPILER} ]]; then
- export CXX=${COMPILER}
- fi
+ export JOB_NAME=limited-build
+ export WAF_JOBS=2
- |
: Enabling workarounds
case "${TRAVIS_CPU_ARCH},${COMPILER}" in
diff --git a/ndn-cxx/impl/common-pch.hpp b/ndn-cxx/impl/common-pch.hpp
index 7f1ab5a..877c6e7 100644
--- a/ndn-cxx/impl/common-pch.hpp
+++ b/ndn-cxx/impl/common-pch.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -28,18 +28,21 @@
#include "ndn-cxx/detail/common.hpp"
// STL headers to precompile
+#include <array>
+#include <cstring>
#include <fstream>
+#include <iterator>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <unordered_map>
-#include <unordered_set>
#include <vector>
// Boost headers to precompile
#include <boost/algorithm/string.hpp>
#include <boost/chrono.hpp>
+#include <boost/endian/conversion.hpp>
#include <boost/filesystem.hpp>
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/stream.hpp>
diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp
index 00a3249..5ebc21e 100644
--- a/ndn-cxx/interest.cpp
+++ b/ndn-cxx/interest.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -127,8 +127,7 @@
// HopLimit
if (getHopLimit()) {
- uint8_t hopLimit = *getHopLimit();
- totalLength += encoder.prependByteArrayBlock(tlv::HopLimit, &hopLimit, sizeof(hopLimit));
+ totalLength += encoder.prependByteArrayBlock(tlv::HopLimit, &*m_hopLimit, 1);
}
// InterestLifetime
@@ -138,8 +137,9 @@
}
// Nonce
- uint32_t nonce = getNonce(); // if nonce was unset, this generates a fresh nonce
- totalLength += encoder.prependByteArrayBlock(tlv::Nonce, reinterpret_cast<uint8_t*>(&nonce), sizeof(nonce));
+ getNonce(); // if nonce was unset, this generates a fresh nonce
+ BOOST_ASSERT(hasNonce());
+ totalLength += encoder.prependByteArrayBlock(tlv::Nonce, m_nonce->data(), m_nonce->size());
// ForwardingHint
if (!getForwardingHint().empty()) {
@@ -262,12 +262,11 @@
if (lastElement >= 5) {
NDN_THROW(Error("Nonce element is out of order"));
}
- uint32_t nonce = 0;
- if (element->value_size() != sizeof(nonce)) {
+ if (element->value_size() != Nonce().size()) {
NDN_THROW(Error("Nonce element is malformed"));
}
- std::memcpy(&nonce, element->value(), sizeof(nonce));
- m_nonce = nonce;
+ m_nonce.emplace();
+ std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
lastElement = 5;
break;
}
@@ -396,18 +395,27 @@
return *this;
}
-uint32_t
+static auto
+generateNonce()
+{
+ uint32_t r = random::generateWord32();
+ Interest::Nonce n;
+ std::memcpy(n.data(), &r, sizeof(r));
+ return n;
+}
+
+Interest::Nonce
Interest::getNonce() const
{
if (!hasNonce()) {
- m_nonce = random::generateWord32();
+ m_nonce = generateNonce();
m_wire.reset();
}
return *m_nonce;
}
Interest&
-Interest::setNonce(uint32_t nonce)
+Interest::setNonce(optional<Interest::Nonce> nonce)
{
if (nonce != m_nonce) {
m_nonce = nonce;
@@ -422,9 +430,9 @@
if (!hasNonce())
return;
- uint32_t oldNonce = *m_nonce;
+ auto oldNonce = *m_nonce;
while (m_nonce == oldNonce)
- m_nonce = random::generateWord32();
+ m_nonce = generateNonce();
m_wire.reset();
}
diff --git a/ndn-cxx/interest.hpp b/ndn-cxx/interest.hpp
index c386ce8..f69b855 100644
--- a/ndn-cxx/interest.hpp
+++ b/ndn-cxx/interest.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -23,10 +23,14 @@
#define NDN_INTEREST_HPP
#include "ndn-cxx/delegation-list.hpp"
-#include "ndn-cxx/name.hpp"
#include "ndn-cxx/detail/packet-base.hpp"
+#include "ndn-cxx/name.hpp"
+#include "ndn-cxx/util/string-helper.hpp"
#include "ndn-cxx/util/time.hpp"
+#include <array>
+
+#include <boost/endian/conversion.hpp>
#include <boost/logic/tribool.hpp>
namespace ndn {
@@ -49,6 +53,52 @@
using tlv::Error::Error;
};
+ class Nonce final : public std::array<uint8_t, 4>
+ {
+ using Base = std::array<uint8_t, 4>;
+
+ public:
+ Nonce() = default;
+
+ // implicit conversion from uint32_t
+ Nonce(uint32_t n) noexcept
+ {
+ boost::endian::native_to_big_inplace(n);
+ std::memcpy(data(), &n, sizeof(n));
+ }
+
+ Nonce(uint8_t n1, uint8_t n2, uint8_t n3, uint8_t n4) noexcept
+ {
+ data()[0] = n1;
+ data()[1] = n2;
+ data()[2] = n3;
+ data()[3] = n4;
+ }
+
+ private: // non-member operators
+ // NOTE: the following "hidden friend" operators are available via
+ // argument-dependent lookup only and must be defined inline.
+
+ friend bool
+ operator==(const Nonce& lhs, const Nonce& rhs) noexcept
+ {
+ return static_cast<const Base&>(lhs) == static_cast<const Base&>(rhs);
+ }
+
+ friend bool
+ operator!=(const Nonce& lhs, const Nonce& rhs) noexcept
+ {
+ return static_cast<const Base&>(lhs) != static_cast<const Base&>(rhs);
+ }
+
+ friend std::ostream&
+ operator<<(std::ostream& os, const Nonce& nonce)
+ {
+ printHex(os, nonce.data(), nonce.size(), false);
+ return os;
+ }
+ };
+
/** @brief Construct an Interest with given @p name and @p lifetime.
*
* @throw std::invalid_argument @p name is invalid or @p lifetime is negative
@@ -228,13 +278,15 @@
*
* If nonce was not present, it is added and assigned a random value.
*/
- uint32_t
+ Nonce
getNonce() const;
- /** @brief Set nonce value.
+ /** @brief Set the Interest's nonce.
+ *
+ * Use `setNonce(nullopt)` to remove any nonce from the Interest.
*/
Interest&
- setNonce(uint32_t nonce);
+ setNonce(optional<Nonce> nonce);
/** @brief Change nonce value.
*
@@ -392,7 +444,7 @@
Name m_name;
DelegationList m_forwardingHint;
- mutable optional<uint32_t> m_nonce;
+ mutable optional<Nonce> m_nonce;
time::milliseconds m_interestLifetime;
optional<uint8_t> m_hopLimit;
mutable bool m_isCanBePrefixSet = false;
diff --git a/ndn-cxx/util/string-helper.cpp b/ndn-cxx/util/string-helper.cpp
index 06b08a6..d0afc19 100644
--- a/ndn-cxx/util/string-helper.cpp
+++ b/ndn-cxx/util/string-helper.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -20,7 +20,6 @@
*/
#include "ndn-cxx/util/string-helper.hpp"
-#include "ndn-cxx/encoding/buffer.hpp"
#include "ndn-cxx/encoding/buffer-stream.hpp"
#include "ndn-cxx/security/transform/buffer-source.hpp"
#include "ndn-cxx/security/transform/hex-decode.hpp"
@@ -31,13 +30,6 @@
namespace ndn {
-std::ostream&
-operator<<(std::ostream& os, const AsHex& hex)
-{
- printHex(os, hex.m_value, os.flags() & std::ostream::uppercase);
- return os;
-}
-
void
printHex(std::ostream& os, uint64_t num, bool wantUpperCase)
{
@@ -57,12 +49,6 @@
tr::bufferSource(buffer, length) >> tr::hexEncode(wantUpperCase) >> tr::streamSink(os);
}
-void
-printHex(std::ostream& os, const Buffer& buffer, bool wantUpperCase)
-{
- return printHex(os, buffer.data(), buffer.size(), wantUpperCase);
-}
-
std::string
toHex(const uint8_t* buffer, size_t length, bool wantUpperCase)
{
@@ -71,12 +57,6 @@
return result.str();
}
-std::string
-toHex(const Buffer& buffer, bool wantUpperCase)
-{
- return toHex(buffer.data(), buffer.size(), wantUpperCase);
-}
-
shared_ptr<Buffer>
fromHex(const std::string& hexString)
{
diff --git a/ndn-cxx/util/string-helper.hpp b/ndn-cxx/util/string-helper.hpp
index 97973da..b923317 100644
--- a/ndn-cxx/util/string-helper.hpp
+++ b/ndn-cxx/util/string-helper.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,12 +22,10 @@
#ifndef NDN_UTIL_STRING_HELPER_HPP
#define NDN_UTIL_STRING_HELPER_HPP
-#include "ndn-cxx/detail/common.hpp"
+#include "ndn-cxx/encoding/buffer.hpp"
namespace ndn {
-class Buffer;
-
class StringHelperError : public std::invalid_argument
{
public:
@@ -35,35 +33,6 @@
};
/**
- * @brief Helper class to convert a number to hexadecimal
- * format, for use with stream insertion operators
- *
- * Example usage:
- *
- * @code
- * std::cout << AsHex{42}; // outputs "0x2a"
- * std::cout << std::uppercase << AsHex{42}; // outputs "0x2A"
- * @endcode
- */
-class AsHex
-{
-public:
- constexpr explicit
- AsHex(uint64_t val) noexcept
- : m_value(val)
- {
- }
-
-private:
- uint64_t m_value;
-
- friend std::ostream& operator<<(std::ostream&, const AsHex&);
-};
-
-std::ostream&
-operator<<(std::ostream& os, const AsHex& hex);
-
-/**
* @brief Output the hex representation of @p num to the output stream @p os
*
* @param os Output stream
@@ -104,8 +73,43 @@
* @param buffer Buffer of bytes to print in hexadecimal format
* @param wantUpperCase if true (the default) print uppercase hex chars
*/
-void
-printHex(std::ostream& os, const Buffer& buffer, bool wantUpperCase = true);
+inline void
+printHex(std::ostream& os, const Buffer& buffer, bool wantUpperCase = true)
+{
+ return printHex(os, buffer.data(), buffer.size(), wantUpperCase);
+}
+
+/**
+ * @brief Helper class to convert a number to hexadecimal
+ * format, for use with stream insertion operators
+ *
+ * Example usage:
+ *
+ * @code
+ * std::cout << AsHex{42}; // outputs "0x2a"
+ * std::cout << std::uppercase << AsHex{42}; // outputs "0x2A"
+ * @endcode
+ */
+class AsHex
+{
+public:
+ constexpr explicit
+ AsHex(uint64_t val) noexcept
+ : m_value(val)
+ {
+ }
+
+private:
+ friend std::ostream&
+ operator<<(std::ostream& os, const AsHex& hex)
+ {
+ printHex(os, hex.m_value, os.flags() & std::ostream::uppercase);
+ return os;
+ }
+
+private:
+ uint64_t m_value;
+};
/**
* @brief Return a string containing the hex representation of the bytes in @p buffer
@@ -134,8 +138,11 @@
* @param buffer Buffer of bytes to convert to hexadecimal format
* @param wantUpperCase if true (the default) use uppercase hex chars
*/
-NDN_CXX_NODISCARD std::string
-toHex(const Buffer& buffer, bool wantUpperCase = true);
+NDN_CXX_NODISCARD inline std::string
+toHex(const Buffer& buffer, bool wantUpperCase = true)
+{
+ return toHex(buffer.data(), buffer.size(), wantUpperCase);
+}
/**
* @brief Convert the hex string to buffer
diff --git a/tests/make-interest-data.cpp b/tests/make-interest-data.cpp
index 76b2f44..4031507 100644
--- a/tests/make-interest-data.cpp
+++ b/tests/make-interest-data.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -27,13 +27,12 @@
namespace tests {
shared_ptr<Interest>
-makeInterest(const Name& name, bool canBePrefix, time::milliseconds lifetime, uint32_t nonce)
+makeInterest(const Name& name, bool canBePrefix, time::milliseconds lifetime,
+ optional<Interest::Nonce> nonce)
{
auto interest = make_shared<Interest>(name, lifetime);
interest->setCanBePrefix(canBePrefix);
- if (nonce != 0) {
- interest->setNonce(nonce);
- }
+ interest->setNonce(nonce);
return interest;
}
@@ -55,20 +54,12 @@
}
lp::Nack
-makeNack(const Interest& interest, lp::NackReason reason)
+makeNack(Interest interest, lp::NackReason reason)
{
- lp::Nack nack(interest);
+ lp::Nack nack(std::move(interest));
nack.setReason(reason);
return nack;
}
-lp::Nack
-makeNack(const Name& name, uint32_t nonce, lp::NackReason reason)
-{
- Interest interest(name);
- interest.setNonce(nonce);
- return makeNack(interest, reason);
-}
-
} // namespace tests
} // namespace ndn
diff --git a/tests/make-interest-data.hpp b/tests/make-interest-data.hpp
index 10381fd..2d12011 100644
--- a/tests/make-interest-data.hpp
+++ b/tests/make-interest-data.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -24,21 +24,17 @@
#include "ndn-cxx/data.hpp"
#include "ndn-cxx/interest.hpp"
-#include "ndn-cxx/link.hpp"
#include "ndn-cxx/lp/nack.hpp"
namespace ndn {
namespace tests {
/** \brief create an Interest
- * \param name Interest name
- * \param canBePrefix CanBePrefix setting
- * \param lifetime InterestLifetime
- * \param nonce if non-zero, set Nonce to this value (useful for creating Nack with same Nonce)
*/
shared_ptr<Interest>
makeInterest(const Name& name, bool canBePrefix = false,
- time::milliseconds lifetime = DEFAULT_INTEREST_LIFETIME, uint32_t nonce = 0);
+ time::milliseconds lifetime = DEFAULT_INTEREST_LIFETIME,
+ optional<Interest::Nonce> nonce = nullopt);
/** \brief create a Data with fake signature
* \note Data may be modified afterwards without losing the fake signature.
@@ -62,11 +58,9 @@
}
/** \brief create a Nack
- * \param interest Interest
- * \param reason Nack reason
*/
lp::Nack
-makeNack(const Interest& interest, lp::NackReason reason);
+makeNack(Interest interest, lp::NackReason reason);
/** \brief replace a name component in a packet
* \param[inout] pkt the packet
diff --git a/tests/unit/interest.t.cpp b/tests/unit/interest.t.cpp
index 7b8f843..1787b87 100644
--- a/tests/unit/interest.t.cpp
+++ b/tests/unit/interest.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -75,13 +75,13 @@
0x08, 0x03, 0x6e, 0x64, 0x6e, // GenericNameComponent
0x08, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, // GenericNameComponent
0x0a, 0x04, // Nonce
- 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x03, 0x04,
};
Interest i1;
i1.setName("/local/ndn/prefix");
i1.setCanBePrefix(false);
- i1.setNonce(1);
+ i1.setNonce(0x01020304);
BOOST_CHECK_EQUAL(i1.isParametersDigestValid(), true);
Block wire1 = i1.wireEncode();
@@ -93,7 +93,7 @@
BOOST_CHECK_EQUAL(i2.getMustBeFresh(), false);
BOOST_CHECK_EQUAL(i2.getForwardingHint().empty(), true);
BOOST_CHECK_EQUAL(i2.hasNonce(), true);
- BOOST_CHECK_EQUAL(i2.getNonce(), 1);
+ BOOST_CHECK_EQUAL(i2.getNonce(), 0x01020304);
BOOST_CHECK_EQUAL(i2.getInterestLifetime(), DEFAULT_INTEREST_LIFETIME);
BOOST_CHECK(i2.getHopLimit() == nullopt);
BOOST_CHECK_EQUAL(i2.hasApplicationParameters(), false);
@@ -113,7 +113,7 @@
0x26, 0xa0, 0x51, 0xba, 0x25, 0xf5, 0x6b, 0x69, 0xbf, 0xa0, 0x26, 0xdc,
0xcc, 0xd7, 0x2c, 0x6e, 0xa0, 0xf7, 0x31, 0x5a,
0x0a, 0x04, // Nonce
- 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
0x24, 0x04, // ApplicationParameters
0xc0, 0xc1, 0xc2, 0xc3
};
@@ -121,7 +121,7 @@
Interest i1;
i1.setName("/local/ndn/prefix");
i1.setCanBePrefix(false);
- i1.setNonce(1);
+ i1.setNonce(0x1);
i1.setApplicationParameters("2404C0C1C2C3"_block);
BOOST_CHECK_EQUAL(i1.isParametersDigestValid(), true);
@@ -135,7 +135,7 @@
BOOST_CHECK_EQUAL(i2.getMustBeFresh(), false);
BOOST_CHECK_EQUAL(i2.getForwardingHint().empty(), true);
BOOST_CHECK_EQUAL(i2.hasNonce(), true);
- BOOST_CHECK_EQUAL(i2.getNonce(), 1);
+ BOOST_CHECK_EQUAL(i2.getNonce(), 0x1);
BOOST_CHECK_EQUAL(i2.getInterestLifetime(), DEFAULT_INTEREST_LIFETIME);
BOOST_CHECK(i2.getHopLimit() == nullopt);
BOOST_CHECK_EQUAL(i2.hasApplicationParameters(), true);
@@ -163,7 +163,7 @@
0x07, 0x03,
0x08, 0x01, 0x48,
0x0a, 0x04, // Nonce
- 0x4a, 0xcb, 0x1e, 0x4c,
+ 0x4c, 0x1e, 0xcb, 0x4a,
0x0c, 0x02, // InterestLifetime
0x76, 0xa1,
0x22, 0x01, // HopLimit
@@ -264,7 +264,7 @@
BOOST_CHECK_EQUAL(i.getApplicationParameters().isValid(), false);
// modify then re-encode
- i.setNonce(0x54657c95);
+ i.setNonce(0x957c6554);
BOOST_CHECK_EQUAL(i.hasWire(), false);
BOOST_CHECK_EQUAL(i.wireEncode(), "050B 0703(080149) 0A04957C6554"_block);
}
@@ -294,7 +294,7 @@
BOOST_CHECK_EQUAL(i.getMustBeFresh(), true);
BOOST_CHECK_EQUAL(i.getForwardingHint(), DelegationList({{15893, "/H"}}));
BOOST_CHECK_EQUAL(i.hasNonce(), true);
- BOOST_CHECK_EQUAL(i.getNonce(), 0x4c1ecb4a);
+ BOOST_CHECK_EQUAL(i.getNonce(), 0x4acb1e4c);
BOOST_CHECK_EQUAL(i.getInterestLifetime(), 30369_ms);
BOOST_CHECK_EQUAL(*i.getHopLimit(), 214);
BOOST_CHECK_EQUAL(i.hasApplicationParameters(), false);
@@ -322,7 +322,7 @@
BOOST_CHECK_EQUAL(i.getMustBeFresh(), true);
BOOST_CHECK_EQUAL(i.getForwardingHint(), DelegationList({{15893, "/H"}}));
BOOST_CHECK_EQUAL(i.hasNonce(), true);
- BOOST_CHECK_EQUAL(i.getNonce(), 0x4c1ecb4a);
+ BOOST_CHECK_EQUAL(i.getNonce(), 0x4acb1e4c);
BOOST_CHECK_EQUAL(i.getInterestLifetime(), 30369_ms);
BOOST_CHECK_EQUAL(*i.getHopLimit(), 214);
BOOST_CHECK_EQUAL(i.hasApplicationParameters(), true);
@@ -503,8 +503,9 @@
interest = makeInterest(data->getFullName());
BOOST_CHECK_EQUAL(interest->matchesData(*data), true);
- setNameComponent(*interest, -1, name::Component::fromEscapedString(
- "sha256digest=0000000000000000000000000000000000000000000000000000000000000000"));
+ setNameComponent(*interest, -1,
+ name::Component::fromEscapedString("sha256digest=00000000000000000000000000"
+ "00000000000000000000000000000000000000"));
BOOST_CHECK_EQUAL(interest->matchesData(*data), false); // violates implicit digest
}
@@ -596,12 +597,12 @@
BOOST_AUTO_TEST_CASE(GetNonce)
{
unique_ptr<Interest> i1, i2;
+ Interest::Nonce nonce1(0), nonce2(0);
// getNonce automatically assigns a random Nonce.
// It's possible to assign the same Nonce to two Interest, but it's unlikely to get 100 pairs of
- // same Nonces in a row.
+ // identical Nonces in a row.
int nIterations = 0;
- uint32_t nonce1 = 0, nonce2 = 0;
do {
i1 = make_unique<Interest>();
nonce1 = i1->getNonce();
@@ -609,28 +610,37 @@
nonce2 = i2->getNonce();
}
while (nonce1 == nonce2 && ++nIterations < 100);
+
BOOST_CHECK_NE(nonce1, nonce2);
BOOST_CHECK(i1->hasNonce());
BOOST_CHECK(i2->hasNonce());
// Once a Nonce is assigned, it should not change.
BOOST_CHECK_EQUAL(i1->getNonce(), nonce1);
+ BOOST_CHECK_EQUAL(i2->getNonce(), nonce2);
}
BOOST_AUTO_TEST_CASE(SetNonce)
{
Interest i1("/A");
i1.setCanBePrefix(false);
+ BOOST_CHECK(!i1.hasNonce());
+
i1.setNonce(1);
i1.wireEncode();
+ BOOST_CHECK(i1.hasNonce());
BOOST_CHECK_EQUAL(i1.getNonce(), 1);
Interest i2(i1);
+ BOOST_CHECK(i2.hasNonce());
BOOST_CHECK_EQUAL(i2.getNonce(), 1);
i2.setNonce(2);
BOOST_CHECK_EQUAL(i2.getNonce(), 2);
- BOOST_CHECK_EQUAL(i1.getNonce(), 1); // should not affect i1 Nonce (Bug #4168)
+ BOOST_CHECK_EQUAL(i1.getNonce(), 1); // should not affect i1's Nonce (Bug #4168)
+
+ i2.setNonce(nullopt);
+ BOOST_CHECK(!i2.hasNonce());
}
BOOST_AUTO_TEST_CASE(RefreshNonce)
@@ -647,6 +657,31 @@
BOOST_CHECK_NE(i.getNonce(), 1);
}
+BOOST_AUTO_TEST_CASE(NonceConversions)
+{
+ Interest i;
+ i.setCanBePrefix(false);
+
+ // 4-arg constructor
+ Interest::Nonce n1(1, 2, 3, 4);
+ i.setNonce(n1);
+ BOOST_CHECK_EQUAL(i.getNonce(), 0x01020304);
+
+ // 4-arg constructor + assignment
+ n1 = {0xf, 0xe, 0xd, 0xc};
+ i.setNonce(n1);
+ BOOST_CHECK_EQUAL(i.getNonce(), 0x0f0e0d0c);
+
+ // 1-arg constructor + assignment (implicit conversion)
+ Interest::Nonce n2;
+ n2 = 42;
+ BOOST_CHECK_NE(n1, n2);
+ i.setNonce(n2);
+ n2 = 21; // should not affect i's Nonce
+ BOOST_CHECK_EQUAL(i.getNonce(), 42);
+ BOOST_CHECK_EQUAL(i.toUri(), "/?Nonce=0000002a"); // stored in big-endian
+}
+
BOOST_AUTO_TEST_CASE(SetInterestLifetime)
{
BOOST_CHECK_THROW(Interest("/A", -1_ms), std::invalid_argument);
@@ -766,14 +801,14 @@
i.setMustBeFresh(true);
BOOST_CHECK_EQUAL(i.toUri(), "/foo?CanBePrefix&MustBeFresh");
- i.setNonce(1234);
- BOOST_CHECK_EQUAL(i.toUri(), "/foo?CanBePrefix&MustBeFresh&Nonce=1234");
+ i.setNonce(0xa1b2c3);
+ BOOST_CHECK_EQUAL(i.toUri(), "/foo?CanBePrefix&MustBeFresh&Nonce=00a1b2c3");
i.setInterestLifetime(2_s);
- BOOST_CHECK_EQUAL(i.toUri(), "/foo?CanBePrefix&MustBeFresh&Nonce=1234&Lifetime=2000");
+ BOOST_CHECK_EQUAL(i.toUri(), "/foo?CanBePrefix&MustBeFresh&Nonce=00a1b2c3&Lifetime=2000");
i.setHopLimit(18);
- BOOST_CHECK_EQUAL(i.toUri(), "/foo?CanBePrefix&MustBeFresh&Nonce=1234&Lifetime=2000&HopLimit=18");
+ BOOST_CHECK_EQUAL(i.toUri(), "/foo?CanBePrefix&MustBeFresh&Nonce=00a1b2c3&Lifetime=2000&HopLimit=18");
i.setCanBePrefix(false);
i.setMustBeFresh(false);
@@ -781,7 +816,7 @@
i.setApplicationParameters("2402CAFE"_block);
BOOST_CHECK_EQUAL(i.toUri(),
"/foo/params-sha256=8621f5e8321f04104640c8d02877d7c5142cad6e203c5effda1783b1a0e476d6"
- "?Nonce=1234&Lifetime=2000");
+ "?Nonce=00a1b2c3&Lifetime=2000");
}
BOOST_AUTO_TEST_SUITE_END() // TestInterest