First step of refactoring code (ccnx prefix => ndn prefix)
diff --git a/model/ndn-l3-protocol.cc b/model/ndn-l3-protocol.cc
new file mode 100644
index 0000000..62c6241
--- /dev/null
+++ b/model/ndn-l3-protocol.cc
@@ -0,0 +1,676 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Ilya Moiseenko <iliamo@cs.ucla.edu>
+ */
+
+#include "ndn-l3-protocol.h"
+
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/log.h"
+#include "ns3/callback.h"
+#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/object-vector.h"
+#include "ns3/pointer.h"
+#include "ns3/simulator.h"
+#include "ns3/random-variable.h"
+
+#include "ns3/ndn-header-helper.h"
+#include "ns3/ndn-pit.h"
+#include "ns3/ndn-interest-header.h"
+#include "ns3/ndn-content-object-header.h"
+
+#include "ns3/ndn-face.h"
+#include "ns3/ndn-forwarding-strategy.h"
+
+// #include "fib/ndn-fib-impl.h"
+
+#include "ndn-net-device-face.h"
+
+#include <boost/foreach.hpp>
+
+NS_LOG_COMPONENT_DEFINE ("NdnL3Protocol");
+
+namespace ns3 {
+
+const uint16_t NdnL3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
+
+
+NS_OBJECT_ENSURE_REGISTERED (NdnL3Protocol);
+
+TypeId
+NdnL3Protocol::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::NdnL3Protocol")
+ .SetParent<Ndn> ()
+ .SetGroupName ("ndn")
+ .AddConstructor<NdnL3Protocol> ()
+ .AddAttribute ("FaceList", "List of faces associated with ndn stack",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&NdnL3Protocol::m_faces),
+ MakeObjectVectorChecker<NdnFace> ())
+ ;
+ return tid;
+}
+
+NdnL3Protocol::NdnL3Protocol()
+: m_faceCounter (0)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+NdnL3Protocol::~NdnL3Protocol ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+/*
+ * This method is called by AddAgregate and completes the aggregation
+ * by setting the node in the ndn stack
+ */
+void
+NdnL3Protocol::NotifyNewAggregate ()
+{
+ // not really efficient, but this will work only once
+ if (m_node == 0)
+ {
+ m_node = GetObject<Node> ();
+ if (m_node != 0)
+ {
+ // NS_ASSERT_MSG (m_pit != 0 && m_fib != 0 && m_contentStore != 0 && m_forwardingStrategy != 0,
+ // "PIT, FIB, and ContentStore should be aggregated before NdnL3Protocol");
+ NS_ASSERT_MSG (m_forwardingStrategy != 0,
+ "Forwarding strategy should be aggregated before NdnL3Protocol");
+ }
+ }
+ // if (m_pit == 0)
+ // {
+ // m_pit = GetObject<NdnPit> ();
+ // }
+ // if (m_fib == 0)
+ // {
+ // m_fib = GetObject<NdnFib> ();
+ // }
+ if (m_forwardingStrategy == 0)
+ {
+ m_forwardingStrategy = GetObject<NdnForwardingStrategy> ();
+ }
+ // if (m_contentStore == 0)
+ // {
+ // m_contentStore = GetObject<NdnContentStore> ();
+ // }
+
+ Ndn::NotifyNewAggregate ();
+}
+
+void
+NdnL3Protocol::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ for (NdnFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
+ {
+ *i = 0;
+ }
+ m_faces.clear ();
+ m_node = 0;
+
+ // Force delete on objects
+ m_forwardingStrategy = 0; // there is a reference to PIT stored in here
+
+ Ndn::DoDispose ();
+}
+
+uint32_t
+NdnL3Protocol::AddFace (const Ptr<NdnFace> &face)
+{
+ NS_LOG_FUNCTION (this << &face);
+
+ face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
+
+ // ask face to register in lower-layer stack
+ face->RegisterProtocolHandler (MakeCallback (&NdnL3Protocol::Receive, this));
+
+ m_faces.push_back (face);
+ m_faceCounter++;
+ return face->GetId ();
+}
+
+void
+NdnL3Protocol::RemoveFace (Ptr<NdnFace> face)
+{
+ // ask face to register in lower-layer stack
+ face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<NdnFace>&,const Ptr<const Packet>&> ());
+ Ptr<NdnPit> pit = GetObject<NdnPit> ();
+
+ // just to be on a safe side. Do the process in two steps
+ std::list< Ptr<NdnPitEntry> > entriesToRemoves;
+ for (Ptr<NdnPitEntry> pitEntry = pit->Begin (); pitEntry != 0; pitEntry = pit->Next (pitEntry))
+ {
+ pitEntry->RemoveAllReferencesToFace (face);
+
+ // If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
+ // Thus, we have to remove the whole PIT entry
+ if (pitEntry->GetFibEntry ()->m_faces.size () == 1 &&
+ pitEntry->GetFibEntry ()->m_faces.begin ()->m_face == face)
+ {
+ entriesToRemoves.push_back (pitEntry);
+ }
+ }
+ BOOST_FOREACH (Ptr<NdnPitEntry> removedEntry, entriesToRemoves)
+ {
+ pit->MarkErased (removedEntry);
+ }
+
+ NdnFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
+ NS_ASSERT_MSG (face_it != m_faces.end (), "Attempt to remove face that doesn't exist");
+ m_faces.erase (face_it);
+}
+
+Ptr<NdnFace>
+NdnL3Protocol::GetFace (uint32_t index) const
+{
+ BOOST_FOREACH (const Ptr<NdnFace> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
+ {
+ if (face->GetId () == index)
+ return face;
+ }
+ return 0;
+}
+
+Ptr<NdnFace>
+NdnL3Protocol::GetFaceByNetDevice (Ptr<NetDevice> netDevice) const
+{
+ BOOST_FOREACH (const Ptr<NdnFace> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
+ {
+ Ptr<NdnNetDeviceFace> netDeviceFace = DynamicCast<NdnNetDeviceFace> (face);
+ if (netDeviceFace == 0) continue;
+
+ if (netDeviceFace->GetNetDevice () == netDevice)
+ return face;
+ }
+ return 0;
+}
+
+uint32_t
+NdnL3Protocol::GetNFaces (void) const
+{
+ return m_faces.size ();
+}
+
+// Callback from lower layer
+void
+NdnL3Protocol::Receive (const Ptr<NdnFace> &face, const Ptr<const Packet> &p)
+{
+ if (!face->IsUp ())
+ return;
+
+ NS_LOG_DEBUG (*p);
+
+ NS_LOG_LOGIC ("Packet from face " << *face << " received on node " << m_node->GetId ());
+
+ Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
+ try
+ {
+ NdnHeaderHelper::Type type = NdnHeaderHelper::GetNdnHeaderType (p);
+ switch (type)
+ {
+ case NdnHeaderHelper::INTEREST:
+ {
+ Ptr<NdnInterestHeader> header = Create<NdnInterestHeader> ();
+
+ // Deserialization. Exception may be thrown
+ packet->RemoveHeader (*header);
+ NS_ASSERT_MSG (packet->GetSize () == 0, "Payload of Interests should be zero");
+
+ m_forwardingStrategy->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 NdnHeaderHelper::CONTENT_OBJECT:
+ {
+ Ptr<NdnContentObjectHeader> header = Create<NdnContentObjectHeader> ();
+
+ static NdnContentObjectTail contentObjectTrailer; //there is no data in this object
+
+ // Deserialization. Exception may be thrown
+ packet->RemoveHeader (*header);
+ packet->RemoveTrailer (contentObjectTrailer);
+
+ m_forwardingStrategy->OnData (face, header, packet/*payload*/, p/*original packet*/);
+ break;
+ }
+ }
+
+ // exception will be thrown if packet is not recognized
+ }
+ catch (NdnUnknownHeaderException)
+ {
+ NS_ASSERT_MSG (false, "Unknown Ndn header. Should not happen");
+ NS_LOG_ERROR ("Unknown Ndn header. Should not happen");
+ return;
+ }
+}
+
+// void
+// NdnL3Protocol::OnNack (const Ptr<NdnFace> &incomingFace,
+// Ptr<NdnInterestHeader> &header,
+// const Ptr<const Packet> &packet)
+// {
+// NS_LOG_FUNCTION (incomingFace << header << packet);
+// m_inNacks (header, incomingFace);
+
+// Ptr<NdnPitEntry> pitEntry = m_pit->Lookup (*header);
+// if (pitEntry == 0)
+// {
+// // somebody is doing something bad
+// m_dropNacks (header, NON_DUPLICATED, incomingFace);
+// return;
+// }
+
+// // NdnPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry->GetIncoming ().find (incomingFace);
+// NdnPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry->GetOutgoing ().find (incomingFace);
+
+// if (outFace == pitEntry->GetOutgoing ().end ())
+// {
+// // NS_ASSERT_MSG (false,
+// // "Node " << GetObject<Node> ()->GetId () << ", outgoing entry should exist for face " << boost::cref(*incomingFace) << "\n" <<
+// // "size: " << pitEntry.GetOutgoing ().size ());
+
+// // m_dropNacks (header, NON_DUPLICATE, incomingFace);
+// return;
+// }
+
+// // This was done in error. Never, never do anything, except normal leakage. This way we ensure that we will not have losses,
+// // at least when there is only one client
+// //
+// // incomingFace->LeakBucketByOnePacket ();
+
+// NS_LOG_ERROR ("Nack on " << boost::cref(*incomingFace));
+
+// pitEntry->SetWaitingInVain (outFace);
+
+// // If NACK is NACK_GIVEUP_PIT, then neighbor gave up trying to and removed it's PIT entry.
+// // So, if we had an incoming entry to this neighbor, then we can remove it now
+
+// if (header->GetNack () == NdnInterestHeader::NACK_GIVEUP_PIT)
+// {
+// pitEntry->RemoveIncoming (incomingFace);
+// }
+
+// pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, NdnFibFaceMetric::NDN_FIB_YELLOW);
+// // StaticCast<NdnFibImpl> (m_fib)->modify (pitEntry->GetFibEntry (),
+// // ll::bind (&NdnFibEntry::UpdateStatus,
+// // ll::_1, incomingFace, NdnFibFaceMetric::NDN_FIB_YELLOW));
+
+// if (pitEntry->GetIncoming ().size () == 0) // interest was actually satisfied
+// {
+// // no need to do anything
+// m_dropNacks (header, AFTER_SATISFIED, incomingFace);
+// return;
+// }
+
+// if (!pitEntry->AreAllOutgoingInVain ()) // not all ougtoing are in vain
+// {
+// NS_LOG_DEBUG ("Not all outgoing are in vain");
+// // suppress
+// // Don't do anything, we are still expecting data from some other face
+// m_dropNacks (header, SUPPRESSED, incomingFace);
+// return;
+// }
+
+// Ptr<Packet> nonNackInterest = Create<Packet> ();
+// header->SetNack (NdnInterestHeader::NORMAL_INTEREST);
+// nonNackInterest->AddHeader (*header);
+
+// bool propagated = m_forwardingStrategy->
+// PropagateInterest (pitEntry, incomingFace, header, nonNackInterest);
+
+// // // 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)
+// {
+// m_dropNacks (header, NO_FACES, incomingFace); // this headers doesn't have NACK flag set
+// GiveUpInterest (pitEntry, header);
+// }
+// }
+
+// Processing Interests
+//
+// // !!! Key point.
+// // !!! All interests should be answerred!!! Either later with data, immediately with data, or immediately with NACK
+// void NdnL3Protocol::OnInterest (const Ptr<NdnFace> &incomingFace,
+// Ptr<NdnInterestHeader> &header,
+// const Ptr<const Packet> &packet)
+// {
+// m_inInterests (header, incomingFace);
+
+// Ptr<NdnPitEntry> pitEntry = m_pit->Lookup (*header);
+// if (pitEntry == 0)
+// {
+// pitEntry = m_pit->Create (header);
+// }
+
+// if (pitEntry == 0)
+// {
+// // if it is still not created, then give up processing
+// m_dropInterests (header, PIT_LIMIT, incomingFace);
+// return;
+// }
+
+// bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
+// bool isDuplicated = true;
+// if (!pitEntry->IsNonceSeen (header->GetNonce ()))
+// {
+// pitEntry->AddSeenNonce (header->GetNonce ());
+// isDuplicated = false;
+// }
+
+// NS_LOG_FUNCTION (header->GetName () << header->GetNonce () << boost::cref (*incomingFace) << isDuplicated);
+
+// /////////////////////////////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////////////////////////
+// // //
+// // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
+// // //
+// /////////////////////////////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////////////////////////
+
+// // Data is not in cache
+// NdnPitEntry::in_iterator inFace = pitEntry->GetIncoming ().find (incomingFace);
+// NdnPitEntry::out_iterator outFace = pitEntry->GetOutgoing ().find (incomingFace);
+
+// bool isRetransmitted = false;
+
+// if (inFace != pitEntry->GetIncoming ().end ())
+// {
+// // NdnPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
+
+// isRetransmitted = true;
+// // this is almost definitely a retransmission. But should we trust the user on that?
+// }
+// else
+// {
+// inFace = pitEntry->AddIncoming (incomingFace);
+// }
+// //////////////////////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////////////////////
+
+// if (isDuplicated)
+// {
+// NS_LOG_DEBUG ("Received duplicatie interest on " << *incomingFace);
+// m_dropInterests (header, DUPLICATED, incomingFace);
+
+// /**
+// * 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.
+// */
+
+// if (m_nacksEnabled)
+// {
+// NS_LOG_DEBUG ("Sending NACK_LOOP");
+// header->SetNack (NdnInterestHeader::NACK_LOOP);
+// Ptr<Packet> nack = Create<Packet> ();
+// nack->AddHeader (*header);
+
+// incomingFace->Send (nack);
+// m_outNacks (header, incomingFace);
+// }
+
+// return;
+// }
+
+// Ptr<Packet> contentObject;
+// Ptr<const NdnContentObjectHeader> contentObjectHeader; // used for tracing
+// Ptr<const Packet> payload; // used for tracing
+// tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
+// if (contentObject != 0)
+// {
+// NS_ASSERT (contentObjectHeader != 0);
+// NS_LOG_LOGIC("Found in cache");
+
+// OnDataDelayed (contentObjectHeader, payload, contentObject);
+// return;
+// }
+
+// // update PIT entry lifetime
+// pitEntry->UpdateLifetime (header->GetInterestLifetime ());
+
+// if (outFace != pitEntry->GetOutgoing ().end ())
+// {
+// NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
+// // 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 ?? ...
+
+// pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, NdnFibFaceMetric::NDN_FIB_YELLOW);
+// // StaticCast<NdnFibImpl> (m_fib)->modify(pitEntry->GetFibEntry (),
+// // ll::bind (&NdnFibEntry::UpdateStatus,
+// // ll::_1, incomingFace, NdnFibFaceMetric::NDN_FIB_YELLOW));
+// }
+// else
+// if (!isNew && !isRetransmitted)
+// {
+// // Suppress this interest if we're still expecting data from some other face
+// NS_LOG_DEBUG ("Suppress interests");
+// m_dropInterests (header, SUPPRESSED, incomingFace);
+// return;
+// }
+
+// /////////////////////////////////////////////////////////////////////
+// // Propagate
+// /////////////////////////////////////////////////////////////////////
+
+// bool propagated = m_forwardingStrategy->
+// PropagateInterest (pitEntry, incomingFace, header, packet);
+
+// if (!propagated && isRetransmitted) //give another chance if retransmitted
+// {
+// // increase max number of allowed retransmissions
+// pitEntry->IncreaseAllowedRetxCount ();
+
+// // try again
+// propagated = m_forwardingStrategy->
+// PropagateInterest (pitEntry, incomingFace, header, packet);
+// }
+
+// // 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)
+// {
+// NS_LOG_DEBUG ("Not propagated");
+// m_dropInterests (header, NO_FACES, incomingFace);
+// GiveUpInterest (pitEntry, header);
+// }
+// }
+
+// void
+// NdnL3Protocol::OnDataDelayed (Ptr<const NdnContentObjectHeader> header,
+// Ptr<const Packet> payload,
+// const Ptr<const Packet> &packet)
+// {
+// // 1. Lookup PIT entry
+// Ptr<NdnPitEntry> pitEntry = m_pit->Lookup (*header);
+// if (pitEntry != 0)
+// {
+// //satisfy all pending incoming Interests
+// BOOST_FOREACH (const NdnPitEntryIncomingFace &incoming, pitEntry->GetIncoming ())
+// {
+// incoming.m_face->Send (packet->Copy ());
+// m_outData (header, payload, false, incoming.m_face);
+// NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
+
+// // successfull forwarded data trace
+// }
+
+// if (pitEntry->GetIncoming ().size () > 0)
+// {
+// // All incoming interests are satisfied. Remove them
+// pitEntry->ClearIncoming ();
+
+// // Remove all outgoing faces
+// pitEntry->ClearOutgoing ();
+
+// // Set pruning timout on PIT entry (instead of deleting the record)
+// m_pit->MarkErased (pitEntry);
+// }
+// }
+// else
+// {
+// NS_LOG_DEBUG ("Pit entry not found (was satisfied and removed before)");
+// return; // do not process unsoliced data packets
+// }
+// }
+
+// // Processing ContentObjects
+// void
+// NdnL3Protocol::OnData (const Ptr<NdnFace> &incomingFace,
+// Ptr<NdnContentObjectHeader> &header,
+// Ptr<Packet> &payload,
+// const Ptr<const Packet> &packet)
+// {
+
+// NS_LOG_FUNCTION (incomingFace << header->GetName () << payload << packet);
+// m_inData (header, payload, incomingFace);
+
+// // 1. Lookup PIT entry
+// Ptr<NdnPitEntry> pitEntry = m_pit->Lookup (*header);
+// if (pitEntry != 0)
+// {
+// // Note that with MultiIndex we need to modify entries indirectly
+
+// NdnPitEntry::out_iterator out = pitEntry->GetOutgoing ().find (incomingFace);
+
+// // If we have sent interest for this data via this face, then update stats.
+// if (out != pitEntry->GetOutgoing ().end ())
+// {
+// pitEntry->GetFibEntry ()->UpdateFaceRtt (incomingFace, Simulator::Now () - out->m_sendTime);
+// // StaticCast<NdnFibImpl> (m_fib)->modify (pitEntry->GetFibEntry (),
+// // ll::bind (&NdnFibEntry::UpdateFaceRtt,
+// // ll::_1,
+// // incomingFace,
+// // Simulator::Now () - out->m_sendTime));
+// }
+// else
+// {
+// // Unsolicited data, but we're interested in it... should we get it?
+// // Potential hole for attacks
+
+// if (m_cacheUnsolicitedData)
+// {
+// // Optimistically add or update entry in the content store
+// m_contentStore->Add (header, payload);
+// }
+// else
+// {
+// NS_LOG_ERROR ("Node "<< m_node->GetId() <<
+// ". PIT entry for "<< header->GetName ()<<" is valid, "
+// "but outgoing entry for interface "<< boost::cref(*incomingFace) <<" doesn't exist\n");
+// }
+// // ignore unsolicited data
+// return;
+// }
+
+// // Update metric status for the incoming interface in the corresponding FIB entry
+// pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, NdnFibFaceMetric::NDN_FIB_GREEN);
+// // StaticCast<NdnFibImpl>(m_fib)->modify (pitEntry->GetFibEntry (),
+// // ll::bind (&NdnFibEntry::UpdateStatus, ll::_1,
+// // incomingFace, NdnFibFaceMetric::NDN_FIB_GREEN));
+
+// // Add or update entry in the content store
+// m_contentStore->Add (header, payload);
+
+// pitEntry->RemoveIncoming (incomingFace);
+
+// if (pitEntry->GetIncoming ().size () == 0)
+// {
+// // Set pruning timout on PIT entry (instead of deleting the record)
+// m_pit->MarkErased (pitEntry);
+// }
+// else
+// {
+// OnDataDelayed (header, payload, packet);
+// }
+// }
+// else
+// {
+// NS_LOG_DEBUG ("Pit entry not found");
+// if (m_cacheUnsolicitedData)
+// {
+// // Optimistically add or update entry in the content store
+// m_contentStore->Add (header, payload);
+// }
+// else
+// {
+// // Drop data packet if PIT entry is not found
+// // (unsolicited data packets should not "poison" content store)
+
+// //drop dulicated or not requested data packet
+// m_dropData (header, payload, UNSOLICITED, incomingFace);
+// }
+// return; // do not process unsoliced data packets
+// }
+// }
+
+// void
+// NdnL3Protocol::GiveUpInterest (Ptr<NdnPitEntry> pitEntry,
+// Ptr<NdnInterestHeader> header)
+// {
+// NS_LOG_FUNCTION (this);
+
+// if (m_nacksEnabled)
+// {
+// Ptr<Packet> packet = Create<Packet> ();
+// header->SetNack (NdnInterestHeader::NACK_GIVEUP_PIT);
+// packet->AddHeader (*header);
+
+// BOOST_FOREACH (const NdnPitEntryIncomingFace &incoming, pitEntry->GetIncoming ())
+// {
+// NS_LOG_DEBUG ("Send NACK for " << boost::cref (header->GetName ()) << " to " << boost::cref (*incoming.m_face));
+// incoming.m_face->Send (packet->Copy ());
+
+// m_outNacks (header, incoming.m_face);
+// }
+
+// // All incoming interests cannot be satisfied. Remove them
+// pitEntry->ClearIncoming ();
+
+// // Remove also outgoing
+// pitEntry->ClearOutgoing ();
+
+// // Set pruning timout on PIT entry (instead of deleting the record)
+// m_pit->MarkErased (pitEntry);
+// }
+// }
+
+} //namespace ns3