32 #include <ndn-cxx/lp/tags.hpp>    50   , m_measurements(m_nameTree)
    51   , m_strategyChoice(*this)
    57     face.afterReceiveInterest.connect(
    58       [
this, &face] (
const Interest& interest) {
    61     face.afterReceiveData.connect(
    62       [
this, &face] (
const Data& data) {
    65     face.afterReceiveNack.connect(
    66       [
this, &face] (
const lp::Nack& nack) {
    81 Forwarder::onIncomingInterest(
Face& inFace, 
const Interest& interest)
    85                 " interest=" << interest.
getName());
    86   interest.
setTag(make_shared<lp::IncomingFaceIdTag>(inFace.getId()));
    92   if (isViolatingLocalhost) {
    94                   " interest=" << interest.
getName() << 
" violates /localhost");
   100   bool hasDuplicateNonceInDnl = m_deadNonceList.
has(interest.
getName(), interest.
getNonce());
   101   if (hasDuplicateNonceInDnl) {
   103     this->onInterestLoop(inFace, interest);
   110     NFD_LOG_DEBUG(
"onIncomingInterest face=" << inFace.getId() <<
   111                   " interest=" << interest.
getName() << 
" reaching-producer-region");
   112     const_cast<Interest&
>(interest).setForwardingHint({});
   116   shared_ptr<pit::Entry> pitEntry = m_pit.insert(interest).first;
   125   if (hasDuplicateNonceInPit) {
   127     this->onInterestLoop(inFace, interest);
   132   this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
   135   bool isPending = inRecords.begin() != inRecords.end();
   137     if (m_csFromNdnSim == 
nullptr) {
   139                 bind(&Forwarder::onContentStoreHit, 
this, ref(inFace), pitEntry, _1, _2),
   140                 bind(&Forwarder::onContentStoreMiss, 
this, ref(inFace), pitEntry, _1));
   143       shared_ptr<Data> match = m_csFromNdnSim->Lookup(interest.shared_from_this());
   144       if (match != 
nullptr) {
   145         this->onContentStoreHit(inFace, pitEntry, interest, *match);
   148         this->onContentStoreMiss(inFace, pitEntry, interest);
   153     this->onContentStoreMiss(inFace, pitEntry, interest);
   158 Forwarder::onInterestLoop(
Face& inFace, 
const Interest& interest)
   163                   " interest=" << interest.
getName() <<
   169                 " interest=" << interest.
getName() <<
   170                 " send-Nack-duplicate");
   175   nack.setReason(lp::NackReason::DUPLICATE);
   176   inFace.sendNack(nack);
   180 Forwarder::onContentStoreMiss(
const Face& inFace, 
const shared_ptr<pit::Entry>& pitEntry,
   187   pitEntry->insertOrUpdateInRecord(const_cast<Face&>(inFace), interest);
   190   this->setUnsatisfyTimer(pitEntry);
   194   if (nextHopTag != 
nullptr) {
   196     Face* nextHopFace = m_faceTable.
get(*nextHopTag);
   197     if (nextHopFace != 
nullptr) {
   198       NFD_LOG_DEBUG(
"onContentStoreMiss interest=" << interest.
getName() << 
" nexthop-faceid=" << nextHopFace->getId());
   201       this->onOutgoingInterest(pitEntry, *nextHopFace, interest);
   207   this->dispatchToStrategy(*pitEntry,
   212 Forwarder::onContentStoreHit(
const Face& inFace, 
const shared_ptr<pit::Entry>& pitEntry,
   219   this->dispatchToStrategy(*pitEntry,
   229   this->onOutgoingData(data, *const_pointer_cast<Face>(inFace.shared_from_this()));
   233 Forwarder::onOutgoingInterest(
const shared_ptr<pit::Entry>& pitEntry, 
Face& outFace, 
const Interest& interest)
   235   NFD_LOG_DEBUG(
"onOutgoingInterest face=" << outFace.getId() <<
   236                 " interest=" << pitEntry->getName());
   239   pitEntry->insertOrUpdateOutRecord(outFace, interest);
   242   outFace.sendInterest(interest);
   247 Forwarder::onInterestReject(
const shared_ptr<pit::Entry>& pitEntry)
   250     NFD_LOG_ERROR(
"onInterestReject interest=" << pitEntry->getName() <<
   251                   " cannot reject forwarded Interest");
   254   NFD_LOG_DEBUG(
"onInterestReject interest=" << pitEntry->getName());
   257   this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
   260   this->setStragglerTimer(pitEntry, 
false);
   264 Forwarder::onInterestUnsatisfied(
const shared_ptr<pit::Entry>& pitEntry)
   266   NFD_LOG_DEBUG(
"onInterestUnsatisfied interest=" << pitEntry->getName());
   270   this->dispatchToStrategy(*pitEntry,
   274   this->onInterestFinalize(pitEntry, 
false);
   278 Forwarder::onInterestFinalize(
const shared_ptr<pit::Entry>& pitEntry, 
bool isSatisfied,
   281   NFD_LOG_DEBUG(
"onInterestFinalize interest=" << pitEntry->getName() <<
   282                 (isSatisfied ? 
" satisfied" : 
" unsatisfied"));
   285   this->insertDeadNonceList(*pitEntry, isSatisfied, dataFreshnessPeriod, 0);
   288   this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
   289   m_pit.erase(pitEntry.get());
   293 Forwarder::onIncomingData(
Face& inFace, 
const Data& data)
   297   data.
setTag(make_shared<lp::IncomingFaceIdTag>(inFace.getId()));
   303   if (isViolatingLocalhost) {
   305                   " data=" << data.
getName() << 
" violates /localhost");
   312   if (pitMatches.begin() == pitMatches.end()) {
   314     this->onDataUnsolicited(inFace, data);
   318   shared_ptr<Data> dataCopyWithoutTag = make_shared<Data>(data);
   322   if (m_csFromNdnSim == 
nullptr)
   323     m_cs.insert(*dataCopyWithoutTag);
   325     m_csFromNdnSim->Add(dataCopyWithoutTag);
   327   std::set<Face*> pendingDownstreams;
   330   for (
const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
   331     NFD_LOG_DEBUG(
"onIncomingData matching=" << pitEntry->getName());
   334     this->cancelUnsatisfyAndStragglerTimer(*pitEntry);
   337     for (
const pit::InRecord& inRecord : pitEntry->getInRecords()) {
   338       if (inRecord.getExpiry() > now) {
   339         pendingDownstreams.insert(&inRecord.getFace());
   345     this->dispatchToStrategy(*pitEntry,
   352     pitEntry->clearInRecords();
   353     pitEntry->deleteOutRecord(inFace);
   360   for (
Face* pendingDownstream : pendingDownstreams) {
   361     if (pendingDownstream->getId() == inFace.getId() &&
   366     this->onOutgoingData(data, *pendingDownstream);
   371 Forwarder::onDataUnsolicited(
Face& inFace, 
const Data& data)
   377     if (m_csFromNdnSim == 
nullptr)
   378       m_cs.insert(data, 
true);
   380       m_csFromNdnSim->Add(data.shared_from_this());
   385                 " decision=" << decision);
   389 Forwarder::onOutgoingData(
const Data& data, 
Face& outFace)
   400   if (isViolatingLocalhost) {
   402                   " data=" << data.
getName() << 
" violates /localhost");
   410   outFace.sendData(data);
   415 Forwarder::onIncomingNack(
Face& inFace, 
const lp::Nack& nack)
   418   nack.
setTag(make_shared<lp::IncomingFaceIdTag>(inFace.getId()));
   425                   "~" << nack.
getReason() << 
" face-is-multi-access");
   430   shared_ptr<pit::Entry> pitEntry = m_pit.find(nack.
getInterest());
   432   if (pitEntry == 
nullptr) {
   435                   "~" << nack.
getReason() << 
" no-PIT-entry");
   442   if (outRecord == pitEntry->out_end()) {
   445                   "~" << nack.
getReason() << 
" no-out-record");
   453                   "~" << nack.
getReason() << 
" wrong-Nonce " <<
   463   outRecord->setIncomingNack(nack);
   466   this->dispatchToStrategy(*pitEntry,
   471 Forwarder::onOutgoingNack(
const shared_ptr<pit::Entry>& pitEntry, 
const Face& outFace,
   476                   " nack=" << pitEntry->getInterest().getName() <<
   477                   "~" << nack.
getReason() << 
" no-in-record");
   485   if (inRecord == pitEntry->in_end()) {
   487                   " nack=" << pitEntry->getInterest().getName() <<
   488                   "~" << nack.
getReason() << 
" no-in-record");
   495                   " nack=" << pitEntry->getInterest().getName() <<
   496                   "~" << nack.
getReason() << 
" face-is-multi-access");
   501                 " nack=" << pitEntry->getInterest().getName() <<
   505   lp::Nack nackPkt(inRecord->getInterest());
   509   pitEntry->deleteInRecord(outFace);
   512   const_cast<Face&
>(outFace).sendNack(nackPkt);
   523 Forwarder::setUnsatisfyTimer(
const shared_ptr<pit::Entry>& pitEntry)
   530   if (lastExpiryFromNow <= time::seconds::zero()) {
   536     bind(&Forwarder::onInterestUnsatisfied, 
this, pitEntry));
   540 Forwarder::setStragglerTimer(
const shared_ptr<pit::Entry>& pitEntry, 
bool isSatisfied,
   547     bind(&Forwarder::onInterestFinalize, 
this, pitEntry, isSatisfied, dataFreshnessPeriod));
   551 Forwarder::cancelUnsatisfyAndStragglerTimer(
pit::Entry& pitEntry)
   565 Forwarder::insertDeadNonceList(
pit::Entry& pitEntry, 
bool isSatisfied,
   571     BOOST_ASSERT(dataFreshnessPeriod);
   572     BOOST_ASSERT(*dataFreshnessPeriod >= time::milliseconds::zero());
   574               *dataFreshnessPeriod < m_deadNonceList.
getLifetime();
   582   if (upstream == 
nullptr) {
   585     std::for_each(outRecords.begin(), outRecords.end(),
   592       m_deadNonceList.
add(pitEntry.
getName(), outRecord->getLastNonce());
 signal::Signal< FaceTable, Face & > afterAdd
fires after a face is added 
 
signal::Signal< Forwarder, pit::Entry, Face, Data > beforeSatisfyInterest
trigger before PIT entry is satisfied 
 
const Name & getName() const 
 
void cleanupOnFaceRemoval(NameTree &nt, Fib &fib, Pit &pit, const Face &face)
cleanup tables when a face is destroyed 
 
shared_ptr< Face > makeNullFace(const FaceUri &uri)
 
represents the Dead Nonce list 
 
bool has(const Name &name, uint32_t nonce) const 
determines if name+nonce exists 
 
OutRecordCollection::iterator getOutRecord(const Face &face)
get the out-record for face 
 
const Name LOCALHOST("ndn:/localhost")
ndn:/localhost 
 
const time::milliseconds & getFreshnessPeriod() const 
 
void cancel(const EventId &eventId)
cancel a scheduled event 
 
static time_point now() noexcept
 
scheduler::EventId m_stragglerTimer
straggler timer 
 
contains information about an Interest from an incoming face 
 
Nack & setHeader(const NackHeader &header)
 
uint32_t getLastNonce() const 
 
boost::posix_time::time_duration milliseconds(long duration)
 
virtual void beforeExpirePendingInterest(const shared_ptr< pit::Entry > &pitEntry)
trigger before PIT entry expires 
 
const Interest & getInterest() const 
 
void startProcessInterest(Face &face, const Interest &interest)
start incoming Interest processing 
 
signal::Signal< FaceTable, Face & > beforeRemove
fires before a face is removed 
 
PacketCounter nInInterests
 
represents an Interest packet 
 
#define NFD_LOG_DEBUG(expression)
 
static bool compare_InRecord_expiry(const pit::InRecord &a, const pit::InRecord &b)
 
void setTag(shared_ptr< T > tag) const 
set a tag item 
 
void add(const Name &name, uint32_t nonce)
records name+nonce 
 
std::list< InRecord > InRecordCollection
an unordered collection of in-records 
 
uint32_t getNonce() const 
Get nonce. 
 
represents a Network Nack 
 
DropAllUnsolicitedDataPolicy DefaultUnsolicitedDataPolicy
the default UnsolicitedDataPolicy 
 
provides a tag type for simple types 
 
Table::const_iterator iterator
 
NackReason getReason() const 
 
virtual void afterReceiveNack(const Face &inFace, const lp::Nack &nack, const shared_ptr< pit::Entry > &pitEntry)
trigger after Nack is received 
 
FaceTable & getFaceTable()
 
#define NFD_LOG_ERROR(expression)
 
static void insertNonceToDnl(DeadNonceList &dnl, const pit::Entry &pitEntry, const pit::OutRecord &outRecord)
 
int getMustBeFresh() const 
 
Copyright (c) 2011-2015 Regents of the University of California. 
 
const Interest & getInterest() const 
 
const time::nanoseconds & getLifetime() const 
 
signal::Signal< Forwarder, pit::Entry > beforeExpirePendingInterest
trigger before PIT entry expires 
 
void startProcessData(Face &face, const Data &data)
start incoming Data processing 
 
virtual void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace, const Data &data)
trigger before PIT entry is satisfied 
 
Represents an absolute name. 
 
bool isPrefixOf(const Name &other) const 
Check if this name is a prefix of another name. 
 
PacketCounter nOutInterests
 
represents the underlying protocol and address used by a Face 
 
bool hasPendingOutRecords(const pit::Entry &pitEntry)
determine whether pitEntry has any pending out-records 
 
no duplicate Nonce is found 
 
represents a forwarding strategy 
 
int findDuplicateNonce(const pit::Entry &pitEntry, uint32_t nonce, const Face &face)
determine whether pitEntry has duplicate Nonce nonce 
 
std::list< OutRecord > OutRecordCollection
an unordered collection of out-records 
 
#define NFD_LOG_WARN(expression)
 
const DelegationList & getForwardingHint() const 
 
const Name & getName() const 
Get name. 
 
static Name getDefaultStrategyName()
 
static const Name & getStrategyName()
 
This file contains common algorithms used by forwarding strategies. 
 
bool empty() const noexcept
 
UnsolicitedDataDecision
a decision made by UnsolicitedDataPolicy 
 
EventId schedule(time::nanoseconds after, const EventCallback &event)
schedule an event 
 
void addReserved(shared_ptr< Face > face, FaceId faceId)
add a special face with a reserved FaceId 
 
const Name & getName() const 
 
contains information about an Interest toward an outgoing face 
 
the Data should be cached in the ContentStore 
 
shared_ptr< T > getTag() const 
get a tag item 
 
virtual void afterReceiveInterest(const Face &inFace, const Interest &interest, const shared_ptr< pit::Entry > &pitEntry)=0
trigger after Interest is received 
 
#define NFD_LOG_INIT(name)
 
Represents a Data packet. 
 
const FaceId FACEID_CONTENT_STORE
identifies a packet comes from the ContentStore 
 
std::vector< shared_ptr< Entry > > DataMatchResult
 
time::steady_clock::TimePoint getExpiry() const 
gives the time point this record expires 
 
Face * get(FaceId id) const 
get face by FaceId 
 
const FaceId INVALID_FACEID
indicates an invalid FaceId 
 
bool isInProducerRegion(const DelegationList &forwardingHint) const 
determines whether an Interest has reached a producer region 
 
void startProcessNack(Face &face, const lp::Nack &nack)
start incoming Nack processing 
 
const OutRecordCollection & getOutRecords() const 
 
scheduler::EventId m_unsatisfyTimer
unsatisfy timer