face: Fix a serious bug with incoming interests processing
There was an error in logic of matching incoming interests to the
registered prefix table. There was actually no matching at all, only
search for the longest prefix.
Change-Id: I701655eb4f488938838df78fcb6730968bb1bbbf
diff --git a/src/face.cpp b/src/face.cpp
index fc064f1..0a967e3 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -61,7 +61,7 @@
pitTimeoutCheckTimer_ = make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
processEventsTimeoutTimer_ = make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
-
+
if (nfdMode)
m_fwController = make_shared<nfd::Controller>(boost::ref(*this));
else
@@ -77,9 +77,9 @@
bind(&Face::onReceiveElement, this, _1));
shared_ptr<const Interest> interestToExpress(new Interest(interest));
-
+
ioService_->post(bind(&Face::asyncExpressInterest, this, interestToExpress, onData, onTimeout));
-
+
return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
}
@@ -114,7 +114,7 @@
pitTimeoutCheckTimer_->async_wait(bind(&Face::checkPitExpire, this));
}
}
-
+
void
Face::put(const Data &data)
{
@@ -149,7 +149,7 @@
m_fwController->selfRegisterPrefix(prefixToRegister->getPrefix(),
bind(&RegisteredPrefixTable::push_back, ®isteredPrefixTable_, prefixToRegister),
bind(onSetInterestFilterFailed, prefixToRegister->getPrefix(), _1));
-
+
return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
}
@@ -163,7 +163,7 @@
Face::asyncUnsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
{
RegisteredPrefixTable::iterator i = std::find_if(registeredPrefixTable_.begin(), registeredPrefixTable_.end(),
- MatchRegisteredPrefixId(registeredPrefixId));
+ MatchRegisteredPrefixId(registeredPrefixId));
if (i != registeredPrefixTable_.end())
{
m_fwController->selfDeregisterPrefix((*i)->getPrefix(),
@@ -188,7 +188,7 @@
}
}
-void
+void
Face::processEvents(Milliseconds timeout/* = 0 */, bool keepThread/* = false*/)
{
try
@@ -205,12 +205,12 @@
processEventsTimeoutTimer_->expires_from_now(boost::posix_time::milliseconds(timeout));
processEventsTimeoutTimer_->async_wait(&fireProcessEventsTimeout);
}
-
+
if (keepThread) {
// work will ensure that ioService_ is running until work object exists
ioServiceWork_ = make_shared<boost::asio::io_service::work>(boost::ref(*ioService_));
}
-
+
ioService_->run();
ioService_->reset(); // so it is possible to run processEvents again (if necessary)
}
@@ -228,7 +228,7 @@
}
}
-void
+void
Face::shutdown()
{
pendingInterestTable_.clear();
@@ -271,7 +271,7 @@
if (!pendingInterestTable_.empty()) {
pitTimeoutCheckTimerActive_ = true;
-
+
pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
pitTimeoutCheckTimer_->async_wait(bind(&Face::checkPitExpire, this));
}
@@ -288,14 +288,14 @@
}
-void
+void
Face::onReceiveElement(const Block &block)
{
if (block.type() == Tlv::Interest)
{
shared_ptr<Interest> interest(new Interest());
interest->wireDecode(block);
-
+
RegisteredPrefixTable::iterator entry = getEntryForRegisteredPrefix(interest->getName());
if (entry != registeredPrefixTable_.end()) {
(*entry)->getOnInterest()((*entry)->getPrefix(), *interest);
@@ -324,7 +324,7 @@
}
}
-Face::PendingInterestTable::iterator
+Face::PendingInterestTable::iterator
Face::getEntryIndexForExpressedInterest(const Name& name)
{
for (PendingInterestTable::iterator i = pendingInterestTable_.begin ();
@@ -338,7 +338,7 @@
return pendingInterestTable_.end();
}
-
+
Face::RegisteredPrefixTable::iterator
Face::getEntryForRegisteredPrefix(const Name& name)
{
@@ -348,10 +348,14 @@
i != registeredPrefixTable_.end();
++i)
{
- if (longestPrefix == registeredPrefixTable_.end() ||
- (*i)->getPrefix().size() > (*longestPrefix)->getPrefix().size())
+ if ((*i)->getPrefix().isPrefixOf(name))
{
- longestPrefix = i;
+
+ if (longestPrefix == registeredPrefixTable_.end() ||
+ (*i)->getPrefix().size() > (*longestPrefix)->getPrefix().size())
+ {
+ longestPrefix = i;
+ }
}
}
return longestPrefix;
diff --git a/tests/test-faces.cpp b/tests/test-faces.cpp
index 9fc5860..1fab695 100644
--- a/tests/test-faces.cpp
+++ b/tests/test-faces.cpp
@@ -19,6 +19,7 @@
, timeoutCount(0)
, regPrefixId(0)
, inInterestCount(0)
+ , inInterestCount2(0)
, regFailedCount(0)
{
}
@@ -44,6 +45,14 @@
}
void
+ onInterest2(Face& face)
+ {
+ ++inInterestCount2;
+
+ face.unsetInterestFilter(regPrefixId2);
+ }
+
+ void
onRegFailed()
{
++regFailedCount;
@@ -69,7 +78,9 @@
uint32_t timeoutCount;
const RegisteredPrefixId* regPrefixId;
+ const RegisteredPrefixId* regPrefixId2;
uint32_t inInterestCount;
+ uint32_t inInterestCount2;
uint32_t regFailedCount;
};
@@ -144,6 +155,36 @@
BOOST_CHECK_EQUAL(dataCount, 0);
}
+BOOST_FIXTURE_TEST_CASE (SetTwoFilters, FacesFixture)
+{
+ Face face;
+ Face face2(face.ioService());
+ Scheduler scheduler(*face.ioService());
+ scheduler.scheduleEvent(time::seconds(0.3),
+ bind(&FacesFixture::terminate, this, func_lib::ref(face)));
+
+ regPrefixId = face.setInterestFilter("/Hello/World",
+ bind(&FacesFixture::onInterest, this, func_lib::ref(face)),
+ bind(&FacesFixture::onRegFailed, this));
+
+ regPrefixId2 = face.setInterestFilter("/Los/Angeles/Lakers",
+ bind(&FacesFixture::onInterest2, this, func_lib::ref(face)),
+ bind(&FacesFixture::onRegFailed, this));
+
+
+ scheduler.scheduleEvent(time::seconds(0.2),
+ bind(&FacesFixture::expressInterest, this,
+ func_lib::ref(face2), Name("/Hello/World/!")));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(regFailedCount, 0);
+ BOOST_CHECK_EQUAL(inInterestCount, 1);
+ BOOST_CHECK_EQUAL(inInterestCount2, 0);
+ BOOST_CHECK_EQUAL(timeoutCount, 1);
+ BOOST_CHECK_EQUAL(dataCount, 0);
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace ndn