diff --git a/daemon/face/face.cpp b/daemon/face/face.cpp index 6518117a..9c8613bd 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 @@ Face::~Face() { } +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 9ff2d202..994bc782 100644 --- a/daemon/face/face.hpp +++ b/daemon/face/face.hpp @@ -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 { public: - Face(FaceId id); + Face(); virtual ~Face(); + + FaceId + getId() const; /// fires when an Interest is received EventEmitter 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 diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp index e0ea05b7..a764a073 100644 --- a/daemon/face/stream-face.hpp +++ b/daemon/face/stream-face.hpp @@ -17,8 +17,7 @@ class StreamFace : public Face public: typedef T protocol; - StreamFace(FaceId id, - const shared_ptr& socket); + StreamFace(const shared_ptr& socket); protected: void @@ -39,10 +38,8 @@ private: template inline -StreamFace::StreamFace(FaceId id, - const shared_ptr& socket) - : Face(id) - , m_socket(socket) +StreamFace::StreamFace(const shared_ptr& socket) + : m_socket(socket) { m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0, bind(&StreamFace::handleReceive, this, _1, _2)); diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp index 25244f8e..f67e9b2d 100644 --- a/daemon/face/tcp-channel.cpp +++ b/daemon/face/tcp-channel.cpp @@ -117,10 +117,7 @@ TcpChannel::handleConnection(const boost::system::error_code& error, return; } - /** - * \todo Remove FaceId from here - */ - shared_ptr face = make_shared(1, boost::cref(socket)); + shared_ptr face = make_shared(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 79f9b8ce..4a295ff4 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& socket) - : StreamFace(id, socket) +TcpFace::TcpFace(const shared_ptr& socket) + : StreamFace(socket) { } diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp index c76cbc83..cf3188c4 100644 --- a/daemon/face/tcp-face.hpp +++ b/daemon/face/tcp-face.hpp @@ -21,8 +21,7 @@ class TcpFace : public StreamFace public: typedef boost::asio::ip::tcp protocol; - TcpFace(FaceId id, - const shared_ptr& socket); + TcpFace(const shared_ptr& socket); // from Face virtual void diff --git a/daemon/fw/best-route-strategy.cpp b/daemon/fw/best-route-strategy.cpp index 12db7441..3b94531f 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 @@ void BestRouteStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest, shared_ptr fibEntry, - shared_ptr pitEntry, - pit::InRecordCollection::iterator pitInRecord) + shared_ptr 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 diff --git a/daemon/fw/best-route-strategy.hpp b/daemon/fw/best-route-strategy.hpp index 8e9f1273..c29caaea 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 @@ 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 fibEntry, - shared_ptr pitEntry, - pit::InRecordCollection::iterator pitInRecord - ); + shared_ptr 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 1ba6808b..d9850df8 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) -{ - return -1; + m_strategy = make_shared(boost::ref(*this)); } void -Forwarder::removeFace(const shared_ptr& face) +Forwarder::addFace(shared_ptr 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) { - this->onIncomingInterest(const_cast(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), 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, 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 pitEntry) { + NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() << " interest=" << interest.getName()); + // do nothing, which means Interest is dropped } void Forwarder::onOutgoingInterest(shared_ptr 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 pitEntry, Face& outFace) void Forwarder::onInterestRebuff(shared_ptr pitEntry) { + NFD_LOG_DEBUG("onInterestRebuff interest=" << pitEntry->getName()); + // set PIT straggler timer this->setStragglerTimer(pitEntry); } @@ -127,6 +160,8 @@ Forwarder::onInterestRebuff(shared_ptr pitEntry) void Forwarder::onInterestUnsatisfied(shared_ptr 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 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 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 diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp index 591254e0..1359737b 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 @@ class Forwarder public: Forwarder(boost::asio::io_service& ioService); - uint64_t - addFace(const shared_ptr& face); + void + addFace(shared_ptr face); void - removeFace(const shared_ptr& face); + removeFace(shared_ptr 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 > m_faces; + Fib m_fib; Pit m_pit; Cs m_cs; - // container< shared_ptr > m_faces; + /// the active strategy (only one strategy in mock) + shared_ptr 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 ed1233f0..f8c2f122 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 @@ void Strategy::sendInterest(shared_ptr pitEntry, shared_ptr outFace) { - m_fw.onOutgoingInterest(pitEntry, *outFace); + m_forwarder.onOutgoingInterest(pitEntry, *outFace); } void Strategy::rebuffPendingInterest(shared_ptr 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 1a6e47ff..ce21c135 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 @@ 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 fibEntry, - shared_ptr pitEntry, - pit::InRecordCollection::iterator pitInRecord - ) =0; + shared_ptr pitEntry) =0; //virtual void //beforeExpirePendingInterest() =0; @@ -57,9 +65,10 @@ protected: // actions rebuffPendingInterest(shared_ptr 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 cd66b4af..e3daeca6 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 a58a3ee2..c7b5d763 100644 --- a/tests/face/dummy-face.hpp +++ b/tests/face/dummy-face.hpp @@ -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) { } }; diff --git a/tests/face/face.cpp b/tests/face/face.cpp index dced5287..5245f513 100644 --- a/tests/face/face.cpp +++ b/tests/face/face.cpp @@ -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"); } diff --git a/tests/fw/forwarder.cpp b/tests/fw/forwarder.cpp new file mode 100644 index 00000000..cf5115f3 --- /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 + +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 m_sentInterests; + std::vector 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 face1 = make_shared(); + shared_ptr face2 = make_shared(); + + 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 face1 = make_shared(boost::ref(io)); + shared_ptr face2 = make_shared(boost::ref(io)); + forwarder.addFace(face1); + forwarder.addFace(face2); + + Fib& fib = forwarder.getFib(); + std::pair, bool> fibInsertResult = + fib.insert(Name("ndn:/A")); + shared_ptr 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 ceba1da5..d4dc463c 100644 --- a/tests/table/fib.cpp +++ b/tests/table/fib.cpp @@ -16,8 +16,8 @@ BOOST_AUTO_TEST_SUITE(TableFib) BOOST_AUTO_TEST_CASE(Entry) { Name prefix("ndn:/pxWhfFza"); - shared_ptr face1 = make_shared(1); - shared_ptr face2 = make_shared(2); + shared_ptr face1 = make_shared(); + shared_ptr face2 = make_shared(); 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 face1 = make_shared(1); - shared_ptr face2 = make_shared(2); + shared_ptr face1 = make_shared(); + shared_ptr face2 = make_shared(); Name nameA("ndn:/A"); Name nameB("ndn:/B"); diff --git a/tests/table/pit.cpp b/tests/table/pit.cpp index 3d81c72a..5fc50cdb 100644 --- a/tests/table/pit.cpp +++ b/tests/table/pit.cpp @@ -15,8 +15,8 @@ BOOST_AUTO_TEST_SUITE(TablePit) BOOST_AUTO_TEST_CASE(EntryInOutRecords) { - shared_ptr face1 = make_shared(1); - shared_ptr face2 = make_shared(2); + shared_ptr face1 = make_shared(); + shared_ptr face2 = make_shared(); Name name("ndn:/KuYfjtRq"); Interest interest(name); Interest interest1(name, static_cast(2528));