NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
strategy.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "strategy.hpp"
27 #include "forwarder.hpp"
28 #include "algorithm.hpp"
29 #include "core/logger.hpp"
30 #include "core/random.hpp"
31 
32 namespace nfd {
33 namespace fw {
34 
35 NFD_LOG_INIT("Strategy");
36 
38  : afterAddFace(forwarder.getFaceTable().afterAdd)
39  , beforeRemoveFace(forwarder.getFaceTable().beforeRemove)
40  , m_name(name)
41  , m_forwarder(forwarder)
42  , m_measurements(m_forwarder.getMeasurements(), m_forwarder.getStrategyChoice(), *this)
43 {
44 }
45 
46 Strategy::~Strategy() = default;
47 
48 void
49 Strategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
50  const Face& inFace, const Data& data)
51 {
52  NFD_LOG_DEBUG("beforeSatisfyInterest pitEntry=" << pitEntry->getName() <<
53  " inFace=" << inFace.getId() << " data=" << data.getName());
54 }
55 
56 void
57 Strategy::beforeExpirePendingInterest(const shared_ptr<pit::Entry>& pitEntry)
58 {
59  NFD_LOG_DEBUG("beforeExpirePendingInterest pitEntry=" << pitEntry->getName());
60 }
61 
62 void
63 Strategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
64  const shared_ptr<pit::Entry>& pitEntry)
65 {
66  NFD_LOG_DEBUG("afterReceiveNack inFace=" << inFace.getId() <<
67  " pitEntry=" << pitEntry->getName());
68 }
69 
70 void
71 Strategy::sendInterest(const shared_ptr<pit::Entry>& pitEntry, Face& outFace,
72  bool wantNewNonce)
73 {
74  // scope control
75  if (fw::violatesScope(*pitEntry, outFace)) {
76  NFD_LOG_DEBUG("sendInterestLegacy face=" << outFace.getId() <<
77  " interest=" << pitEntry->getName() << " violates scope");
78  return;
79  }
80 
81  // pick Interest
82  // The outgoing Interest picked is the last incoming Interest that does not come from outFace.
83  // If all in-records come from outFace, it's fine to pick that.
84  // This happens when there's only one in-record that comes from outFace.
85  // The legit use is for vehicular network; otherwise, strategy shouldn't send to the sole inFace.
86  pit::InRecordCollection::iterator pickedInRecord = std::max_element(
87  pitEntry->in_begin(), pitEntry->in_end(),
88  [&outFace] (const pit::InRecord& a, const pit::InRecord& b) {
89  bool isOutFaceA = &a.getFace() == &outFace;
90  bool isOutFaceB = &b.getFace() == &outFace;
91  return (isOutFaceA > isOutFaceB) ||
92  (isOutFaceA == isOutFaceB && a.getLastRenewed() < b.getLastRenewed());
93  });
94  BOOST_ASSERT(pickedInRecord != pitEntry->in_end());
95  auto interest = const_pointer_cast<Interest>(pickedInRecord->getInterest().shared_from_this());
96 
97  if (wantNewNonce) {
98  interest = make_shared<Interest>(*interest);
99  static std::uniform_int_distribution<uint32_t> dist;
100  interest->setNonce(dist(getGlobalRng()));
101  }
102 
103  this->sendInterest(pitEntry, outFace, *interest);
104 }
105 
106 void
107 Strategy::sendNacks(const shared_ptr<pit::Entry>& pitEntry, const lp::NackHeader& header,
108  std::initializer_list<const Face*> exceptFaces)
109 {
110  // populate downstreams with all downstreams faces
111  std::unordered_set<const Face*> downstreams;
112  std::transform(pitEntry->in_begin(), pitEntry->in_end(), std::inserter(downstreams, downstreams.end()),
113  [] (const pit::InRecord& inR) { return &inR.getFace(); });
114 
115  // delete excluded faces
116  // .erase in a loop is more efficient than std::set_difference because that requires sorted range
117  for (const Face* exceptFace : exceptFaces) {
118  downstreams.erase(exceptFace);
119  }
120 
121  // send Nacks
122  for (const Face* downstream : downstreams) {
123  this->sendNack(pitEntry, *downstream, header);
124  }
125  // warning: don't loop on pitEntry->getInRecords(), because in-record is deleted when sending Nack
126 }
127 
128 const fib::Entry&
129 Strategy::lookupFib(const pit::Entry& pitEntry) const
130 {
131  const Fib& fib = m_forwarder.getFib();
132  const NetworkRegionTable& nrt = m_forwarder.getNetworkRegionTable();
133 
134  const Interest& interest = pitEntry.getInterest();
135  // has Link object?
136  if (!interest.hasLink()) {
137  // FIB lookup with Interest name
138  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(pitEntry);
139  NFD_LOG_TRACE("lookupFib noLinkObject found=" << fibEntry.getPrefix());
140  return fibEntry;
141  }
142 
143  const Link& link = interest.getLink();
144 
145  // in producer region?
146  if (nrt.isInProducerRegion(link)) {
147  // FIB lookup with Interest name
148  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(pitEntry);
149  NFD_LOG_TRACE("lookupFib inProducerRegion found=" << fibEntry.getPrefix());
150  return fibEntry;
151  }
152 
153  // has SelectedDelegation?
154  if (interest.hasSelectedDelegation()) {
155  // FIB lookup with SelectedDelegation
156  Name selectedDelegation = interest.getSelectedDelegation();
157  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(selectedDelegation);
158  NFD_LOG_TRACE("lookupFib hasSelectedDelegation=" << selectedDelegation << " found=" << fibEntry.getPrefix());
159  return fibEntry;
160  }
161 
162  // FIB lookup with first delegation Name
163  const fib::Entry& fibEntry0 = fib.findLongestPrefixMatch(link.getDelegations().begin()->second);
164  // in default-free zone?
165  bool isDefaultFreeZone = !(fibEntry0.getPrefix().size() == 0 && fibEntry0.hasNextHops());
166  if (!isDefaultFreeZone) {
167  NFD_LOG_TRACE("lookupFib inConsumerRegion found=" << fibEntry0.getPrefix());
168  return fibEntry0;
169  }
170 
171  // choose and set SelectedDelegation
172  for (const std::pair<uint32_t, Name>& delegation : link.getDelegations()) {
173  const Name& delegationName = delegation.second;
174  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(delegationName);
175  if (fibEntry.hasNextHops()) {
178  std::for_each(pitEntry.in_begin(), pitEntry.in_end(),
179  [&delegationName] (const pit::InRecord& inR) {
180  const_cast<Interest&>(inR.getInterest()).setSelectedDelegation(delegationName);
181  });
182  NFD_LOG_TRACE("lookupFib enterDefaultFreeZone setSelectedDelegation=" << delegationName);
183  return fibEntry;
184  }
185  }
186  BOOST_ASSERT(false);
187  return fibEntry0;
188 }
189 
190 } // namespace fw
191 } // namespace nfd
const Name & getPrefix() const
Definition: fib-entry.hpp:58
const Link & getLink() const
Get the link object for this interest.
Definition: interest.cpp:370
generalization of a network interface
Definition: face.hpp:67
represents a FIB entry
Definition: fib-entry.hpp:51
void sendNack(const shared_ptr< pit::Entry > &pitEntry, const Face &outFace, const lp::NackHeader &header)
send Nack to outFace
Definition: strategy.hpp:175
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:318
contains information about an Interest from an incoming face
Fib & getFib()
Definition: forwarder.hpp:137
virtual void beforeExpirePendingInterest(const shared_ptr< pit::Entry > &pitEntry)
trigger before PIT entry expires
Definition: strategy.cpp:57
main class of NFD
Definition: forwarder.hpp:54
represents an Interest packet
Definition: interest.hpp:42
#define NFD_LOG_DEBUG(expression)
Definition: logger.hpp:55
stores a collection of producer region names
const Entry & findLongestPrefixMatch(const Name &prefix) const
performs a longest prefix match
Definition: fib.cpp:74
Face & getFace() const
represents a Network Nack
Definition: nack.hpp:40
Table::const_iterator iterator
Definition: cs-internal.hpp:41
virtual void afterReceiveNack(const Face &inFace, const lp::Nack &nack, const shared_ptr< pit::Entry > &pitEntry)
trigger after Nack is received
Definition: strategy.cpp:63
virtual ~Strategy()
#define NFD_LOG_TRACE(expression)
Definition: logger.hpp:54
Name getSelectedDelegation() const
Get the name of the selected delegation.
Definition: interest.cpp:409
bool violatesScope(const pit::Entry &pitEntry, const Face &outFace)
Definition: algorithm.cpp:59
InRecordCollection::iterator in_end()
Definition: pit-entry.hpp:122
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
an Interest table entry
Definition: pit-entry.hpp:57
Interest & setNonce(uint32_t nonce)
Set Interest&#39;s nonce.
Definition: interest.cpp:76
represents the Forwarding Information Base (FIB)
Definition: fib.hpp:47
FaceId getId() const
Definition: face.hpp:229
bool isInProducerRegion(const Link &link) const
determines whether an Interest has reached a producer region
virtual void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace, const Data &data)
trigger before PIT entry is satisfied
Definition: strategy.cpp:49
Strategy(Forwarder &forwarder, const Name &name)
construct a strategy instance
Definition: strategy.cpp:37
Name abstraction to represent an absolute name.
Definition: name.hpp:46
const Interest & getInterest() const
Definition: pit-entry.hpp:69
size_t size() const
Get the number of components.
Definition: name.hpp:400
void sendNacks(const shared_ptr< pit::Entry > &pitEntry, const lp::NackHeader &header, std::initializer_list< const Face *> exceptFaces=std::initializer_list< const Face *>())
send Nack to every face that has an in-record, except those in exceptFaces
Definition: strategy.cpp:107
std::mt19937 & getGlobalRng()
Definition: random.cpp:32
InRecordCollection::iterator in_begin()
Definition: pit-entry.hpp:110
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
performs a FIB lookup, considering Link object if present
Definition: strategy.cpp:129
NetworkRegionTable & getNetworkRegionTable()
Definition: forwarder.hpp:173
bool hasLink() const
Check whether the Interest contains a Link object.
Definition: interest.cpp:364
bool hasSelectedDelegation() const
Check whether the Interest includes a selected delegation.
Definition: interest.cpp:403
#define NFD_LOG_INIT(name)
Definition: logger.hpp:34
represents a Data packet
Definition: data.hpp:37
represents a Network NACK header
Definition: nack-header.hpp:52
void sendInterest(const shared_ptr< pit::Entry > &pitEntry, Face &outFace, const Interest &interest)
send Interest to outFace
Definition: strategy.hpp:137
bool hasNextHops() const
Definition: fib-entry.hpp:72
time::steady_clock::TimePoint getLastRenewed() const