face+fw: store and return PitToken from downstream
refs #4532 Change-Id: I97b95232a242186601459622f17983d1bef806d6
This commit is contained in:
1 parent
24be073413
commit
606d5ddc9e
7 files changed
+248
-38
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user