src: onFaceEventNotification only proceed if face id was zero or updated
refs: #5010
Change-Id: Ie5b1f8a5ca2a372890a9ef2a28dc00e1a7c0a366
diff --git a/src/adjacent.cpp b/src/adjacent.cpp
index 4afe6d7..af1f926 100644
--- a/src/adjacent.cpp
+++ b/src/adjacent.cpp
@@ -53,7 +53,7 @@
{
}
-Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
+Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
Status s, uint32_t iton, uint64_t faceId)
: m_name(an)
, m_faceUri(faceUri)
diff --git a/src/hello-protocol.hpp b/src/hello-protocol.hpp
index 94330e2..ff87a3b 100644
--- a/src/hello-protocol.hpp
+++ b/src/hello-protocol.hpp
@@ -167,12 +167,6 @@
onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
const ndn::Name& neighbor, const ndn::time::milliseconds& timeout);
- /*! \brief Create a Face for an adjacency
- * \sa HelloProtocol::onRegistrationSuccess
- */
- void
- registerPrefixes(const ndn::Name& adjName, const std::string& faceUri,
- double linkCost, const ndn::time::milliseconds& timeout);
private:
ndn::Face& m_face;
ndn::Scheduler m_scheduler;
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index a6da9a0..9a62a24 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -483,14 +483,16 @@
return;
}
auto adjacent = m_adjacencyList.findAdjacent(faceUri);
+ uint64_t faceId = faceEventNotification.getFaceId();
- // If we have a neighbor by that FaceUri and it has no FaceId, we
- // have a match.
- if (adjacent != m_adjacencyList.end()) {
+ // If we have a neighbor by that FaceUri and it has no FaceId or
+ // the FaceId is different from ours, we have a match.
+ if (adjacent != m_adjacencyList.end() &&
+ (adjacent->getFaceId() == 0 || adjacent->getFaceId() != faceId))
+ {
NLSR_LOG_DEBUG("Face creation event matches neighbor: " << adjacent->getName()
- << ". New Face ID: " << faceEventNotification.getFaceId()
- << ". Registering prefixes.");
- adjacent->setFaceId(faceEventNotification.getFaceId());
+ << ". New Face ID: " << faceId << ". Registering prefixes.");
+ adjacent->setFaceId(faceId);
registerAdjacencyPrefixes(*adjacent, ndn::time::milliseconds::max());
diff --git a/src/route/fib.cpp b/src/route/fib.cpp
index 7d08e12..9ee14c7 100644
--- a/src/route/fib.cpp
+++ b/src/route/fib.cpp
@@ -199,8 +199,7 @@
void
Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
- uint64_t faceCost,
- const ndn::time::milliseconds& timeout,
+ uint64_t faceCost, const ndn::time::milliseconds& timeout,
uint64_t flags, uint8_t times)
{
uint64_t faceId = m_adjacencyList.getFaceId(ndn::FaceUri(faceUri));
diff --git a/tests/test-nlsr.cpp b/tests/test-nlsr.cpp
index 76b0fd3..6be31ed 100644
--- a/tests/test-nlsr.cpp
+++ b/tests/test-nlsr.cpp
@@ -202,20 +202,24 @@
BOOST_AUTO_TEST_CASE(FaceCreateEventAlreadyConfigured)
{
- // Setting constants for the unit test
- const uint32_t eventFaceId = 1;
- const uint32_t neighborFaceId = 2;
+ // So if NLSR gets the notification and registers prefixes it
+ // will change the Id to 1 and our tests will fail
+ // Need to disable registrationReply in dummy face and have own registration reply in the future
+ const uint32_t neighborFaceId = 1;
const std::string faceUri = "udp4://10.0.0.1:6363";
Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
- Adjacent::STATUS_ACTIVE, 0, neighborFaceId);
+ Adjacent::STATUS_ACTIVE, 0, 0);
conf.getAdjacencyList().insert(neighbor);
+ // Let NLSR start the face monitor
+ this->advanceClocks(10_ms);
+
// Build, sign, and send the Face Event
ndn::nfd::FaceEventNotification event;
event.setKind(ndn::nfd::FACE_EVENT_CREATED)
.setRemoteUri(faceUri)
- .setFaceId(eventFaceId);
+ .setFaceId(neighborFaceId); // Does not matter what we set here, dummy face always returns 1
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
data->setFreshnessPeriod(1_s);
data->setContent(event.wireEncode());
@@ -225,10 +229,24 @@
// Move the clocks forward so that the Face processes the event.
this->advanceClocks(10_ms);
- // Since the neighbor was already configured, this (simply erroneous) event should have no effect.
+ // Check that the neighbor is configured with the face id of 1
auto iterator = conf.getAdjacencyList().findAdjacent(ndn::FaceUri(faceUri));
BOOST_REQUIRE(iterator != conf.getAdjacencyList().end());
BOOST_CHECK_EQUAL(iterator->getFaceId(), neighborFaceId);
+
+ // Resend same event notification again
+ m_face.sentInterests.clear();
+ data->setName("/localhost/nfd/faces/events/%FE%01");
+ m_keyChain.sign(*data);
+ m_face.receive(*data);
+ this->advanceClocks(10_ms);
+
+ for (const auto& interest : m_face.sentInterests) {
+ // Should not re-register prefix since this is the same event notification
+ if (ndn::Name("/localhost/nfd/rib/register").isPrefixOf(interest.getName())) {
+ BOOST_CHECK(false);
+ }
+ }
}
BOOST_AUTO_TEST_CASE(FaceDestroyEvent)