34 #include <boost/random/uniform_int_distribution.hpp> 42 const Name Forwarder::LOCALHOST_NAME(
"ndn:/localhost");
48 , m_measurements(m_nameTree)
62 Forwarder::onIncomingInterest(
Face& inFace,
const Interest& interest)
66 " interest=" << interest.
getName());
67 const_cast<Interest&
>(interest).setIncomingFaceId(inFace.
getId());
71 bool isViolatingLocalhost = !inFace.
isLocal() &&
73 if (isViolatingLocalhost) {
75 " interest=" << interest.
getName() <<
" violates /localhost");
81 shared_ptr<pit::Entry> pitEntry = m_pit.
insert(interest).first;
84 int dnw = pitEntry->findNonce(interest.
getNonce(), inFace);
87 if (hasDuplicateNonce) {
89 this->onInterestLoop(inFace, interest, pitEntry);
94 this->cancelUnsatisfyAndStragglerTimer(pitEntry);
98 bool isPending = inRecords.begin() != inRecords.end();
100 if (m_csFromNdnSim ==
nullptr) {
102 bind(&Forwarder::onContentStoreHit,
this, ref(inFace), pitEntry, _1, _2),
103 bind(&Forwarder::onContentStoreMiss,
this, ref(inFace), pitEntry, _1));
106 shared_ptr<Data> match = m_csFromNdnSim->Lookup(interest.shared_from_this());
107 if (match !=
nullptr) {
108 this->onContentStoreHit(inFace, pitEntry, interest, *match);
111 this->onContentStoreMiss(inFace, pitEntry, interest);
116 this->onContentStoreMiss(inFace, pitEntry, interest);
121 Forwarder::onContentStoreMiss(
const Face& inFace,
122 shared_ptr<pit::Entry> pitEntry,
127 shared_ptr<Face> face = const_pointer_cast<
Face>(inFace.shared_from_this());
129 pitEntry->insertOrUpdateInRecord(face, interest);
132 this->setUnsatisfyTimer(pitEntry);
138 this->dispatchToStrategy(pitEntry, bind(&Strategy::afterReceiveInterest, _1,
139 cref(inFace), cref(interest), fibEntry, pitEntry));
143 Forwarder::onContentStoreHit(
const Face& inFace,
144 shared_ptr<pit::Entry> pitEntry,
151 this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeSatisfyInterest, _1,
152 pitEntry, cref(*m_csFace), cref(data)));
161 this->onOutgoingData(data, *const_pointer_cast<Face>(inFace.shared_from_this()));
165 Forwarder::onInterestLoop(
Face& inFace,
const Interest& interest,
166 shared_ptr<pit::Entry> pitEntry)
169 " interest=" << interest.
getName());
187 bool isOutFaceA = a.
getFace().get() == outFace;
188 bool isOutFaceB = b.
getFace().get() == outFace;
190 if (!isOutFaceA && isOutFaceB) {
193 if (isOutFaceA && !isOutFaceB) {
201 Forwarder::onOutgoingInterest(shared_ptr<pit::Entry> pitEntry,
Face& outFace,
205 NFD_LOG_WARN(
"onOutgoingInterest face=invalid interest=" << pitEntry->getName());
209 " interest=" << pitEntry->getName());
212 if (pitEntry->violatesScope(outFace)) {
214 " interest=" << pitEntry->getName() <<
" violates scope");
220 pit::InRecordCollection::const_iterator pickedInRecord = std::max_element(
222 BOOST_ASSERT(pickedInRecord != inRecords.end());
223 shared_ptr<Interest> interest = const_pointer_cast<
Interest>(
224 pickedInRecord->getInterest().shared_from_this());
227 interest = make_shared<Interest>(*interest);
228 static boost::random::uniform_int_distribution<uint32_t> dist;
233 pitEntry->insertOrUpdateOutRecord(outFace.shared_from_this(), *interest);
241 Forwarder::onInterestReject(shared_ptr<pit::Entry> pitEntry)
243 if (pitEntry->hasUnexpiredOutRecords()) {
244 NFD_LOG_ERROR(
"onInterestReject interest=" << pitEntry->getName() <<
245 " cannot reject forwarded Interest");
248 NFD_LOG_DEBUG(
"onInterestReject interest=" << pitEntry->getName());
251 this->cancelUnsatisfyAndStragglerTimer(pitEntry);
254 this->setStragglerTimer(pitEntry,
false);
258 Forwarder::onInterestUnsatisfied(shared_ptr<pit::Entry> pitEntry)
260 NFD_LOG_DEBUG(
"onInterestUnsatisfied interest=" << pitEntry->getName());
264 this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeExpirePendingInterest, _1,
268 this->onInterestFinalize(pitEntry,
false);
272 Forwarder::onInterestFinalize(shared_ptr<pit::Entry> pitEntry,
bool isSatisfied,
273 const time::milliseconds& dataFreshnessPeriod)
275 NFD_LOG_DEBUG(
"onInterestFinalize interest=" << pitEntry->getName() <<
276 (isSatisfied ?
" satisfied" :
" unsatisfied"));
279 this->insertDeadNonceList(*pitEntry, isSatisfied, dataFreshnessPeriod, 0);
282 this->cancelUnsatisfyAndStragglerTimer(pitEntry);
283 m_pit.
erase(pitEntry);
287 Forwarder::onIncomingData(
Face& inFace,
const Data& data)
291 const_cast<Data&
>(data).setIncomingFaceId(inFace.
getId());
295 bool isViolatingLocalhost = !inFace.
isLocal() &&
297 if (isViolatingLocalhost) {
299 " data=" << data.
getName() <<
" violates /localhost");
306 if (pitMatches.begin() == pitMatches.end()) {
308 this->onDataUnsolicited(inFace, data);
318 shared_ptr<Data> dataCopyWithoutPacket = make_shared<Data>(data);
322 if (m_csFromNdnSim ==
nullptr)
323 m_cs.insert(*dataCopyWithoutPacket);
325 m_csFromNdnSim->Add(dataCopyWithoutPacket);
327 std::set<shared_ptr<Face> > pendingDownstreams;
329 for (
const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
330 NFD_LOG_DEBUG(
"onIncomingData matching=" << pitEntry->getName());
333 this->cancelUnsatisfyAndStragglerTimer(pitEntry);
337 for (pit::InRecordCollection::const_iterator it = inRecords.begin();
338 it != inRecords.end(); ++it) {
340 pendingDownstreams.insert(it->getFace());
346 this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeSatisfyInterest, _1,
347 pitEntry, cref(inFace), cref(data)));
353 pitEntry->deleteInRecords();
354 pitEntry->deleteOutRecord(inFace);
361 for (std::set<shared_ptr<Face> >::
iterator it = pendingDownstreams.begin();
362 it != pendingDownstreams.end(); ++it) {
363 shared_ptr<Face> pendingDownstream = *it;
364 if (pendingDownstream.get() == &inFace) {
368 this->onOutgoingData(data, *pendingDownstream);
373 Forwarder::onDataUnsolicited(
Face& inFace,
const Data& data)
376 bool acceptToCache = inFace.
isLocal();
379 if (m_csFromNdnSim ==
nullptr)
380 m_cs.insert(data,
true);
382 m_csFromNdnSim->Add(data.shared_from_this());
387 (acceptToCache ?
" cached" :
" not cached"));
391 Forwarder::onOutgoingData(
const Data& data,
Face& outFace)
400 bool isViolatingLocalhost = !outFace.
isLocal() &&
402 if (isViolatingLocalhost) {
404 " data=" << data.
getName() <<
" violates /localhost");
423 Forwarder::setUnsatisfyTimer(shared_ptr<pit::Entry> pitEntry)
426 pit::InRecordCollection::const_iterator lastExpiring =
427 std::max_element(inRecords.begin(), inRecords.end(),
432 if (lastExpiryFromNow <= time::seconds(0)) {
438 bind(&Forwarder::onInterestUnsatisfied,
this, pitEntry));
442 Forwarder::setStragglerTimer(shared_ptr<pit::Entry> pitEntry,
bool isSatisfied,
443 const time::milliseconds& dataFreshnessPeriod)
445 time::nanoseconds stragglerTime = time::milliseconds(100);
449 bind(&Forwarder::onInterestFinalize,
this, pitEntry, isSatisfied, dataFreshnessPeriod));
453 Forwarder::cancelUnsatisfyAndStragglerTimer(shared_ptr<pit::Entry> pitEntry)
467 Forwarder::insertDeadNonceList(
pit::Entry& pitEntry,
bool isSatisfied,
468 const time::milliseconds& dataFreshnessPeriod,
472 bool needDnl =
false;
474 bool hasFreshnessPeriod = dataFreshnessPeriod >= time::milliseconds::zero();
477 (hasFreshnessPeriod && dataFreshnessPeriod < m_deadNonceList.
getLifetime());
491 std::for_each(outRecords.begin(), outRecords.end(),
496 pit::OutRecordCollection::const_iterator outRecord = pitEntry.
getOutRecord(*upstream);
498 m_deadNonceList.
add(pitEntry.
getName(), outRecord->getLastNonce());
signal::Signal< Forwarder, pit::Entry, Face, Data > beforeSatisfyInterest
trigger before PIT entry is satisfied
std::list< InRecord > InRecordCollection
represents an unordered collection of InRecords
const Name & getName() const
void erase(shared_ptr< pit::Entry > pitEntry)
erases a PIT Entry
represents the Dead Nonce list
#define NFD_LOG_DEBUG(expression)
bool has(const Name &name, uint32_t nonce) const
determines if name+nonce exists
shared_ptr< fib::Entry > findLongestPrefixMatch(const Name &prefix) const
performs a longest prefix match
time::steady_clock::TimePoint getLastRenewed() const
OutRecordCollection::const_iterator getOutRecord(const Face &face) const
get the OutRecord for face
void cancel(const EventId &eventId)
cancel a scheduled event
void installStrategies(Forwarder &forwarder)
static time_point now() noexcept
represents the underlying protocol and address used by a Face
FaceTable & getFaceTable()
contains information about an Interest from an incoming face
uint32_t getLastNonce() const
represents an Interest packet
#define NFD_LOG_ERROR(expression)
pit::DataMatchResult findAllDataMatches(const Data &data) const
performs a Data match
const PacketCounter & getNOutDatas() const
outgoing Data
static bool compare_InRecord_expiry(const pit::InRecord &a, const pit::InRecord &b)
virtual void sendData(const Data &data)=0
send a Data
const PacketCounter & getNOutInterests() const
outgoing Interest
shared_ptr< Strategy > makeDefaultStrategy(Forwarder &forwarder)
void add(const Name &name, uint32_t nonce)
records name+nonce
uint32_t getNonce() const
Get Interest's nonce.
const Name & getName() const
Get name of the Data packet.
Table::const_iterator iterator
#define NFD_LOG_WARN(expression)
static void insertNonceToDnl(DeadNonceList &dnl, const pit::Entry &pitEntry, const pit::OutRecord &outRecord)
int getMustBeFresh() const
const Interest & getInterest() const
Copyright (c) 2011-2015 Regents of the University of California.
const time::nanoseconds & getLifetime() const
signal::Signal< Forwarder, pit::Entry > beforeExpirePendingInterest
trigger before PIT entry expires
Interest & setNonce(uint32_t nonce)
Set Interest's nonce.
const Name & getName() const
EventId schedule(const time::nanoseconds &after, const std::function< void()> &event)
schedule an event
Name abstraction to represent an absolute name.
boost::random::mt19937 & getGlobalRng()
const PacketCounter & getNInDatas() const
incoming Data
std::pair< shared_ptr< pit::Entry >, bool > insert(const Interest &interest)
inserts a PIT entry for Interest
a Face that has no underlying transport and drops every packet
const OutRecordCollection & getOutRecords() const
std::list< OutRecord > OutRecordCollection
represents an unordered collection of OutRecords
static bool compare_pickInterest(const pit::InRecord &a, const pit::InRecord &b, const Face *outFace)
compare two InRecords for picking outgoing Interest
shared_ptr< Face > getFace() const
#define NFD_LOG_INIT(name)
const FaceId FACEID_CONTENT_STORE
identifies a packet comes from the ContentStore, in LocalControlHeader incomingFaceId ...
const FaceId INVALID_FACEID
indicates an invalid FaceId
void addReserved(shared_ptr< Face > face, FaceId faceId)
add a special Face with a reserved FaceId
contains information about an Interest toward an outgoing face
const PacketCounter & getNInInterests() const
incoming Interest
bool isPrefixOf(const Name &name) const
Check if the N components of this name are the same as the first N components of the given name...
time::steady_clock::TimePoint getExpiry() const
gives the time point this record expires
bool isLocal() const
Get whether face is connected to a local app.
const time::milliseconds & getFreshnessPeriod() const
virtual void sendInterest(const Interest &interest)=0
send an Interest
std::vector< shared_ptr< pit::Entry > > DataMatchResult