fw: integrate forwarder, strategy, tables
refs #1131, #1136
Change-Id: Ica58341cdc1ea1dc421693a87f35fc50177a707d
diff --git a/daemon/face/face.cpp b/daemon/face/face.cpp
index 6518117..9c8613b 100644
--- a/daemon/face/face.cpp
+++ b/daemon/face/face.cpp
@@ -8,8 +8,8 @@
namespace nfd {
-Face::Face(FaceId id)
- : m_id(id)
+Face::Face()
+ : m_id(INVALID_FACEID)
{
}
@@ -17,6 +17,18 @@
{
}
+FaceId
+Face::getId() const
+{
+ return m_id;
+}
+
+FaceId
+Face::setId(FaceId faceId)
+{
+ m_id = faceId;
+}
+
bool
Face::isUp() const
{
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index 9ff2d20..994bc78 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -17,6 +17,8 @@
*/
typedef int FaceId;
+const FaceId INVALID_FACEID = -1;
+
const std::size_t MAX_NDN_PACKET_SIZE = 8800;
/** \class Face
@@ -25,10 +27,13 @@
class Face : noncopyable, public enable_shared_from_this<Face>
{
public:
- Face(FaceId id);
+ Face();
virtual
~Face();
+
+ FaceId
+ getId() const;
/// fires when an Interest is received
EventEmitter<const Interest&> onReceiveInterest;
@@ -81,8 +86,15 @@
// receiveData();
private:
+ FaceId
+ setId(FaceId faceId);
+
+private:
FaceId m_id;
std::string m_description;
+
+ // allow setting FaceId
+ friend class Forwarder;
};
} // namespace nfd
diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp
index e0ea05b..a764a07 100644
--- a/daemon/face/stream-face.hpp
+++ b/daemon/face/stream-face.hpp
@@ -17,8 +17,7 @@
public:
typedef T protocol;
- StreamFace(FaceId id,
- const shared_ptr<typename protocol::socket>& socket);
+ StreamFace(const shared_ptr<typename protocol::socket>& socket);
protected:
void
@@ -39,10 +38,8 @@
template <class T>
inline
-StreamFace<T>::StreamFace(FaceId id,
- const shared_ptr<typename StreamFace::protocol::socket>& socket)
- : Face(id)
- , m_socket(socket)
+StreamFace<T>::StreamFace(const shared_ptr<typename StreamFace::protocol::socket>& socket)
+ : m_socket(socket)
{
m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
bind(&StreamFace<T>::handleReceive, this, _1, _2));
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 25244f8..f67e9b2 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -117,10 +117,7 @@
return;
}
- /**
- * \todo Remove FaceId from here
- */
- shared_ptr<TcpFace> face = make_shared<TcpFace>(1, boost::cref(socket));
+ shared_ptr<TcpFace> face = make_shared<TcpFace>(boost::cref(socket));
onFaceCreated(face);
tcp::Endpoint remoteEndpoint = socket->remote_endpoint();
diff --git a/daemon/face/tcp-face.cpp b/daemon/face/tcp-face.cpp
index 79f9b8c..4a295ff 100644
--- a/daemon/face/tcp-face.cpp
+++ b/daemon/face/tcp-face.cpp
@@ -8,9 +8,8 @@
namespace nfd {
-TcpFace::TcpFace(FaceId id,
- const shared_ptr<TcpFace::protocol::socket>& socket)
- : StreamFace<protocol>(id, socket)
+TcpFace::TcpFace(const shared_ptr<TcpFace::protocol::socket>& socket)
+ : StreamFace<protocol>(socket)
{
}
diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp
index c76cbc8..cf3188c 100644
--- a/daemon/face/tcp-face.hpp
+++ b/daemon/face/tcp-face.hpp
@@ -21,8 +21,7 @@
public:
typedef boost::asio::ip::tcp protocol;
- TcpFace(FaceId id,
- const shared_ptr<protocol::socket>& socket);
+ TcpFace(const shared_ptr<protocol::socket>& socket);
// from Face
virtual void
diff --git a/daemon/fw/best-route-strategy.cpp b/daemon/fw/best-route-strategy.cpp
index 12db744..3b94531 100644
--- a/daemon/fw/best-route-strategy.cpp
+++ b/daemon/fw/best-route-strategy.cpp
@@ -7,9 +7,10 @@
#include "best-route-strategy.hpp"
namespace nfd {
+namespace fw {
-BestRouteStrategy::BestRouteStrategy(Forwarder& fw)
- : Strategy(fw)
+BestRouteStrategy::BestRouteStrategy(Forwarder& forwarder)
+ : Strategy(forwarder)
{
}
@@ -21,8 +22,7 @@
BestRouteStrategy::afterReceiveInterest(const Face& inFace,
const Interest& interest,
shared_ptr<fib::Entry> fibEntry,
- shared_ptr<pit::Entry> pitEntry,
- pit::InRecordCollection::iterator pitInRecord)
+ shared_ptr<pit::Entry> pitEntry)
{
const fib::NextHopList& nexthops = fibEntry->getNextHops();
if (nexthops.size() == 0) {
@@ -34,4 +34,5 @@
this->sendInterest(pitEntry, outFace);
}
+} // namespace fw
} // namespace nfd
diff --git a/daemon/fw/best-route-strategy.hpp b/daemon/fw/best-route-strategy.hpp
index 8e9f127..c29caae 100644
--- a/daemon/fw/best-route-strategy.hpp
+++ b/daemon/fw/best-route-strategy.hpp
@@ -8,8 +8,10 @@
#define NFD_FW_BEST_ROUTE_STRATEGY_HPP
#include "strategy.hpp"
+#include "forwarder.hpp"
namespace nfd {
+namespace fw {
/** \class BestRouteStrategy
* \brief a forwarding strategy that forwards Interest
@@ -19,7 +21,7 @@
{
public:
explicit
- BestRouteStrategy(Forwarder& fw);
+ BestRouteStrategy(Forwarder& forwarder);
virtual
~BestRouteStrategy();
@@ -28,11 +30,10 @@
afterReceiveInterest(const Face& inFace,
const Interest& interest,
shared_ptr<fib::Entry> fibEntry,
- shared_ptr<pit::Entry> pitEntry,
- pit::InRecordCollection::iterator pitInRecord
- );
+ shared_ptr<pit::Entry> pitEntry);
};
+} // namespace fw
} // namespace nfd
#endif // NFD_FW_BEST_ROUTE_STRATEGY_HPP
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 1ba6808..d9850df 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -5,41 +5,67 @@
*/
#include "forwarder.hpp"
+#include "core/logger.hpp"
+#include "best-route-strategy.hpp"
namespace nfd {
+NFD_LOG_INIT("Forwarder");
+
Forwarder::Forwarder(boost::asio::io_service& ioService)
: m_scheduler(ioService)
+ , m_lastFaceId(0)
{
-}
-
-uint64_t
-Forwarder::addFace(const shared_ptr<Face>& face)
-{
- return -1;
+ m_strategy = make_shared<fw::BestRouteStrategy>(boost::ref(*this));
}
void
-Forwarder::removeFace(const shared_ptr<Face>& face)
+Forwarder::addFace(shared_ptr<Face> face)
{
+ FaceId faceId = ++m_lastFaceId;
+ face->setId(faceId);
+ m_faces[faceId] = face;
+ NFD_LOG_INFO("addFace id=" << faceId);
+
+ face->onReceiveInterest += bind(&Forwarder::onInterest,
+ this, boost::ref(*face), _1);
+ face->onReceiveData += bind(&Forwarder::onData,
+ this, boost::ref(*face), _1);
}
void
-Forwarder::onInterest(const Face& face, const Interest& interest)
+Forwarder::removeFace(shared_ptr<Face> face)
{
- this->onIncomingInterest(const_cast<Face&>(face), interest);
+ FaceId faceId = face->getId();
+ m_faces.erase(faceId);
+ face->setId(INVALID_FACEID);
+ NFD_LOG_INFO("removeFace id=" << faceId);
+
+ // XXX This clears all subscriptions, because EventEmitter
+ // does not support only removing Forwarder's subscription
+ face->onReceiveInterest.clear();
+ face->onReceiveData .clear();
+
+ m_fib.removeNextHopFromAllEntries(face);
}
void
-Forwarder::onData(const Face& face, const Data& data)
+Forwarder::onInterest(Face& face, const Interest& interest)
{
- this->onIncomingData(const_cast<Face&>(face), data);
+ this->onIncomingInterest(face, interest);
+}
+
+void
+Forwarder::onData(Face& face, const Data& data)
+{
+ this->onIncomingData(face, data);
}
void
Forwarder::onIncomingInterest(Face& inFace, const Interest& interest)
{
// receive Interest
+ NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() << " interest=" << interest.getName());
// PIT insert
std::pair<shared_ptr<pit::Entry>, bool>
@@ -89,19 +115,24 @@
// TODO use Fib::findParent(pitEntry)
// dispatch to strategy
- // TODO
+ m_strategy->afterReceiveInterest(inFace, interest, fibEntry, pitEntry);
+ // TODO dispatch according to fibEntry
}
void
Forwarder::onInterestLoop(Face& inFace, const Interest& interest,
shared_ptr<pit::Entry> pitEntry)
{
+ NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() << " interest=" << interest.getName());
+
// do nothing, which means Interest is dropped
}
void
Forwarder::onOutgoingInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace)
{
+ NFD_LOG_DEBUG("onOutgoingInterest face=" << outFace.getId() << " interest=" << pitEntry->getName());
+
// pick Interest
const Interest& interest = pitEntry->getInterest();
// TODO pick the last incoming Interest
@@ -120,6 +151,8 @@
void
Forwarder::onInterestRebuff(shared_ptr<pit::Entry> pitEntry)
{
+ NFD_LOG_DEBUG("onInterestRebuff interest=" << pitEntry->getName());
+
// set PIT straggler timer
this->setStragglerTimer(pitEntry);
}
@@ -127,6 +160,8 @@
void
Forwarder::onInterestUnsatisfied(shared_ptr<pit::Entry> pitEntry)
{
+ NFD_LOG_DEBUG("onInterestUnsatisfied interest=" << pitEntry->getName());
+
// invoke PIT unsatisfied callback
// TODO
@@ -138,6 +173,7 @@
Forwarder::onIncomingData(Face& inFace, const Data& data)
{
// receive Data
+ NFD_LOG_DEBUG("onIncomingData face=" << inFace.getId() << " data=" << data.getName());
// PIT match
shared_ptr<pit::DataMatchResult> pitMatches = m_pit.findAllDataMatches(data);
@@ -155,6 +191,7 @@
for (pit::DataMatchResult::iterator it = pitMatches->begin();
it != pitMatches->end(); ++it) {
shared_ptr<pit::Entry> pitEntry = *it;
+ NFD_LOG_DEBUG("onIncomingData matching=" << pitEntry->getName());
// cancel unsatisfy & straggler timer
this->cancelUnsatisfyAndStragglerTimer(pitEntry);
@@ -196,11 +233,15 @@
// CS insert
m_cs.insert(data);
}
+
+ NFD_LOG_DEBUG("onDataUnsolicited face=" << inFace.getId() << " data=" << data.getName() << " acceptToCache=" << acceptToCache);
}
void
Forwarder::onOutgoingData(const Data& data, Face& outFace)
{
+ NFD_LOG_DEBUG("onOutgoingData face=" << outFace.getId() << " data=" << data.getName());
+
// traffic manager
// pass through
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index 591254e..1359737 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -13,6 +13,7 @@
#include "table/fib.hpp"
#include "table/pit.hpp"
#include "table/cs.hpp"
+#include "strategy.hpp"
namespace nfd {
@@ -26,18 +27,28 @@
public:
Forwarder(boost::asio::io_service& ioService);
- uint64_t
- addFace(const shared_ptr<Face>& face);
+ void
+ addFace(shared_ptr<Face> face);
void
- removeFace(const shared_ptr<Face>& face);
+ removeFace(shared_ptr<Face> face);
void
- onInterest(const Face& face, const Interest& interest);
+ onInterest(Face& face, const Interest& interest);
void
- onData(const Face& face, const Data& data);
+ onData(Face& face, const Data& data);
+public:
+ Fib&
+ getFib();
+
+ Pit&
+ getPit();
+
+ Cs&
+ getCs();
+
private: // pipelines
/** \brief incoming Interest pipeline
*/
@@ -92,15 +103,39 @@
private:
Scheduler m_scheduler;
+
+ FaceId m_lastFaceId;
+ std::map<FaceId, shared_ptr<Face> > m_faces;
+
Fib m_fib;
Pit m_pit;
Cs m_cs;
- // container< shared_ptr<Face> > m_faces;
+ /// the active strategy (only one strategy in mock)
+ shared_ptr<fw::Strategy> m_strategy;
// allow Strategy (base class) to enter pipelines
- friend class Strategy;
+ friend class fw::Strategy;
};
+inline Fib&
+Forwarder::getFib()
+{
+ return m_fib;
+}
+
+inline Pit&
+Forwarder::getPit()
+{
+ return m_pit;
+}
+
+inline Cs&
+Forwarder::getCs()
+{
+ return m_cs;
+}
+
+
} // namespace nfd
#endif // NFD_FW_FORWARDER_HPP
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index ed1233f..f8c2f12 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -5,11 +5,13 @@
*/
#include "strategy.hpp"
+#include "forwarder.hpp"
namespace nfd {
+namespace fw {
-Strategy::Strategy(Forwarder& fw)
- : m_fw(fw)
+Strategy::Strategy(Forwarder& forwarder)
+ : m_forwarder(forwarder)
{
}
@@ -22,13 +24,14 @@
Strategy::sendInterest(shared_ptr<pit::Entry> pitEntry,
shared_ptr<Face> outFace)
{
- m_fw.onOutgoingInterest(pitEntry, *outFace);
+ m_forwarder.onOutgoingInterest(pitEntry, *outFace);
}
void
Strategy::rebuffPendingInterest(shared_ptr<pit::Entry> pitEntry)
{
- m_fw.onInterestRebuff(pitEntry);
+ m_forwarder.onInterestRebuff(pitEntry);
}
+} // namespace fw
} // namespace nfd
diff --git a/daemon/fw/strategy.hpp b/daemon/fw/strategy.hpp
index 1a6e47f..ce21c13 100644
--- a/daemon/fw/strategy.hpp
+++ b/daemon/fw/strategy.hpp
@@ -7,10 +7,20 @@
#ifndef NFD_FW_STRATEGY_HPP
#define NFD_FW_STRATEGY_HPP
-#include "forwarder.hpp"
+#include "face/face.hpp"
namespace nfd {
+class Forwarder;
+namespace fib {
+class Entry;
+}
+namespace pit {
+class Entry;
+}
+
+namespace fw {
+
/** \class Strategy
* \brief represents a forwarding strategy
*/
@@ -18,7 +28,7 @@
{
public:
explicit
- Strategy(Forwarder& fw);
+ Strategy(Forwarder& forwarder);
virtual
~Strategy();
@@ -27,9 +37,7 @@
afterReceiveInterest(const Face& inFace,
const Interest& interest,
shared_ptr<fib::Entry> fibEntry,
- shared_ptr<pit::Entry> pitEntry,
- pit::InRecordCollection::iterator pitInRecord
- ) =0;
+ shared_ptr<pit::Entry> pitEntry) =0;
//virtual void
//beforeExpirePendingInterest() =0;
@@ -57,9 +65,10 @@
rebuffPendingInterest(shared_ptr<pit::Entry> pitEntry);
private:
- Forwarder& m_fw;
+ Forwarder& m_forwarder;
};
+} // namespace fw
} // namespace nfd
#endif // NFD_FW_STRATEGY_HPP
diff --git a/daemon/mgmt/internal-face.cpp b/daemon/mgmt/internal-face.cpp
index cd66b4a..e3daeca 100644
--- a/daemon/mgmt/internal-face.cpp
+++ b/daemon/mgmt/internal-face.cpp
@@ -8,10 +8,7 @@
namespace nfd {
-const FaceId INTERNAL_FACE_FACEID = 0;
-
InternalFace::InternalFace()
- : Face(INTERNAL_FACE_FACEID)
{
}
diff --git a/tests/face/dummy-face.hpp b/tests/face/dummy-face.hpp
index a58a3ee..c7b5d76 100644
--- a/tests/face/dummy-face.hpp
+++ b/tests/face/dummy-face.hpp
@@ -18,18 +18,17 @@
class DummyFace : public Face
{
public:
- DummyFace(FaceId id)
- : Face(id)
+ DummyFace()
{
}
virtual void
- sendInterest(const Interest &interest)
+ sendInterest(const Interest& interest)
{
}
virtual void
- sendData(const Data &data)
+ sendData(const Data& data)
{
}
};
diff --git a/tests/face/face.cpp b/tests/face/face.cpp
index dced528..5245f51 100644
--- a/tests/face/face.cpp
+++ b/tests/face/face.cpp
@@ -15,7 +15,7 @@
BOOST_AUTO_TEST_CASE(Description)
{
- DummyFace face(1);
+ DummyFace face;
face.setDescription("3pFsKrvWr");
BOOST_CHECK_EQUAL(face.getDescription(), "3pFsKrvWr");
}
diff --git a/tests/fw/forwarder.cpp b/tests/fw/forwarder.cpp
new file mode 100644
index 0000000..cf5115f
--- /dev/null
+++ b/tests/fw/forwarder.cpp
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "fw/forwarder.hpp"
+#include "../face/dummy-face.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+namespace nfd {
+
+class ForwarderTestFace : public Face {
+public:
+ ForwarderTestFace(boost::asio::io_service& ioService)
+ : m_ioService(ioService)
+ {
+ }
+
+ virtual void
+ sendInterest(const Interest& interest)
+ {
+ m_sentInterests.push_back(interest);
+ m_ioService.stop();
+ }
+
+ virtual void
+ sendData(const Data& data)
+ {
+ m_sentDatas.push_back(data);
+ m_ioService.stop();
+ }
+
+ void
+ receiveInterest(const Interest& interest)
+ {
+ onReceiveInterest(interest);
+ }
+
+ void
+ receiveData(const Data& data)
+ {
+ onReceiveData(data);
+ }
+
+public:
+ std::vector<Interest> m_sentInterests;
+ std::vector<Data> m_sentDatas;
+
+private:
+ boost::asio::io_service& m_ioService;
+};
+
+BOOST_AUTO_TEST_SUITE(FwForwarder)
+
+BOOST_AUTO_TEST_CASE(AddRemoveFace)
+{
+ boost::asio::io_service io;
+ Forwarder forwarder(io);
+
+ shared_ptr<Face> face1 = make_shared<DummyFace>();
+ shared_ptr<Face> face2 = make_shared<DummyFace>();
+
+ BOOST_CHECK_EQUAL(face1->getId(), INVALID_FACEID);
+ BOOST_CHECK_EQUAL(face2->getId(), INVALID_FACEID);
+
+ forwarder.addFace(face1);
+ forwarder.addFace(face2);
+
+ BOOST_CHECK_NE(face1->getId(), INVALID_FACEID);
+ BOOST_CHECK_NE(face2->getId(), INVALID_FACEID);
+ BOOST_CHECK_NE(face1->getId(), face2->getId());
+
+ forwarder.removeFace(face1);
+ forwarder.removeFace(face2);
+
+ BOOST_CHECK_EQUAL(face1->getId(), INVALID_FACEID);
+ BOOST_CHECK_EQUAL(face2->getId(), INVALID_FACEID);
+}
+
+BOOST_AUTO_TEST_CASE(SimpleExchange)
+{
+ Name nameA ("ndn:/A");
+ Name nameAB ("ndn:/A/B");
+ Name nameABC("ndn:/A/B/C");
+ Interest interestAB(nameAB);
+ interestAB.setInterestLifetime(4000);
+ Data dataABC(nameABC);
+
+ boost::asio::io_service io;
+ Forwarder forwarder(io);
+
+ shared_ptr<ForwarderTestFace> face1 = make_shared<ForwarderTestFace>(boost::ref(io));
+ shared_ptr<ForwarderTestFace> face2 = make_shared<ForwarderTestFace>(boost::ref(io));
+ forwarder.addFace(face1);
+ forwarder.addFace(face2);
+
+ Fib& fib = forwarder.getFib();
+ std::pair<shared_ptr<fib::Entry>, bool> fibInsertResult =
+ fib.insert(Name("ndn:/A"));
+ shared_ptr<fib::Entry> fibEntry = fibInsertResult.first;
+ fibEntry->addNextHop(face2, 0);
+
+ face1->receiveInterest(interestAB);
+ io.run();
+ io.reset();
+ BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
+ BOOST_CHECK(face2->m_sentInterests[0].getName().equals(nameAB));
+
+ face2->receiveData(dataABC);
+ io.run();
+ io.reset();
+ BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
+ BOOST_CHECK(face1->m_sentDatas[0].getName().equals(nameABC));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace nfd
diff --git a/tests/table/fib.cpp b/tests/table/fib.cpp
index ceba1da..d4dc463 100644
--- a/tests/table/fib.cpp
+++ b/tests/table/fib.cpp
@@ -16,8 +16,8 @@
BOOST_AUTO_TEST_CASE(Entry)
{
Name prefix("ndn:/pxWhfFza");
- shared_ptr<Face> face1 = make_shared<DummyFace>(1);
- shared_ptr<Face> face2 = make_shared<DummyFace>(2);
+ shared_ptr<Face> face1 = make_shared<DummyFace>();
+ shared_ptr<Face> face2 = make_shared<DummyFace>();
fib::Entry entry(prefix);
BOOST_CHECK(entry.getPrefix().equals(prefix));
@@ -166,8 +166,8 @@
BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
{
- shared_ptr<Face> face1 = make_shared<DummyFace>(1);
- shared_ptr<Face> face2 = make_shared<DummyFace>(2);
+ shared_ptr<Face> face1 = make_shared<DummyFace>();
+ shared_ptr<Face> face2 = make_shared<DummyFace>();
Name nameA("ndn:/A");
Name nameB("ndn:/B");
diff --git a/tests/table/pit.cpp b/tests/table/pit.cpp
index 3d81c72..5fc50cd 100644
--- a/tests/table/pit.cpp
+++ b/tests/table/pit.cpp
@@ -15,8 +15,8 @@
BOOST_AUTO_TEST_CASE(EntryInOutRecords)
{
- shared_ptr<Face> face1 = make_shared<DummyFace>(1);
- shared_ptr<Face> face2 = make_shared<DummyFace>(2);
+ shared_ptr<Face> face1 = make_shared<DummyFace>();
+ shared_ptr<Face> face2 = make_shared<DummyFace>();
Name name("ndn:/KuYfjtRq");
Interest interest(name);
Interest interest1(name, static_cast<ndn::Milliseconds>(2528));