face: Refactored code to set interest filter
Change-Id: I1f9637a79c03a9e24608403d963bbfc4d9bcab1c
diff --git a/src/node.cpp b/src/node.cpp
index 0c9c872..513c40f 100644
--- a/src/node.cpp
+++ b/src/node.cpp
@@ -9,41 +9,31 @@
#include "node.hpp"
-#include "forwarding-entry.hpp"
-#include "face-instance.hpp"
-#include "status-response.hpp"
#include "security/signature-sha256-with-rsa.hpp"
#include "util/time.hpp"
#include "util/random.hpp"
-#include "util/ndnd-id-fetcher.hpp"
-
-using namespace std;
-#if NDN_CPP_HAVE_CXX11
-// In the std library, the placeholders are in a different namespace than boost.
-using namespace ndn::func_lib::placeholders;
-#endif
namespace ndn {
-Node::Node(const ptr_lib::shared_ptr<Transport>& transport)
+Node::Node(const shared_ptr<Transport>& transport)
: pitTimeoutCheckTimerActive_(false)
, transport_(transport)
- , ndndIdFetcherInterest_(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"), 4000.0)
+ , m_fwController(*this)
{
- ioService_ = ptr_lib::make_shared<boost::asio::io_service>();
- pitTimeoutCheckTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
- processEventsTimeoutTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
+ ioService_ = make_shared<boost::asio::io_service>();
+ pitTimeoutCheckTimer_ = make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
+ processEventsTimeoutTimer_ = make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
}
-Node::Node(const ptr_lib::shared_ptr<Transport>& transport, const ptr_lib::shared_ptr<boost::asio::io_service> &ioService)
+Node::Node(const shared_ptr<Transport>& transport, const shared_ptr<boost::asio::io_service> &ioService)
: ioService_(ioService)
, pitTimeoutCheckTimerActive_(false)
, transport_(transport)
- , ndndIdFetcherInterest_(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"), 4000.0)
+ , m_fwController(*this)
{
- pitTimeoutCheckTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
- processEventsTimeoutTimer_ = ptr_lib::make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
+ pitTimeoutCheckTimer_ = make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
+ processEventsTimeoutTimer_ = make_shared<boost::asio::deadline_timer>(boost::ref(*ioService_));
}
const PendingInterestId*
@@ -51,27 +41,28 @@
{
if (!transport_->isConnected())
transport_->connect(*ioService_,
- ptr_lib::bind(&Node::onReceiveElement, this, _1));
+ bind(&Node::onReceiveElement, this, _1));
- ptr_lib::shared_ptr<const Interest> interestToExpress(new Interest(interest));
+ shared_ptr<const Interest> interestToExpress(new Interest(interest));
- ioService_->post(func_lib::bind(&Node::asyncExpressInterest, this, interestToExpress, onData, onTimeout));
+ ioService_->post(bind(&Node::asyncExpressInterest, this, interestToExpress, onData, onTimeout));
return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
}
void
-Node::asyncExpressInterest(const ptr_lib::shared_ptr<const Interest> &interest, const OnData& onData, const OnTimeout& onTimeout)
+Node::asyncExpressInterest(const shared_ptr<const Interest> &interest,
+ const OnData& onData, const OnTimeout& onTimeout)
{
- pendingInterestTable_.push_back(ptr_lib::shared_ptr<PendingInterest>(new PendingInterest
- (interest, onData, onTimeout)));
+ pendingInterestTable_.push_back(shared_ptr<PendingInterest>(new PendingInterest
+ (interest, onData, onTimeout)));
transport_->send(interest->wireEncode());
if (!pitTimeoutCheckTimerActive_) {
pitTimeoutCheckTimerActive_ = true;
pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
- pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
+ pitTimeoutCheckTimer_->async_wait(bind(&Node::checkPitExpire, this));
}
}
@@ -80,7 +71,7 @@
{
if (!transport_->isConnected())
transport_->connect(*ioService_,
- ptr_lib::bind(&Node::onReceiveElement, this, _1));
+ bind(&Node::onReceiveElement, this, _1));
transport_->send(data.wireEncode());
}
@@ -89,173 +80,52 @@
void
Node::removePendingInterest(const PendingInterestId *pendingInterestId)
{
- ioService_->post(func_lib::bind(&Node::asyncRemovePendingInterest, this, pendingInterestId));
+ ioService_->post(bind(&Node::asyncRemovePendingInterest, this, pendingInterestId));
}
void
Node::asyncRemovePendingInterest(const PendingInterestId *pendingInterestId)
{
- std::remove_if(pendingInterestTable_.begin(), pendingInterestTable_.end(),
- MatchPendingInterestId(pendingInterestId));
+ pendingInterestTable_.remove_if(MatchPendingInterestId(pendingInterestId));
}
const RegisteredPrefixId*
-Node::registerPrefix
- (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags)
+Node::setInterestFilter(const Name& prefix,
+ const OnInterest& onInterest,
+ const OnSetInterestFilterFailed& onSetInterestFilterFailed)
{
- ptr_lib::shared_ptr<RegisteredPrefix> prefixToRegister(new RegisteredPrefix(prefix, onInterest));
-
- if (ndndId_.size() == 0) {
- // First fetch the ndndId of the connected hub.
- NdndIdFetcher fetcher(ndndId_,
- func_lib::bind(&Node::registerPrefixHelper, this,
- prefixToRegister, onRegisterFailed, flags),
- func_lib::bind(onRegisterFailed, prefixToRegister->getPrefix().shared_from_this()));
+ shared_ptr<RegisteredPrefix> prefixToRegister(new RegisteredPrefix(prefix, onInterest));
- // @todo: Check if this crash
- // It is OK for func_lib::function make a copy of the function object because the Info is in a ptr_lib::shared_ptr.
- expressInterest(ndndIdFetcherInterest_, fetcher, fetcher);
- }
- else
- registerPrefixHelper(prefixToRegister, onRegisterFailed, flags);
+ m_fwController.selfRegisterPrefix(prefixToRegister->getPrefix(),
+ bind(&RegisteredPrefixTable::push_back, ®isteredPrefixTable_, prefixToRegister),
+ bind(onSetInterestFilterFailed, prefixToRegister->getPrefix().shared_from_this()));
return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
}
void
-Node::removeRegisteredPrefix(const RegisteredPrefixId *registeredPrefixId)
+Node::unsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
+{
+ ioService_->post(bind(&Node::asyncUnsetInterestFilter, this, registeredPrefixId));
+}
+
+void
+Node::asyncUnsetInterestFilter(const RegisteredPrefixId *registeredPrefixId)
{
RegisteredPrefixTable::iterator i = std::find_if(registeredPrefixTable_.begin(), registeredPrefixTable_.end(),
MatchRegisteredPrefixId(registeredPrefixId));
if (i != registeredPrefixTable_.end())
{
- ForwardingEntry forwardingEntry("unreg", (*i)->getPrefix(), faceId_);
- Data data;
- // This ensures uniqueness of each prefix registration commands
- data.setName(Name().appendVersion(random::generateWord32()));
- data.setContent(forwardingEntry.wireEncode());
-
- SignatureSha256WithRsa signature;
- signature.setValue(Block(Tlv::SignatureValue, ptr_lib::make_shared<Buffer>()));
- data.setSignature(signature);
-
- // Create an interest where the name has the encoded Data packet.
- Name interestName;
- interestName.append("ndnx");
- interestName.append(ndndId_);
- interestName.append("unreg");
- interestName.append(data.wireEncode());
-
- Interest interest(interestName);
- interest.setScope(1);
- interest.setInterestLifetime(1000);
- interest.setMustBeFresh(true);
-
- expressInterest(interest, OnData(), OnTimeout());
-
- registeredPrefixTable_.erase(i);
+ m_fwController.selfDeregisterPrefix((*i)->getPrefix(),
+ bind(&RegisteredPrefixTable::erase, ®isteredPrefixTable_, i),
+ ndnd::Control::FailCallback());
}
// there cannot be two registered prefixes with the same id. if there are, then something is broken
}
void
-Node::registerPrefixHelper(const ptr_lib::shared_ptr<RegisteredPrefix> &prefixToRegister,
- const OnRegisterFailed& onRegisterFailed,
- const ForwardingFlags& flags)
-{
- // Create a ForwardingEntry.
-
- // AlexA: ndnd ignores any freshness that is larger than 3600 sec and sets 300 sec instead
- // to register "forever" (=2000000000 sec), freshnessPeriod must be omitted
- ForwardingEntry forwardingEntry("selfreg", prefixToRegister->getPrefix(), -1, flags, -1);
- Block content = forwardingEntry.wireEncode();
-
-
- // Set the ForwardingEntry as the content of a Data packet and sign.
- Data data;
- // This ensures uniqueness of each prefix registration commands
- data.setName(Name().appendVersion(random::generateWord32()));
- data.setContent(content);
-
- // Create an empty signature, since nobody going to verify it for now
- // @todo In the future, we may require real signatures to do the registration
- SignatureSha256WithRsa signature;
- signature.setValue(Block(Tlv::SignatureValue, ptr_lib::make_shared<Buffer>()));
- data.setSignature(signature);
-
- // Create an interest where the name has the encoded Data packet.
- Name interestName;
- interestName.append("ndnx");
- interestName.append(ndndId_);
- interestName.append("selfreg");
- interestName.append(data.wireEncode());
-
- Interest interest(interestName);
- interest.setScope(1);
- interest.setInterestLifetime(1000);
- interest.setMustBeFresh(true);
-
- expressInterest(interest,
- func_lib::bind(&Node::registerPrefixFinal, this,
- prefixToRegister, onRegisterFailed, _1, _2),
- func_lib::bind(onRegisterFailed, prefixToRegister->getPrefix().shared_from_this()));
-}
-
-void
-Node::registerPrefixFinal(const ptr_lib::shared_ptr<RegisteredPrefix> &prefixToRegister,
- const OnRegisterFailed& onRegisterFailed,
- const ptr_lib::shared_ptr<const Interest>&, const ptr_lib::shared_ptr<Data>&data)
-{
- Block content = data->getContent();
- content.parse();
-
- if (content.getAll().empty())
- {
- onRegisterFailed(prefixToRegister->getPrefix().shared_from_this());
- return;
- }
-
- Block::element_iterator val = content.getAll().begin();
-
- switch(val->type())
- {
- case Tlv::FaceManagement::ForwardingEntry:
- {
- ForwardingEntry entry;
- entry.wireDecode(*val);
-
- // Save the onInterest callback and send the registration interest.
- registeredPrefixTable_.push_back(prefixToRegister);
-
- /// @todo Notify user about successful registration
-
- // succeeded
- return;
- }
- case Tlv::FaceManagement::StatusResponse:
- {
- // failed :(
- StatusResponse resp;
- resp.wireDecode(*val);
-
- // std::cerr << "StatusReponse: " << resp << std::endl;
-
- onRegisterFailed(prefixToRegister->getPrefix().shared_from_this());
- return;
- }
- default:
- {
- // failed :(
-
- onRegisterFailed(prefixToRegister->getPrefix().shared_from_this());
- return;
- }
- }
-}
-
-void
Node::processEvents(Milliseconds timeout/* = 0 */, bool keepThread/* = false*/)
{
try
@@ -275,7 +145,7 @@
if (keepThread) {
// work will ensure that ioService_ is running until work object exists
- ioServiceWork_ = ptr_lib::make_shared<boost::asio::io_service::work>(boost::ref(*ioService_));
+ ioServiceWork_ = make_shared<boost::asio::io_service::work>(boost::ref(*ioService_));
}
ioService_->run();
@@ -295,6 +165,18 @@
}
}
+void
+Node::shutdown()
+{
+ pendingInterestTable_.clear();
+ registeredPrefixTable_.clear();
+
+ transport_->close();
+ pitTimeoutCheckTimer_->cancel();
+ processEventsTimeoutTimer_->cancel();
+ pitTimeoutCheckTimerActive_ = false;
+}
+
void
Node::fireProcessEventsTimeout(const boost::system::error_code& error)
{
@@ -306,24 +188,29 @@
Node::checkPitExpire()
{
// Check for PIT entry timeouts. Go backwards through the list so we can erase entries.
- MillisecondsSince1970 nowMilliseconds = ndn_getNowMilliseconds();
- for (int i = (int)pendingInterestTable_.size() - 1; i >= 0; --i) {
- if (pendingInterestTable_[i]->isTimedOut(nowMilliseconds)) {
- // Save the PendingInterest and remove it from the PIT. Then call the callback.
- ptr_lib::shared_ptr<PendingInterest> pendingInterest = pendingInterestTable_[i];
- pendingInterestTable_.erase(pendingInterestTable_.begin() + i);
- pendingInterest->callTimeout();
-
- // Refresh now since the timeout callback might have delayed.
- nowMilliseconds = ndn_getNowMilliseconds();
+ MillisecondsSince1970 nowMilliseconds = getNowMilliseconds();
+
+ PendingInterestTable::iterator i = pendingInterestTable_.begin();
+ while (i != pendingInterestTable_.end())
+ {
+ if ((*i)->isTimedOut(nowMilliseconds))
+ {
+ // Save the PendingInterest and remove it from the PIT. Then call the callback.
+ shared_ptr<PendingInterest> pendingInterest = *i;
+
+ i = pendingInterestTable_.erase(i);
+
+ pendingInterest->callTimeout();
+ }
+ else
+ ++i;
}
- }
if (!pendingInterestTable_.empty()) {
pitTimeoutCheckTimerActive_ = true;
pitTimeoutCheckTimer_->expires_from_now(boost::posix_time::milliseconds(100));
- pitTimeoutCheckTimer_->async_wait(func_lib::bind(&Node::checkPitExpire, this));
+ pitTimeoutCheckTimer_->async_wait(bind(&Node::checkPitExpire, this));
}
else {
pitTimeoutCheckTimerActive_ = false;
@@ -343,7 +230,7 @@
{
if (block.type() == Tlv::Interest)
{
- ptr_lib::shared_ptr<Interest> interest(new Interest());
+ shared_ptr<Interest> interest(new Interest());
interest->wireDecode(block);
RegisteredPrefixTable::iterator entry = getEntryForRegisteredPrefix(interest->getName());
@@ -353,14 +240,14 @@
}
else if (block.type() == Tlv::Data)
{
- ptr_lib::shared_ptr<Data> data(new Data());
+ shared_ptr<Data> data(new Data());
data->wireDecode(block);
PendingInterestTable::iterator entry = getEntryIndexForExpressedInterest(data->getName());
if (entry != pendingInterestTable_.end()) {
// Copy pointers to the needed objects and remove the PIT entry before the calling the callback.
const OnData onData = (*entry)->getOnData();
- const ptr_lib::shared_ptr<const Interest> interest = (*entry)->getInterest();
+ const shared_ptr<const Interest> interest = (*entry)->getInterest();
pendingInterestTable_.erase(entry);
if (onData) {
@@ -374,18 +261,6 @@
}
}
-void
-Node::shutdown()
-{
- pendingInterestTable_.clear();
- registeredPrefixTable_.clear();
-
- transport_->close();
- pitTimeoutCheckTimer_->cancel();
- processEventsTimeoutTimer_->cancel();
- pitTimeoutCheckTimerActive_ = false;
-}
-
Node::PendingInterestTable::iterator
Node::getEntryIndexForExpressedInterest(const Name& name)
{
@@ -419,28 +294,4 @@
return longestPrefix;
}
-Node::PendingInterest::PendingInterest(const ptr_lib::shared_ptr<const Interest>& interest,
- const OnData& onData, const OnTimeout& onTimeout)
-: interest_(interest),
- onData_(onData), onTimeout_(onTimeout)
-{
- // Set up timeoutTime_.
- if (interest_->getInterestLifetime() >= 0)
- timeoutTimeMilliseconds_ = ndn_getNowMilliseconds() + interest_->getInterestLifetime();
- else
- // No timeout.
- /**
- * @todo Set more meaningful default timeout. This timeout MUST exist.
- */
- timeoutTimeMilliseconds_ = ndn_getNowMilliseconds() + 4000;
-}
-
-void
-Node::PendingInterest::callTimeout()
-{
- if (onTimeout_) {
- onTimeout_(interest_);
- }
-}
-
-}
+} // namespace ndn