interest: Allow in-wire refreshing of Interest's nonce

Change-Id: I47500fce16a1d37af865d3f9dab59355d6108c95
Refs: #1758
diff --git a/src/interest.cpp b/src/interest.cpp
index a6bd107..db3744c 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -58,6 +58,20 @@
   return *this;
 }
 
+void
+Interest::refreshNonce()
+{
+  if (!hasNonce())
+    return;
+
+  uint32_t oldNonce = getNonce();
+  uint32_t newNonce = oldNonce;
+  while (newNonce == oldNonce)
+    newNonce = random::generateWord32();
+
+  setNonce(newNonce);
+}
+
 bool
 Interest::matchesName(const Name& name) const
 {
diff --git a/src/interest.hpp b/src/interest.hpp
index 0750542..89c5c24 100644
--- a/src/interest.hpp
+++ b/src/interest.hpp
@@ -334,6 +334,17 @@
   Interest&
   setNonce(uint32_t nonce);
 
+  /**
+   * @brief Refresh nonce
+   *
+   * Refresh guarantees that new nonce value is different from the existing one.
+   *
+   * If nonce is already set, it will be updated to a different random value.
+   * If nonce is not set, this method will do nothing.
+   */
+  void
+  refreshNonce();
+
   //
 
   nfd::LocalControlHeader&
diff --git a/tests/unit-tests/test-interest.cpp b/tests/unit-tests/test-interest.cpp
index 2f465ae..82bf8bd 100644
--- a/tests/unit-tests/test-interest.cpp
+++ b/tests/unit-tests/test-interest.cpp
@@ -351,6 +351,11 @@
                     "ndn.ChildSelector=1&ndn.Scope=1&"
                     "ndn.InterestLifetime=1000&"
                     "ndn.Nonce=2&ndn.Exclude=alex,xxxx,*,yyyy");
+
+  i.refreshNonce();
+  BOOST_CHECK_EQUAL(i.hasWire(), true);
+  BOOST_CHECK_EQUAL(originalWire, i.wireEncode().wire());
+  BOOST_CHECK_NE(i.getNonce(), 2);
 }
 
 BOOST_AUTO_TEST_CASE(EncodeWithLocalHeader)