fw: integrate forwarder, strategy, tables

refs #1131, #1136

Change-Id: Ica58341cdc1ea1dc421693a87f35fc50177a707d
This commit is contained in:
Junxiao Shi
2014-01-30 22:33:00 -07:00
parent 234a532c0a
commit 8c8d2187b3
18 changed files with 291 additions and 69 deletions
+14 -2
View File
@@ -8,8 +8,8 @@
namespace nfd {
Face::Face(FaceId id)
: m_id(id)
Face::Face()
: m_id(INVALID_FACEID)
{
}
@@ -17,6 +17,18 @@ Face::~Face()
{
}
FaceId
Face::getId() const
{
return m_id;
}
FaceId
Face::setId(FaceId faceId)
{
m_id = faceId;
}
bool
Face::isUp() const
{
+13 -1
View File
@@ -17,6 +17,8 @@ namespace nfd {
*/
typedef int FaceId;
const FaceId INVALID_FACEID = -1;
const std::size_t MAX_NDN_PACKET_SIZE = 8800;
/** \class Face
@@ -25,10 +27,13 @@ const std::size_t MAX_NDN_PACKET_SIZE = 8800;
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;
@@ -80,9 +85,16 @@ protected:
// void
// receiveData();
private:
FaceId
setId(FaceId faceId);
private:
FaceId m_id;
std::string m_description;
// allow setting FaceId
friend class Forwarder;
};
} // namespace nfd
+3 -6
View File
@@ -17,8 +17,7 @@ class StreamFace : public Face
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 @@ private:
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));
+1 -4
View File
@@ -117,10 +117,7 @@ TcpChannel::handleConnection(const boost::system::error_code& error,
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();
+2 -3
View File
@@ -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)
{
}
+1 -2
View File
@@ -21,8 +21,7 @@ class TcpFace : public StreamFace<boost::asio::ip::tcp>
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
+5 -4
View File
@@ -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 @@ void
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 @@ BestRouteStrategy::afterReceiveInterest(const Face& inFace,
this->sendInterest(pitEntry, outFace);
}
} // namespace fw
} // namespace nfd
+5 -4
View File
@@ -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 @@ class BestRouteStrategy : public Strategy
{
public:
explicit
BestRouteStrategy(Forwarder& fw);
BestRouteStrategy(Forwarder& forwarder);
virtual
~BestRouteStrategy();
@@ -28,11 +30,10 @@ public:
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
+53 -12
View File
@@ -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 @@ Forwarder::onIncomingInterest(Face& inFace, const Interest& interest)
// 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 @@ Forwarder::onOutgoingInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace)
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 @@ Forwarder::onInterestRebuff(shared_ptr<pit::Entry> pitEntry)
void
Forwarder::onInterestUnsatisfied(shared_ptr<pit::Entry> pitEntry)
{
NFD_LOG_DEBUG("onInterestUnsatisfied interest=" << pitEntry->getName());
// invoke PIT unsatisfied callback
// TODO
@@ -138,6 +173,7 @@ void
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 @@ Forwarder::onIncomingData(Face& inFace, const Data& data)
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 @@ Forwarder::onDataUnsolicited(Face& inFace, const Data& data)
// 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
+42 -7
View File
@@ -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 @@ class Forwarder
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:
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
+7 -4
View File
@@ -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 @@ void
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
+15 -6
View File
@@ -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 @@ class Strategy
{
public:
explicit
Strategy(Forwarder& fw);
Strategy(Forwarder& forwarder);
virtual
~Strategy();
@@ -27,9 +37,7 @@ public:
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 @@ protected: // actions
rebuffPendingInterest(shared_ptr<pit::Entry> pitEntry);
private:
Forwarder& m_fw;
Forwarder& m_forwarder;
};
} // namespace fw
} // namespace nfd
#endif // NFD_FW_STRATEGY_HPP
-3
View File
@@ -8,10 +8,7 @@
namespace nfd {
const FaceId INTERNAL_FACE_FACEID = 0;
InternalFace::InternalFace()
: Face(INTERNAL_FACE_FACEID)
{
}
+3 -4
View File
@@ -18,18 +18,17 @@ namespace nfd {
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)
{
}
};
+1 -1
View File
@@ -15,7 +15,7 @@ BOOST_AUTO_TEST_SUITE(FaceFace)
BOOST_AUTO_TEST_CASE(Description)
{
DummyFace face(1);
DummyFace face;
face.setDescription("3pFsKrvWr");
BOOST_CHECK_EQUAL(face.getDescription(), "3pFsKrvWr");
}
+120
View File
@@ -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
+4 -4
View File
@@ -16,8 +16,8 @@ BOOST_AUTO_TEST_SUITE(TableFib)
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(Insert_LongestPrefixMatch)
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");
+2 -2
View File
@@ -15,8 +15,8 @@ BOOST_AUTO_TEST_SUITE(TablePit)
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));