face+fw: store and return PitToken from downstream

refs #4532

Change-Id: I97b95232a242186601459622f17983d1bef806d6
This commit is contained in:
Junxiao Shi committed 2019-09-23 12:47:44 -06:00
1 parent 24be073413
commit 606d5ddc9e
7 files changed
+248 -38

No files matched your search

+1
View File
@@ -124,6 +124,7 @@ namespace scheduler = ndn::scheduler;
namespace signal = ndn::util::signal;
namespace time = ndn::time;
using namespace ndn::time_literals;
using ndn::operator""_block;
} // namespace nfd
+14 -4
View File
@@ -25,6 +25,7 @@
#include "generic-link-service.hpp"
#include <ndn-cxx/lp/pit-token.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <cmath>
@@ -129,28 +130,33 @@ void
GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
{
if (m_options.allowLocalFields) {
shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
auto incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
if (incomingFaceIdTag != nullptr) {
lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
}
}
shared_ptr<lp::CongestionMarkTag> congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
auto congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
if (congestionMarkTag != nullptr) {
lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
}
if (m_options.allowSelfLearning) {
shared_ptr<lp::NonDiscoveryTag> nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
auto nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
if (nonDiscoveryTag != nullptr) {
lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
}
shared_ptr<lp::PrefixAnnouncementTag> prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
auto prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
if (prefixAnnouncementTag != nullptr) {
lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
}
}
auto pitToken = netPkt.getTag<lp::PitToken>();
if (pitToken != nullptr) {
lpPacket.add<lp::PitTokenField>(*pitToken);
}
}
void
@@ -388,6 +394,10 @@ GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstP
return;
}
if (firstPkt.has<lp::PitTokenField>()) {
interest->setTag(make_shared<lp::PitToken>(firstPkt.get<lp::PitTokenField>()));
}
this->receiveInterest(*interest, endpointId);
}
+27
View File
@@ -27,6 +27,8 @@
#include "forwarder.hpp"
#include "common/logger.hpp"
#include <ndn-cxx/lp/pit-token.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
@@ -191,16 +193,41 @@ Strategy::onDroppedInterest(const FaceEndpoint& egress, const Interest& interest
NFD_LOG_DEBUG("onDroppedInterest out=" << egress << " name=" << interest.getName());
}
void
Strategy::sendInterest(const shared_ptr<pit::Entry>& pitEntry,
const FaceEndpoint& egress, const Interest& interest)
{
if (interest.getTag<lp::PitToken>() != nullptr) {
Interest interest2 = interest; // make a copy to preserve tag on original packet
interest2.removeTag<lp::PitToken>();
m_forwarder.onOutgoingInterest(pitEntry, egress, interest2);
return;
}
m_forwarder.onOutgoingInterest(pitEntry, egress, interest);
}
void
Strategy::sendData(const shared_ptr<pit::Entry>& pitEntry, const Data& data,
const FaceEndpoint& egress)
{
BOOST_ASSERT(pitEntry->getInterest().matchesData(data));
shared_ptr<lp::PitToken> pitToken;
auto inRecord = pitEntry->getInRecord(egress.face);
if (inRecord != pitEntry->in_end()) {
pitToken = inRecord->getInterest().getTag<lp::PitToken>();
}
// delete the PIT entry's in-record based on egress,
// since Data is sent to face and endpoint from which the Interest was received
pitEntry->deleteInRecord(egress.face);
if (pitToken != nullptr) {
Data data2 = data; // make a copy so each downstream can get a different PIT token
data2.setTag(pitToken);
m_forwarder.onOutgoingData(data2, egress);
return;
}
m_forwarder.onOutgoingData(data, egress);
}
+1 -4
View File
@@ -241,10 +241,7 @@ protected: // actions
*/
VIRTUAL_WITH_TESTS void
sendInterest(const shared_ptr<pit::Entry>& pitEntry,
const FaceEndpoint& egress, const Interest& interest)
{
m_forwarder.onOutgoingInterest(pitEntry, egress, interest);
}
const FaceEndpoint& egress, const Interest& interest);
/** \brief send \p data to \p egress
* \param pitEntry PIT entry
+79
View File
@@ -0,0 +1,79 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tests/daemon/global-io-fixture.hpp"
#include "topology-tester.hpp"
#include <ndn-cxx/lp/packet.hpp>
#include <ndn-cxx/lp/pit-token.hpp>
namespace nfd {
namespace fw {
namespace tests {
using namespace nfd::tests;
BOOST_AUTO_TEST_SUITE(Fw)
BOOST_AUTO_TEST_SUITE(TestPitToken)
// Downstream requires PIT token.
BOOST_FIXTURE_TEST_CASE(Downstream, GlobalIoTimeFixture)
{
TopologyTester topo;
TopologyNode nodeR = topo.addForwarder("R");
auto linkC = topo.addBareLink("C", nodeR, ndn::nfd::FACE_SCOPE_NON_LOCAL);
auto linkS = topo.addBareLink("S", nodeR, ndn::nfd::FACE_SCOPE_NON_LOCAL);
topo.registerPrefix(nodeR, linkS->getForwarderFace(), "/U", 5);
// Client --- Router --- Server
// Client requires PIT token; Router supports PIT token; Server disallows PIT token.
// C sends Interest /U/0 with PIT token
lp::Packet lppI("6414 pit-token=6206A0A1A2A3A4A5 payload=500A interest=0508 0706080155080130"_block);
lp::PitToken tokenI(lppI.get<lp::PitTokenField>());
linkC->receivePacket(lppI.wireEncode());
advanceClocks(5_ms, 30_ms);
// S should receive Interest without PIT token
BOOST_REQUIRE_EQUAL(linkS->sentPackets.size(), 1);
lp::Packet lppS(linkS->sentPackets.front());
BOOST_CHECK_EQUAL(lppS.count<lp::PitTokenField>(), 0);
// S responds Data
linkS->receivePacket(makeData("/U/0")->wireEncode());
advanceClocks(5_ms, 30_ms);
// C should receive Data with same PIT token
BOOST_REQUIRE_EQUAL(linkC->sentPackets.size(), 1);
lp::Packet lppD(linkC->sentPackets.front());
lp::PitToken tokenD(lppD.get<lp::PitTokenField>());
BOOST_CHECK(tokenD == tokenI);
}
BOOST_AUTO_TEST_SUITE_END() // TestPitToken
BOOST_AUTO_TEST_SUITE_END() // Fw
} // namespace tests
} // namespace fw
} // namespace nfd
+66 -19
View File
@@ -104,9 +104,14 @@ TopologyLink::transmit(TopologyNode i, const Block& packet)
}
}
TopologyAppLink::TopologyAppLink(shared_ptr<Face> forwarderFace)
TopologySingleLink::TopologySingleLink(shared_ptr<Face> forwarderFace)
: m_face(std::move(forwarderFace))
, m_forwarderTransport(static_cast<InternalForwarderTransport*>(m_face->getTransport()))
{
}
TopologyAppLink::TopologyAppLink(shared_ptr<Face> forwarderFace)
: TopologySingleLink(std::move(forwarderFace))
, m_clientTransport(make_shared<InternalClientTransport>())
, m_client(make_shared<ndn::Face>(m_clientTransport, getGlobalIoService()))
{
@@ -125,6 +130,38 @@ TopologyAppLink::recover()
m_clientTransport->connectToForwarder(m_forwarderTransport);
}
class TopologyBareLink::Observer : public face::InternalTransportBase
{
public:
explicit
Observer(std::vector<Block>& receivedPackets)
: m_receivedPackets(receivedPackets)
{
}
void
receivePacket(const Block& packet) final
{
m_receivedPackets.push_back(packet);
}
private:
std::vector<Block>& m_receivedPackets;
};
TopologyBareLink::TopologyBareLink(shared_ptr<Face> forwarderFace)
: TopologySingleLink(std::move(forwarderFace))
, m_observer(make_unique<Observer>(sentPackets))
{
m_forwarderTransport->setPeer(m_observer.get());
}
void
TopologyBareLink::receivePacket(const Block& packet)
{
m_forwarderTransport->receivePacket(packet);
}
class TopologyPcapLinkService : public GenericLinkService
, public TopologyPcap
{
@@ -166,6 +203,19 @@ TopologyTester::addForwarder(const std::string& label)
return i;
}
shared_ptr<Face>
TopologyTester::makeFace(TopologyNode i, const FaceUri& localUri, const FaceUri& remoteUri,
ndn::nfd::FaceScope scope, ndn::nfd::LinkType linkType)
{
Forwarder& forwarder = this->getForwarder(i);
unique_ptr<GenericLinkService> service = m_wantPcap ? make_unique<TopologyPcapLinkService>() :
make_unique<GenericLinkService>();
auto transport = make_unique<InternalForwarderTransport>(localUri, remoteUri, scope, linkType);
auto face = make_shared<Face>(std::move(service), std::move(transport));
forwarder.addFace(face);
return face;
}
shared_ptr<TopologyLink>
TopologyTester::addLink(const std::string& label, time::nanoseconds delay,
std::initializer_list<TopologyNode> forwarders,
@@ -180,16 +230,8 @@ TopologyTester::addLink(const std::string& label, time::nanoseconds delay,
BOOST_ASSERT(forwarders.size() <= 2 || linkType != ndn::nfd::LINK_TYPE_POINT_TO_POINT);
for (TopologyNode i : forwarders) {
Forwarder& forwarder = this->getForwarder(i);
FaceUri localUri("topology://" + m_forwarderLabels.at(i) + "/" + label);
unique_ptr<GenericLinkService> service = m_wantPcap ? make_unique<TopologyPcapLinkService>() :
make_unique<GenericLinkService>();
auto transport = make_unique<InternalForwarderTransport>(localUri, remoteUri,
ndn::nfd::FACE_SCOPE_NON_LOCAL, linkType);
auto face = make_shared<Face>(std::move(service), std::move(transport));
forwarder.addFace(face);
auto face = makeFace(i, localUri, remoteUri, ndn::nfd::FACE_SCOPE_NON_LOCAL, linkType);
link->addFace(i, std::move(face));
}
@@ -200,17 +242,9 @@ TopologyTester::addLink(const std::string& label, time::nanoseconds delay,
shared_ptr<TopologyAppLink>
TopologyTester::addAppFace(const std::string& label, TopologyNode i)
{
Forwarder& forwarder = this->getForwarder(i);
FaceUri localUri("topology://" + m_forwarderLabels.at(i) + "/local/" + label);
FaceUri remoteUri("topology://" + m_forwarderLabels.at(i) + "/app/" + label);
unique_ptr<GenericLinkService> service = m_wantPcap ? make_unique<TopologyPcapLinkService>() :
make_unique<GenericLinkService>();
auto transport = make_unique<InternalForwarderTransport>(localUri, remoteUri,
ndn::nfd::FACE_SCOPE_LOCAL, ndn::nfd::LINK_TYPE_POINT_TO_POINT);
auto face = make_shared<Face>(std::move(service), std::move(transport));
forwarder.addFace(face);
auto face = makeFace(i, localUri, remoteUri, ndn::nfd::FACE_SCOPE_LOCAL, ndn::nfd::LINK_TYPE_POINT_TO_POINT);
auto al = make_shared<TopologyAppLink>(std::move(face));
m_appLinks.push_back(al); // keep a shared_ptr so callers don't have to
@@ -225,6 +259,19 @@ TopologyTester::addAppFace(const std::string& label, TopologyNode i, const Name&
return al;
}
shared_ptr<TopologyBareLink>
TopologyTester::addBareLink(const std::string& label, TopologyNode i, ndn::nfd::FaceScope scope,
ndn::nfd::LinkType linkType)
{
FaceUri localUri("topology://" + m_forwarderLabels.at(i) + "/local/" + label);
FaceUri remoteUri("topology://" + m_forwarderLabels.at(i) + "/bare/" + label);
auto face = makeFace(i, localUri, remoteUri, scope, linkType);
auto bl = make_shared<TopologyBareLink>(std::move(face));
m_bareLinks.push_back(bl); // keep a shared_ptr so callers don't have to
return bl;
}
void
TopologyTester::enablePcap(bool isEnabled)
{
+60 -11
View File
@@ -150,9 +150,33 @@ private:
std::unordered_map<TopologyNode, NodeTransport> m_transports;
};
/** \brief represents a link on a single forwarder
*/
class TopologySingleLink : noncopyable
{
public:
/** \brief constructor
* \param forwarderFace a Face with InternalForwarderTransport
*/
explicit
TopologySingleLink(shared_ptr<Face> forwarderFace);
/** \return face on forwarder side
*/
Face&
getForwarderFace()
{
return *m_face;
}
protected:
shared_ptr<Face> m_face;
face::InternalForwarderTransport* m_forwarderTransport;
};
/** \brief represents a link to a local application
*/
class TopologyAppLink : noncopyable
class TopologyAppLink : public TopologySingleLink
{
public:
/** \brief constructor
@@ -171,14 +195,6 @@ public:
void
recover();
/** \return face on forwarder side
*/
Face&
getForwarderFace()
{
return *m_face;
}
/** \return face on application side
*/
ndn::Face&
@@ -188,12 +204,32 @@ public:
}
private:
shared_ptr<Face> m_face;
face::InternalForwarderTransport* m_forwarderTransport;
shared_ptr<face::InternalClientTransport> m_clientTransport;
shared_ptr<ndn::Face> m_client;
};
/** \brief allows the test case to inject and observe L2 packets on a link
*/
class TopologyBareLink : public TopologySingleLink
{
public:
/** \brief constructor
* \param forwarderFace a Face with InternalForwarderTransport
*/
explicit
TopologyBareLink(shared_ptr<Face> forwarderFace);
void
receivePacket(const Block& packet);
public:
std::vector<Block> sentPackets;
private:
class Observer;
unique_ptr<Observer> m_observer;
};
/** \brief captured packets on a face
*/
class TopologyPcap : noncopyable
@@ -264,6 +300,13 @@ public:
shared_ptr<TopologyAppLink>
addAppFace(const std::string& label, TopologyNode i, const Name& prefix, uint64_t cost = 0);
/** \brief makes a link that allows the test case to inject and observe L2 packets
*/
shared_ptr<TopologyBareLink>
addBareLink(const std::string& label, TopologyNode i,
ndn::nfd::FaceScope scope = ndn::nfd::FACE_SCOPE_LOCAL,
ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_POINT_TO_POINT);
/** \brief enables packet capture on every forwarder face
*/
void
@@ -293,12 +336,18 @@ public:
addIntervalConsumer(ndn::Face& face, const Name& prefix, time::nanoseconds interval,
size_t n, int seq = -1);
private:
shared_ptr<Face>
makeFace(TopologyNode i, const FaceUri& localUri, const FaceUri& remoteUri,
ndn::nfd::FaceScope scope, ndn::nfd::LinkType linkType);
private:
bool m_wantPcap = false;
std::vector<unique_ptr<Forwarder>> m_forwarders;
std::vector<std::string> m_forwarderLabels;
std::vector<shared_ptr<TopologyLink>> m_links;
std::vector<shared_ptr<TopologyAppLink>> m_appLinks;
std::vector<shared_ptr<TopologyBareLink>> m_bareLinks;
};
} // namespace tests