37 #include <boost/range/adaptor/reversed.hpp>
45 const time::milliseconds SelfLearningStrategy::ROUTE_RENEW_LIFETIME(10_min);
52 NDN_THROW(std::invalid_argument(
"SelfLearningStrategy does not accept parameters"));
56 "SelfLearningStrategy does not support version " +
to_string(*parsed.
version)));
64 static Name strategyName(
"/localhost/nfd/strategy/self-learning/%FD%01");
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);
83 this->
sendNack(pitEntry, ingress, nackHeader);
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);
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) {
156 pitEntry->getOutRecord(outFace)->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest =
false;
157 NFD_LOG_DEBUG(
"send discovery Interest=" << interest <<
" from="
158 << inFace.
getId() <<
" to=" << outFace.getId());
163 SelfLearningStrategy::multicastInterest(
const Interest& interest,
const Face& inFace,
164 const shared_ptr<pit::Entry>& pitEntry,
167 for (
const auto& nexthop : nexthops) {
168 Face& outFace = nexthop.getFace();
173 this->
sendInterest(pitEntry, FaceEndpoint(outFace, 0), interest);
174 pitEntry->getOutRecord(outFace)->insertStrategyInfo<OutRecordInfo>().first->isNonDiscoveryInterest =
true;
175 NFD_LOG_DEBUG(
"send non-discovery Interest=" << interest <<
" from="
176 << inFace.getId() <<
" to=" << outFace.getId());
181 SelfLearningStrategy::asyncProcessData(
const shared_ptr<pit::Entry>& pitEntry,
const Face& inFace,
const Data& data)
188 runOnRibIoService([pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data,
this] {
190 [pitEntryWeak, inFaceId, data,
this] (optional<ndn::PrefixAnnouncement> paOpt) {
192 runOnMainIoService([pitEntryWeak, inFaceId, data, pa = std::move(*paOpt), this] {
193 auto pitEntry = pitEntryWeak.lock();
194 auto inFace = this->getFace(inFaceId);
195 if (pitEntry && inFace) {
196 NFD_LOG_DEBUG(
"found PrefixAnnouncement=" << pa.getAnnouncedName());
197 data.setTag(make_shared<lp::PrefixAnnouncementTag>(lp::PrefixAnnouncementHeader(pa)));
198 this->sendDataToAll(pitEntry, FaceEndpoint(*inFace, 0), data);
199 this->setExpiryTimer(pitEntry, 0_ms);
202 NFD_LOG_DEBUG(
"PIT entry or Face no longer exists");
211 SelfLearningStrategy::needPrefixAnn(
const shared_ptr<pit::Entry>& pitEntry)
213 bool hasDiscoveryInterest =
false;
214 bool directToConsumer =
true;
217 for (
const auto& inRecord : pitEntry->getInRecords()) {
218 if (inRecord.getExpiry() > now) {
219 InRecordInfo* inRecordInfo = inRecord.getStrategyInfo<InRecordInfo>();
220 if (inRecordInfo && !inRecordInfo->isNonDiscoveryInterest) {
221 hasDiscoveryInterest =
true;
224 directToConsumer =
false;
228 return hasDiscoveryInterest && !directToConsumer;
232 SelfLearningStrategy::addRoute(
const shared_ptr<pit::Entry>& pitEntry,
const Face& inFace,
235 runOnRibIoService([pitEntryWeak = weak_ptr<pit::Entry>{pitEntry}, inFaceId = inFace.getId(), data, pa] {
238 NFD_LOG_DEBUG(
"Add route via PrefixAnnouncement with result=" << res);
244 SelfLearningStrategy::renewRoute(
const Name&
name,
FaceId inFaceId, time::milliseconds maxLifetime)