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 "core/logger.hpp"
29 
30 namespace nfd {
31 namespace fw {
32 
33 NFD_LOG_INIT("Strategy");
34 
35 Strategy::Strategy(Forwarder& forwarder, const Name& name)
36  : afterAddFace(forwarder.getFaceTable().afterAdd)
37  , beforeRemoveFace(forwarder.getFaceTable().beforeRemove)
38  , m_name(name)
39  , m_forwarder(forwarder)
40  , m_measurements(m_forwarder.getMeasurements(), m_forwarder.getStrategyChoice(), *this)
41 {
42 }
43 
44 Strategy::~Strategy() = default;
45 
46 void
47 Strategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
48  const Face& inFace, const Data& data)
49 {
50  NFD_LOG_DEBUG("beforeSatisfyInterest pitEntry=" << pitEntry->getName() <<
51  " inFace=" << inFace.getId() << " data=" << data.getName());
52 }
53 
54 void
55 Strategy::beforeExpirePendingInterest(const shared_ptr<pit::Entry>& pitEntry)
56 {
57  NFD_LOG_DEBUG("beforeExpirePendingInterest pitEntry=" << pitEntry->getName());
58 }
59 
60 void
61 Strategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
62  const shared_ptr<pit::Entry>& pitEntry)
63 {
64  NFD_LOG_DEBUG("afterReceiveNack inFace=" << inFace.getId() <<
65  " pitEntry=" << pitEntry->getName());
66 }
67 
68 void
69 Strategy::sendNacks(const shared_ptr<pit::Entry>& pitEntry, const lp::NackHeader& header,
70  std::initializer_list<const Face*> exceptFaces)
71 {
72  // populate downstreams with all downstreams faces
73  std::unordered_set<const Face*> downstreams;
74  std::transform(pitEntry->in_begin(), pitEntry->in_end(), std::inserter(downstreams, downstreams.end()),
75  [] (const pit::InRecord& inR) { return &inR.getFace(); });
76 
77  // delete excluded faces
78  // .erase in a loop is more efficient than std::set_difference because that requires sorted range
79  for (const Face* exceptFace : exceptFaces) {
80  downstreams.erase(exceptFace);
81  }
82 
83  // send Nacks
84  for (const Face* downstream : downstreams) {
85  this->sendNack(pitEntry, *downstream, header);
86  }
87  // warning: don't loop on pitEntry->getInRecords(), because in-record is deleted when sending Nack
88 }
89 
90 const fib::Entry&
91 Strategy::lookupFib(const pit::Entry& pitEntry) const
92 {
93  const Fib& fib = m_forwarder.getFib();
94  const NetworkRegionTable& nrt = m_forwarder.getNetworkRegionTable();
95 
96  const Interest& interest = pitEntry.getInterest();
97  // has Link object?
98  if (!interest.hasLink()) {
99  // FIB lookup with Interest name
100  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(pitEntry);
101  NFD_LOG_TRACE("lookupFib noLinkObject found=" << fibEntry.getPrefix());
102  return fibEntry;
103  }
104 
105  const Link& link = interest.getLink();
106 
107  // in producer region?
108  if (nrt.isInProducerRegion(link)) {
109  // FIB lookup with Interest name
110  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(pitEntry);
111  NFD_LOG_TRACE("lookupFib inProducerRegion found=" << fibEntry.getPrefix());
112  return fibEntry;
113  }
114 
115  // has SelectedDelegation?
116  if (interest.hasSelectedDelegation()) {
117  // FIB lookup with SelectedDelegation
118  Name selectedDelegation = interest.getSelectedDelegation();
119  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(selectedDelegation);
120  NFD_LOG_TRACE("lookupFib hasSelectedDelegation=" << selectedDelegation << " found=" << fibEntry.getPrefix());
121  return fibEntry;
122  }
123 
124  // FIB lookup with first delegation Name
125  const fib::Entry& fibEntry0 = fib.findLongestPrefixMatch(link.getDelegations().begin()->second);
126  // in default-free zone?
127  bool isDefaultFreeZone = !(fibEntry0.getPrefix().size() == 0 && fibEntry0.hasNextHops());
128  if (!isDefaultFreeZone) {
129  NFD_LOG_TRACE("lookupFib inConsumerRegion found=" << fibEntry0.getPrefix());
130  return fibEntry0;
131  }
132 
133  // choose and set SelectedDelegation
134  for (const std::pair<uint32_t, Name>& delegation : link.getDelegations()) {
135  const Name& delegationName = delegation.second;
136  const fib::Entry& fibEntry = fib.findLongestPrefixMatch(delegationName);
137  if (fibEntry.hasNextHops()) {
140  std::for_each(pitEntry.in_begin(), pitEntry.in_end(),
141  [&delegationName] (const pit::InRecord& inR) {
142  const_cast<Interest&>(inR.getInterest()).setSelectedDelegation(delegationName);
143  });
144  NFD_LOG_TRACE("lookupFib enterDefaultFreeZone setSelectedDelegation=" << delegationName);
145  return fibEntry;
146  }
147  }
148  BOOST_ASSERT(false);
149  return fibEntry0;
150 }
151 
152 } // namespace fw
153 } // namespace nfd
main class of NFD
Definition: forwarder.hpp:52
#define NFD_LOG_DEBUG(expression)
Definition: logger.hpp:161
Strategy(Forwarder &forwarder, const Name &name)
construct a strategy instance
Definition: strategy.cpp:35
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:69
bool isInProducerRegion(const Link &link) const
determines whether an Interest has reached a producer region
Fib & getFib()
Definition: forwarder.hpp:135
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:164
virtual void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace, const Data &data)
trigger before PIT entry is satisfied
Definition: strategy.cpp:47
an Interest table entry
Definition: pit-entry.hpp:57
const Name & getPrefix() const
Definition: fib-entry.hpp:58
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
Definition: algorithm.hpp:32
Face & getFace() const
contains information about an Interest from an incoming face
virtual void afterReceiveNack(const Face &inFace, const lp::Nack &nack, const shared_ptr< pit::Entry > &pitEntry)
trigger after Nack is received
Definition: strategy.cpp:61
stores a collection of producer region names
InRecordCollection::iterator in_end()
Definition: pit-entry.hpp:115
const Interest & getInterest() const
Definition: pit-entry.hpp:69
#define NFD_LOG_INIT(name)
Definition: logger.hpp:122
#define NFD_LOG_TRACE(expression)
Definition: logger.hpp:160
virtual void beforeExpirePendingInterest(const shared_ptr< pit::Entry > &pitEntry)
trigger before PIT entry expires
Definition: strategy.cpp:55
virtual ~Strategy()
NetworkRegionTable & getNetworkRegionTable()
Definition: forwarder.hpp:171
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
performs a FIB lookup, considering Link object if present
Definition: strategy.cpp:91
bool hasNextHops() const
Definition: fib-entry.hpp:72
InRecordCollection::iterator in_begin()
Definition: pit-entry.hpp:103