37 #include <boost/range/adaptor/reversed.hpp> 52 NDN_THROW(std::invalid_argument(
"SelfLearningStrategy does not accept parameters"));
56 "SelfLearningStrategy does not support version " +
to_string(*parsed.
version)));
64 static const auto strategyName =
Name(
"/localhost/nfd/strategy/self-learning").appendVersion(1);
70 const shared_ptr<pit::Entry>& pitEntry)
76 auto inRecordInfo = pitEntry->getInRecord(ingress.
face)->insertStrategyInfo<
InRecordInfo>().first;
78 inRecordInfo->isNonDiscoveryInterest =
true;
79 if (nexthops.empty()) {
80 NFD_LOG_DEBUG(
"NACK non-discovery Interest=" << interest <<
" from=" << ingress <<
" noNextHop");
82 nackHeader.
setReason(lp::NackReason::NO_ROUTE);
87 multicastInterest(interest, ingress.
face, pitEntry, nexthops);
91 inRecordInfo->isNonDiscoveryInterest =
false;
92 if (nexthops.empty()) {
93 broadcastInterest(interest, ingress.
face, pitEntry);
97 multicastInterest(interest, ingress.
face, pitEntry, nexthops);
104 const shared_ptr<pit::Entry>& pitEntry)
106 auto outRecord = pitEntry->getOutRecord(ingress.
face);
107 if (outRecord == pitEntry->out_end()) {
114 if (!needPrefixAnn(pitEntry)) {
118 asyncProcessData(pitEntry, ingress.
face, data);
123 if (paTag !=
nullptr) {
124 addRoute(pitEntry, ingress.
face, data, *paTag->get().getPrefixAnn());
134 const shared_ptr<pit::Entry>& pitEntry)
138 if (nack.
getReason() == lp::NackReason::NO_ROUTE) {
147 SelfLearningStrategy::broadcastInterest(
const Interest& interest,
const Face& inFace,
148 const shared_ptr<pit::Entry>& pitEntry)
150 for (
auto& outFace : this->
getFaceTable() | boost::adaptors::reversed) {
157 NFD_LOG_DEBUG(
"send discovery Interest=" << interest <<
" from=" << inFace.getId() <<
158 " to=" << outFace.getId());
159 auto outRecord = this->
sendInterest(interest, outFace, pitEntry);
160 if (outRecord !=
nullptr) {
167 SelfLearningStrategy::multicastInterest(
const Interest& interest,
const Face& inFace,
168 const shared_ptr<pit::Entry>& pitEntry,
171 for (
const auto& nexthop : nexthops) {
176 Face& outFace = nexthop.getFace();
177 NFD_LOG_DEBUG(
"send non-discovery Interest=" << interest <<
" from=" << inFace.getId() <<
178 " to=" << outFace.getId());
179 auto outRecord = this->
sendInterest(interest, outFace, pitEntry);
180 if (outRecord !=
nullptr) {
187 SelfLearningStrategy::asyncProcessData(
const shared_ptr<pit::Entry>& pitEntry,
const Face& inFace,
const Data& data)
194 runOnRibIoService([pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data,
this] {
196 [pitEntryWeak, inFaceId, data,
this] (optional<ndn::PrefixAnnouncement> paOpt) {
199 auto pitEntry = pitEntryWeak.lock();
200 auto inFace = this->
getFace(inFaceId);
201 if (pitEntry && inFace) {
202 NFD_LOG_DEBUG(
"found PrefixAnnouncement=" << pa.getAnnouncedName());
217 SelfLearningStrategy::needPrefixAnn(
const shared_ptr<pit::Entry>& pitEntry)
219 bool hasDiscoveryInterest =
false;
220 bool directToConsumer =
true;
223 for (
const auto& inRecord : pitEntry->getInRecords()) {
224 if (inRecord.getExpiry() > now) {
227 hasDiscoveryInterest =
true;
230 directToConsumer =
false;
234 return hasDiscoveryInterest && !directToConsumer;
238 SelfLearningStrategy::addRoute(
const shared_ptr<pit::Entry>& pitEntry,
const Face& inFace,
241 runOnRibIoService([pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data, pa] {
244 NFD_LOG_DEBUG(
"Add route via PrefixAnnouncement with result=" << res);
void setTag(shared_ptr< T > tag) const
set a tag item
void slRenew(const Name &name, uint64_t faceId, time::milliseconds maxLifetime, const SlAnnounceCallback &cb)
Renew a route created by prefix announcement from self-learning strategy.
static ParsedInstanceName parseInstanceName(const Name &input)
Parse a strategy instance name.
shared_ptr< T > getTag() const
get a tag item
#define NFD_LOG_INIT(name)
SelfLearningStrategy(Forwarder &forwarder, const Name &name=getStrategyName())
std::string to_string(const T &val)
void sendNacks(const lp::NackHeader &header, const shared_ptr< pit::Entry > &pitEntry, std::initializer_list< const Face *> exceptFaces={})
Send Nack to every face that has an in-record, except those in exceptFaces.
Represents a face-endpoint pair in the forwarder.
PartialName parameters
parameter components
static time_point now() noexcept
void slAnnounce(const ndn::PrefixAnnouncement &pa, uint64_t faceId, time::milliseconds maxLifetime, const SlAnnounceCallback &cb)
Insert a route by prefix announcement from self-learning strategy.
void runOnRibIoService(const std::function< void()> &f)
Run a function on the RIB io_service instance.
Face * getFace(FaceId id) const
Main class of NFD's forwarding engine.
StrategyInfo on pit::OutRecord.
void setInstanceName(const Name &name)
Set strategy instance name.
Represents an Interest packet.
const NackHeader & getHeader() const
void runOnMainIoService(const std::function< void()> &f)
Run a function on the main io_service instance.
Represents a collection of nexthops.
NFD_VIRTUAL_WITH_TESTS void rejectPendingInterest(const shared_ptr< pit::Entry > &pitEntry)
Schedule the PIT entry for immediate deletion.
A prefix announcement object that represents an application's intent of registering a prefix toward i...
represents a Network Nack
NackReason getReason() const
provides a tag type for simple types
NFD_VIRTUAL_WITH_TESTS void sendDataToAll(const Data &data, const shared_ptr< pit::Entry > &pitEntry, const Face &inFace)
Send a Data packet to all matched and qualified faces.
Copyright (c) 2011-2015 Regents of the University of California.
void afterReceiveData(const Data &data, const FaceEndpoint &ingress, const shared_ptr< pit::Entry > &pitEntry) override
trigger after Data is received
NFD_REGISTER_STRATEGY(AccessStrategy)
bool isNonDiscoveryInterest
const Name & getName() const noexcept
Get name.
Represents an absolute name.
RibManager & getRibManager()
NFD_VIRTUAL_WITH_TESTS bool sendNack(const lp::NackHeader &header, Face &egress, const shared_ptr< pit::Entry > &pitEntry)
Send a Nack packet.
Represents a forwarding strategy.
represents a zero-length TLV-VALUE
static Service & get()
Get a reference to the only instance of this class.
optional< uint64_t > version
whether strategyName contains a version component
This file contains common algorithms used by forwarding strategies.
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
Performs a FIB lookup, considering Link object if present.
const FaceTable & getFaceTable() const
const Name & getName() const noexcept
StrategyInfo on pit::InRecord.
bool isNextHopEligible(const Face &inFace, const Interest &interest, const fib::NextHop &nexthop, const shared_ptr< pit::Entry > &pitEntry, bool wantUnused, time::steady_clock::time_point now)
static Name makeInstanceName(const Name &input, const Name &strategyName)
Construct a strategy instance name.
void setExpiryTimer(const shared_ptr< pit::Entry > &pitEntry, time::milliseconds duration)
Schedule the PIT entry to be erased after duration.
const NextHopList & getNextHops() const
void slFindAnn(const Name &name, const SlFindAnnCallback &cb) const
Retrieve an outgoing prefix announcement for self-learning strategy.
NFD_VIRTUAL_WITH_TESTS pit::OutRecord * sendInterest(const Interest &interest, Face &egress, const shared_ptr< pit::Entry > &pitEntry)
Send an Interest packet.
static const Name & getStrategyName()
Represents a Data packet.
void afterReceiveInterest(const Interest &interest, const FaceEndpoint &ingress, const shared_ptr< pit::Entry > &pitEntry) override
Trigger after an Interest is received.
bool wouldViolateScope(const Face &inFace, const Interest &interest, const Face &outFace)
determine whether forwarding the Interest in pitEntry to outFace would violate scope ...
uint64_t FaceId
Identifies a face.
void afterReceiveNack(const lp::Nack &nack, const FaceEndpoint &ingress, const shared_ptr< pit::Entry > &pitEntry) override
Trigger after a Nack is received.
const Interest & getInterest() const
bool isNonDiscoveryInterest
Self-learning forwarding strategy.
boost::chrono::milliseconds milliseconds