Correcting bugs with cleaning timeouts in PIT/RIT/ContentStore
Removing RIT concept. Instead, keep track of nonces for each PIT entry.
Many changes in CcnxL3Protocol regarding Interest/Data handling (NACK
are not yet handled at all)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!! Remove when is not actual !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Code is not compiling !!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 63c9049..a479390 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -41,6 +41,10 @@
#include "ccnx-net-device-face.h"
#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+
+using namespace boost::tuples;
+using namespace boost::lambda;
NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
@@ -257,8 +261,11 @@
// Deserialization. Exception may be thrown
packet->RemoveHeader (*header);
NS_ASSERT_MSG (packet->GetSize () == 0, "Payload of Interests should be zero");
-
- OnInterest (face, header, p/*original packet*/);
+
+ if (header->GetNack () > 0)
+ OnNack (face, header, p/*original packet*/);
+ else
+ OnInterest (face, header, p/*original packet*/);
break;
}
case CcnxHeaderHelper::CONTENT_OBJECT:
@@ -284,376 +291,199 @@
}
}
+void
+CcnxL3Protocol::OnNack (const Ptr<CcnxFace> &face,
+ Ptr<CcnxInterestHeader> &header,
+ const Ptr<const Packet> &p)
+{
+ NS_LOG_FUNCTION (face << header << p);
+
+ // Huh... Ignore all this for now
+
+ /*if( header->IsCongested () == false )
+ m_pit->LeakBucket(incomingFace,1);
+
+
+ m_droppedInterestsTrace (header, DROP_CONGESTION,
+ m_node->GetObject<Ccnx> (), incomingFace);
+
+ m_pit->modify(pitEntry, CcnxPitEntry::DeleteOutgoing(incomingFace));*/
+
+ // No matter is it duplicate or not, if it is a NACK message, remove all possible incoming
+ // entries for this interface (NACK means that neighbor gave up trying and there is no
+ // point of sending data in this direction)
+
+ // NS_LOG_INFO("Before (header->IsNack()) && (pitEntry != m_pit->end ())");
+ // if ((header->IsNack()) && (pitEntry != m_pit->end ()))
+ // {
+ // //m_pit->erase (pitEntry);
+ // NS_LOG_INFO("TRUE");
+ // m_pit->modify(pitEntry, CcnxPitEntry::DeleteIncoming(incomingFace));
+ // }
+
+ // m_fib->modify (m_fib->iterator_to (pitEntry->m_fibEntry),
+ // CcnxFibEntry::UpdateStatus(incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+
+ // if (!pitEntry.AreThereMoreFacesToTry ())
+ // {
+ // BOOST_FOREACH (const CcnxPitEntryIncomingFace face, pitEntry.m_incoming)
+ // {
+ // // check all entries if the name of RIT entry matches the name of interest
+ // for (CcnxRitByNonce::type::iterator it = m_rit->begin(); it != m_rit->end(); it++)
+ // {
+ // if (it->m_prefix == iter->GetPrefix() )
+ // {
+ // header->SetNonce(it->m_nonce);
+ // header->SetNack(true);
+ // SendInterest(face.m_face, header, packet->Copy());
+ // }
+ // }
+ // }
+
+ // m_pit->erase(pitEntry);
+
+ // return;
+ // }
+}
+
// Processing Interests
+//
+// !!! Key point.
+// !!! All interests should be answerred!!! Either later with data, immediately with data, or immediately with NACK
void CcnxL3Protocol::OnInterest (const Ptr<CcnxFace> &incomingFace,
Ptr<CcnxInterestHeader> &header,
const Ptr<const Packet> &packet)
{
- NS_LOG_LOGIC ("Receiving interest from " << &incomingFace);
- m_receivedInterestsTrace (header, m_node->GetObject<Ccnx> (), incomingFace);
+ NS_LOG_FUNCTION (incomingFace << header << packet);
+ // m_receivedInterestsTrace (header, m_node->GetObject<Ccnx> (), incomingFace);
-
- if( header->IsNack () )
- {
- NS_LOG_INFO("============");
- NS_LOG_INFO("NACK");
- NS_LOG_INFO("==========");
- /*if( header->IsCongested () == false )
- m_pit->LeakBucket(incomingFace,1);
-
-
- m_droppedInterestsTrace (header, DROP_CONGESTION,
- m_node->GetObject<Ccnx> (), incomingFace);
-
- m_pit->modify(pitEntry, CcnxPitEntry::DeleteOutgoing(incomingFace));*/
- }
+ // Lookup of Pit (and associated Fib) entry for this Interest
+ const CcnxPitEntry &pitEntry;
+ bool isNew;
+ bool isDuplicated;
+ tie (pitEntry, isNew, isDuplicated) = m_pit->Lookup (*header);
-
-
-
- // Lookup of Pit and Fib entries for this Interest
- CcnxFibEntryContainer::type::iterator fibEntry;
- CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header, fibEntry);
-
- // No matter is it duplicate or not, if it is a NACK message, remove all possible incoming
- // entries for this interface (NACK means that neighbor gave up trying and there is no
- // point of sending data in this direction)
- NS_LOG_INFO("Before (header->IsNack()) && (pitEntry != m_pit->end ())");
- if ((header->IsNack()) && (pitEntry != m_pit->end ()))
+ if (isDuplicated)
{
- //m_pit->erase (pitEntry);
- NS_LOG_INFO("TRUE");
- m_pit->modify(pitEntry, CcnxPitEntry::DeleteIncoming(incomingFace));
- }
-
- NS_LOG_INFO("Before WasRecentlySatisfied");
- /*if (m_rit->WasRecentlySatisfied (*header))
- {
- return;
- }*/
- if (m_rit->WasRecentlySatisfied (*header))
- {
- NS_LOG_INFO("------------");
- NS_LOG_INFO("Entering WasRecentlySatisfied");
- NS_LOG_INFO("------------");
- // duplicate interests (same nonce) from applications are just ignored
- if (incomingFace->IsLocal() == true)
- return;
-
- // Update metric status for the incoming interface in the corresponding FIB entry
- /*if (fibEntry != m_fib->end())
- m_fib->modify (m_fib->iterator_to (pitEntry->m_fibEntry),
- CcnxFibEntry::UpdateStatus(incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+ /**
+ * This condition will handle "routing" loops and also recently satisfied interests.
+ * Every time interest is satisfied, PIT entry (with empty incoming and outgoing faces)
+ * is kept for another small chunk of time.
+ */
- //Trace duplicate interest
- m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
-
- bool isMine = false;
- //TypeId tid = TypeId ("ns3::CcnxProducer");
- for(uint32_t i=0; i<m_node->GetNApplications();i++)
- {
- Ptr<Application> app = m_node->GetApplication(i);
- NS_LOG_INFO("ApplicationName = " << app->GetTypeId().GetName());
- if(app->GetTypeId().GetName() == "ns3::CcnxProducer")
- {
- if((DynamicCast<CcnxProducer>(app))->GetPrefix () == header->GetName ())
- {
- isMine = true;
- break;
- }
- }
- }
-
- Ptr<Packet> contentObject = m_contentStore->Lookup (header);
- if ((isMine == true) || (contentObject != NULL))
- {
- //never respond with NACK to NACK
- if(header->IsNack () )
- return;
-
- // always return a duplicate packet
- header->SetNack(true);
- //Trace duplicate interest
- m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
+ // //Trace duplicate interest
+ // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
- SendInterest(incomingFace, header, packet->Copy());
-
- return;
- }
-
-
- // check PIT. or there is no outgoing entry for this interface,
- // silently drop the duplicate packet
-
- // If no entry found, silently drop
- if( pitEntry == m_pit->end() )
- return;
-
- // If PIT entry timed out, silently drop
- if( pitEntry->m_timerExpired == true )
- return;
-
- // loop?
-
- // Check if there is no outgoing entry for the interface or different nonce
- // (i.e., got a duplicate packet, but we haven't sent interest to this
- // interface)
- //
- // This case means that there is a loop in the network.
- // So, prune this link, but do not remove PIT entry
-
- // Alex, check this condition!!
- if(pitEntry->m_outgoing.size () == 0)
- {
- //never respond with NACK to NACK
- if(header->IsNack () )
- return;
-
- // always return a duplicate packet
- header->SetNack(true);
- //Trace duplicate interest
- m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
+ header->SetNack (CcnxInterestHeader::NACK_LOOP);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (*header);
- SendInterest(incomingFace, header, packet->Copy());
- return;
- }
+ SendInterest (m_incomingFace, header, packet);
-
- // At this point:
- // - there is a non-expired PIT entry,
- // - there is an outgoing interest to the interface, and
- // - a nonce in outgoing entry is equal to a nonce in the received duplicate packet
-
- // Should perform:
- // Cleaning outgoing entry
- // If there are no outgoing interests and available interfaces left (pe->availableInterfaces),
- // prune all incoming interests, otherwise allow forwarding of the interest
- if( header->IsNack () )
- {
- if( header->IsCongested () == false )
- m_pit->LeakBucket(incomingFace,1);
-
- m_pit->modify(pitEntry, CcnxPitEntry::DeleteOutgoing(incomingFace));
- }
- else
- {
- //poit->waitingInVain = true;
- }
-
-
- // prune all incoming interests
- if((pitEntry->m_outgoing.size() ==0) && (pitEntry->m_fibEntry.m_faces.size() == 0))
- {
- BOOST_FOREACH (const CcnxPitEntryIncomingFace face, pitEntry->m_incoming)
- {
- if(face.m_face->IsLocal() == false)
- {
- // check all entries if the name of RIT entry matches the name of interest
- for (CcnxRitByNonce::type::iterator it = m_rit->begin(); it != m_rit->end(); it++)
- {
- if (it->m_prefix == pitEntry->GetPrefix() )
- {
-
- header->SetNonce(it->m_nonce);
- header->SetNack(true);
- SendInterest(face.m_face, header, packet->Copy());
- break;
- }
- }
- }
- }
-
- // Finally, remote the PIT entry
- m_pit->erase (pitEntry);
-
- return; // stop processing
- }
-
- if(pitEntry->m_fibEntry.m_faces.size() == 0)
- return;*/
- return;
- }
-
-
-
- // Otherwise,
- // propagate the interest
- //
- // method `propagateInterest' can/should try different interface
- // from `availableInterfaces' list
-
- NS_LOG_INFO("Before SetRecentlySatisfied");
- m_rit->SetRecentlySatisfied (*header);
-
- NS_LOG_INFO("Cache Lookup for " << header->GetName());
- Ptr<Packet> contentObject = m_contentStore->Lookup (header);
- if (contentObject != NULL)
- {
- NS_LOG_INFO("Found in cache");
-
- TransmittedDataTrace (contentObject, CACHED,
- m_node->GetObject<Ccnx> (), incomingFace);
- incomingFace->Send (contentObject);
+ // //Trace duplicate interest
+ // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
return;
}
+
+ Ptr<Packet> contentObject;
+ Ptr<CcnxContentObjectHeader> contentObjectHeader;
+ tie (contentObject, contentObjectHeader) = m_contentStore->Lookup (header);
+ if (contentObject != 0)
+ {
+ NS_ASSERT_MSG (pitEntry.m_incoming.size () == 0,
+ "Something strange. Data is cached, but size of incoming interests is not zero...");
+ NS_ASSERT (contentObjectHeader != 0);
+
+ NS_LOG_LOGIC("Found in cache");
+
+ // TransmittedDataTrace (contentObject, CACHED,
+ // m_node->GetObject<Ccnx> (), incomingFace);
+ SendContentObject (incomingFace, contentObjectHeader, contentObject);
+
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ boost::bind (&CcnxPitEntry::SetExpireTime, _1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ return;
+ }
+
+ // \todo Detect retransmissions. Not yet sure how...
// Data is not in cache
- NS_LOG_INFO("Before inFace and OutFace");
- CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry->m_incoming.find (incomingFace);
- CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry->m_outgoing.find (incomingFace);
-
- NS_LOG_INFO("Before (pitEntry != m_pit->end()) && (pitEntry->m_timerExpired == false)");
- if ((pitEntry != m_pit->end()) && (pitEntry->m_timerExpired == false))
+ CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
+
+ if (inFace != pitEntry.m_incoming.end ())
{
- NS_LOG_INFO("Entering (pitEntry != m_pit->end()) && (pitEntry->m_timerExpired == false)");
-
- if(inFace->m_face == 0)
- NS_LOG_INFO("in face is null");
- if(outFace->m_face == 0)
- NS_LOG_INFO("outface is null");
- if(outFace == pitEntry->m_outgoing.end())
- NS_LOG_INFO("OUTFACE = END");
-
- // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
- // Give up this interface, but keep a small hope when the returned packet doesn't have PRUNE status
- if(outFace != pitEntry->m_outgoing.end()) // this is correct
- {
- NS_LOG_INFO("Entering outFace != pitEntry->m_outgoing.end()");
- if( header->IsCongested() == true )
- {
- NS_LOG_INFO("Entering header->IsCongested() == true");
- m_pit->LeakBucket(incomingFace, 1);
- m_pit->modify (pitEntry, CcnxPitEntry::DeleteOutgoing(outFace->m_face));
- }
- //else
- // poit->waitingInVain = true;
-
- // Update metric status for the incoming interface in the corresponding FIB entry
- if(fibEntry != m_fib->end())
- m_fib->modify(m_fib->iterator_to (pitEntry->m_fibEntry),
- CcnxFibEntry::UpdateStatus(incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
- }
- }
-
- NS_LOG_INFO("Before (pitEntry->m_outgoing.size() == 0) && (pitEntry->m_fibEntry.m_faces.size() == 0)");
- if((pitEntry->m_outgoing.size() == 0) && (pitEntry->m_fibEntry.m_faces.size() == 0))
- // prune all incoming interests
- {
-
- for(CcnxPitEntryContainer::type::iterator iter = m_pit->begin();
- iter != m_pit->end();
- iter++)
- {
- /*for(CcnxPitEntryIncomingFaceContainer::type::iterator face = iter->m_incoming.begin();
- face != iter->m_incoming.end();
- face++)*/
- BOOST_FOREACH (const CcnxPitEntryIncomingFace face, iter->m_incoming)
- {
- if(face.m_face->IsLocal() == true)
- {
- //returnInterestToApp( pkt, -piit->interfaceIndex );
- //continue;
- }
-
- // check all entries if the name of RIT entry matches the name of interest
- for (CcnxRitByNonce::type::iterator it = m_rit->begin(); it != m_rit->end(); it++)
- {
- if (it->m_prefix == iter->GetPrefix() )
- {
- header->SetNonce(it->m_nonce);
- header->SetNack(true);
- SendInterest(face.m_face, header, packet->Copy());
- }
- }
- }
-
- }
-
- m_pit->erase(pitEntry);
-
- return; // there is nothing else to do
- }
-
- // Suppress this interest only if we're still expecting data from some other interface
- if( pitEntry->m_outgoing.size() > 0 )
- {
- return; //ok. Now we can suppress this interest
- }
-
-
- // Prune and delete PIT entry if there are no available interfaces to propagate interest
- if( pitEntry->m_fibEntry.m_faces.size() == 0)
- {
- //if no match is found in the FIB, drop packet
- //printf( "Node %d: cannot process Interest packet %s (no interfaces left)\n", _node->nodeId, pkt->contentName );
-
- if(incomingFace->IsLocal() == false)
- {
- header->SetNack(true);
- m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
- SendInterest(incomingFace, header, packet->Copy());
- }
-
- m_pit->erase(pitEntry);
-
- }
-
-
-
- // otherwise, try one of the available interfaces
-
- // suppress interest if
- /*if (pitEntry->m_incoming.size () != 0 && // not a new PIT entry and
- inFace != pitEntry->m_incoming.end ()) // existing entry, but interest received via different face
- {
- m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST,
- m_node->GetObject<Ccnx> (), incomingFace);
- return;
- }*/
-
-
- //just in case of bug
- header->SetNack(false);
- header->SetCongested(false);
-
- NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
-
- m_pit->modify (pitEntry, CcnxPitEntry::AddIncoming(incomingFace));
-
- bool propagated = m_forwardingStrategy->
- PropagateInterest (pitEntry, fibEntry,incomingFace, header, packet,
- MakeCallback (&CcnxL3Protocol::SendInterest, this)
- );
-
- // If interest wasn't propagated further (probably, a limit is reached),
- // prune and delete PIT entry if there are no outstanding interests.
- // Stop processing otherwise.
- if( (!propagated) && (pitEntry->m_outgoing.size() == 0)) // this line works
- {
- BOOST_FOREACH (const CcnxPitEntryIncomingFace face, pitEntry->m_incoming)
- {
- header->SetNack(true);
- header->SetCongested(true);
- NS_LOG_INFO("Sending CONGESTION packet");
- SendInterest (face.m_face, header, packet->Copy());
-
- m_droppedInterestsTrace (header, DROP_CONGESTION,
- m_node->GetObject<Ccnx> (), incomingFace);
- }
+ // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
- m_pit->erase (pitEntry);
- }
- /*}
+ // this is almost definitely a retransmission. But should we trust the user on that?
+ }
else
{
- m_droppedInterestsTrace (header, NDN_PIT_TIMER_EXPIRED,
- m_node->GetObject<Ccnx> (), incomingFace);
- return;
- }*/
+ m_pit->modify (m_pit->iterator_to (m_pitpitEntry),
+ iface = _1->m_incoming.insert (CcnxPitEntryIncoming (incomingFace, Simulator::Now ())));
+ }
+
+ if (outFace != pitEntry.m_outgoing.end ())
+ {
+ // got a non-duplicate interest from the face we have sent interest to
+ // Probably, there is no point in waiting data from that face... Not sure yet
+
+ // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
+ // Mark interface YELLOW, but keep a small hope that data will come eventually.
+
+ // ?? not sure if we need to do that ?? ...
+
+ m_fib->modify(m_fib->iterator_to (pitEntry.m_fibEntry),
+ boost::bind (&CcnxFibEntry::UpdateStatus,
+ _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+
+ // suppress?
+ }
+ else if (pitEntry->m_outgoing.size() > 0) // Suppress this interest if we're still expecting data from some other face
+
+ {
+ // We are already expecting data later in future. Suppress the interest
+ // m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
+ return;
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ // Propagate
+ /////////////////////////////////////////////////////////////////////
+
+ NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
+
+ bool propagated = m_forwardingStrategy->
+ PropagateInterest (pitEntry, fibEntry,incomingFace, header, packet,
+ MakeCallback (&CcnxL3Protocol::SendInterest, this)
+ );
+
+ // ForwardingStrategy will try its best to forward packet to at least one interface.
+ // If no interests was propagated, then there is not other option for forwarding or
+ // ForwardingStrategy failed to find it.
+ if (!propagated)
+ {
+ Ptr<Packet> packet = Create<Packet> ();
+ header->SetNack (CcnxInterestHeader::NACK_CONGESTION);
+ packet.AddHeader (*header);
+
+ while (pitEntry.m_incoming.size () > 0)
+ {
+ SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
+
+ pitEntry.m_incoming.pop_front ();
+
+ // m_droppedInterestsTrace (header, DROP_CONGESTION,
+ // m_node->GetObject<Ccnx> (), incomingFace);
+ }
+
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ boost::bind (&CcnxPitEntry::SetExpireTime, _1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ }
}
// Processing ContentObjects
@@ -663,8 +493,8 @@
const Ptr<const Packet> &packet)
{
- NS_LOG_LOGIC ("Receiving contentObject from " << &incomingFace);
- m_receivedDataTrace (header, payload, m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
+ NS_LOG_FUNCTION (incomingFace << header, payload, packet);
+ // m_receivedDataTrace (header, payload, m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
// 1. Lookup PIT entry
try
@@ -675,46 +505,48 @@
// Update metric status for the incoming interface in the corresponding FIB entry
m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
- CcnxFibEntry::UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
+ boost::bind (CcnxFibEntry::UpdateStatus, _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
// Add or update entry in the content store
- NS_LOG_INFO("Cached " << header->GetName());
m_contentStore->Add (header, payload);
- CcnxPitEntryOutgoingFaceContainer::type::iterator
- out = pitEntry.m_outgoing.find (incomingFace);
+ CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry.m_outgoing.find (incomingFace);
// If we have sent interest for this data via this face, then update stats.
if (out != pitEntry.m_outgoing.end ())
{
- m_pit->modify (m_pit->iterator_to (pitEntry),
- CcnxPitEntry::EstimateRttAndRemoveFace(out, m_fib));
- // face will be removed in the above call
+ m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
+ boost::bind (&CcnxFibEntry::UpdateRtt,
+ _1,
+ Simulator::Now () - out->m_sendTime));
}
else
{
- NS_LOG_WARN ("Node "<< m_node->GetId() <<
- ". PIT entry for "<< header->GetName ()<<" is valid, "
- "but outgoing entry for interface "<< incomingFace <<" doesn't exist\n");
+ // Unsolicited data, but we're interested in it... should we get it?
+ // Potential hole for attacks
+
+ NS_LOG_ERROR ("Node "<< m_node->GetId() <<
+ ". PIT entry for "<< header->GetName ()<<" is valid, "
+ "but outgoing entry for interface "<< incomingFace <<" doesn't exist\n");
+
+ NS_ASSERT (false); // temporary put false here
}
//satisfy all pending incoming Interests
- BOOST_FOREACH (const CcnxPitEntryIncomingFace &interest, pitEntry.m_incoming)
+ while (pitEntry.m_incoming.size () > 0)
{
- if (interest.m_face == incomingFace) continue;
+ if (pitEntry.m_incoming.front ().m_face != incomingFace)
+ SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
- // may not work either because of 'const' thing
- interest.m_face->Send (packet->Copy ()); // unfortunately, we have to copy packet...
- m_transmittedDataTrace (header, payload, FORWARDED, m_node->GetObject<Ccnx> (), interest.m_face);
+ pitEntry.m_incoming.pop_front ();
+
+ // m_transmittedDataTrace (header, payload, FORWARDED, m_node->GetObject<Ccnx> (), interest.m_face);
}
- m_pit->modify (m_pit->iterator_to (pitEntry), CcnxPitEntry::ClearIncoming()); // satisfy all incoming interests
-
- if( pitEntry.m_outgoing.size()==0 ) // remove PIT when all outgoing interests are "satisfied"
- {
- m_pit->erase (m_pit->iterator_to (pitEntry));
- }
-
+ // Set pruning timout on PIT entry (instead of deleting the record)
+ m_pit->modify (m_pit->iterator_to (pitEntry),
+ boost::bind (&CcnxPitEntry::SetExpireTime, _1,
+ Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
}
catch (CcnxPitEntryNotFound)
{
@@ -722,7 +554,7 @@
// (unsolicited data packets should not "poison" content store)
//drop dulicated or not requested data packet
- m_droppedDataTrace (header, payload, NDN_UNSOLICITED_DATA, m_node->GetObject<Ccnx> (), incomingFace);
+ // m_droppedDataTrace (header, payload, NDN_UNSOLICITED_DATA, m_node->GetObject<Ccnx> (), incomingFace);
return; // do not process unsoliced data packets
}
}
@@ -738,13 +570,13 @@
if (face->IsUp ())
{
NS_LOG_LOGIC ("Sending via face " << &face); //
- m_transmittedInterestsTrace (header, m_node->GetObject<Ccnx> (), face);
+ // m_transmittedInterestsTrace (header, m_node->GetObject<Ccnx> (), face);
face->Send (packet);
}
else
{
NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
- m_droppedInterestsTrace (header, INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
+ // m_droppedInterestsTrace (header, INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
}
}
@@ -756,8 +588,6 @@
NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face);
NS_ASSERT_MSG (face != 0, "Face should never be NULL");
- NS_ASSERT_MSG (false, "Should not be called for now");
-
if (face->IsUp ())
{
NS_LOG_LOGIC ("Sending via face " << &face); //
@@ -777,11 +607,12 @@
return m_pit;
}
-void
-CcnxL3Protocol::ScheduleLeakage()
-{
- m_pit->LeakBuckets();
- Time interval = MilliSeconds (NDN_INTEREST_RESET_PERIOD);
- Simulator::Schedule (interval, &CcnxL3Protocol::ScheduleLeakage, this);
-}
+// void
+// CcnxL3Protocol::ScheduleLeakage()
+// {
+// m_pit->LeakBuckets();
+// Time interval = MilliSeconds (NDN_INTEREST_RESET_PERIOD);
+
+// Simulator::Schedule (interval, &CcnxL3Protocol::ScheduleLeakage, this);
+// }
} //namespace ns3