NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
nacks.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2011 University of California, Los Angeles
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19  */
20 
21 #include "nacks.h"
22 
23 #include "ns3/ndn-pit.h"
24 #include "ns3/ndn-pit-entry.h"
25 #include "ns3/ndn-interest.h"
26 #include "ns3/ndn-data.h"
27 #include "ns3/ndn-pit.h"
28 #include "ns3/ndn-fib.h"
29 #include "ns3/ndn-content-store.h"
30 #include "ns3/ndnSIM/utils/ndn-fw-hop-count-tag.h"
31 
32 #include "ns3/assert.h"
33 #include "ns3/ptr.h"
34 #include "ns3/log.h"
35 #include "ns3/simulator.h"
36 #include "ns3/boolean.h"
37 #include "ns3/string.h"
38 
39 #include <boost/ref.hpp>
40 #include <boost/foreach.hpp>
41 #include <boost/lambda/lambda.hpp>
42 #include <boost/lambda/bind.hpp>
43 #include <boost/tuple/tuple.hpp>
44 namespace ll = boost::lambda;
45 
46 NS_LOG_COMPONENT_DEFINE ("ndn.fw.Nacks");
47 
48 namespace ns3 {
49 namespace ndn {
50 namespace fw {
51 
52 NS_OBJECT_ENSURE_REGISTERED (Nacks);
53 
54 TypeId
55 Nacks::GetTypeId (void)
56 {
57  static TypeId tid = TypeId ("ns3::ndn::fw::Nacks")
58  .SetGroupName ("Ndn")
59  .SetParent<ForwardingStrategy> ()
60 
63 
64  .AddTraceSource ("OutNacks", "OutNacks", MakeTraceSourceAccessor (&Nacks::m_outNacks))
65  .AddTraceSource ("InNacks", "InNacks", MakeTraceSourceAccessor (&Nacks::m_inNacks))
66  .AddTraceSource ("DropNacks", "DropNacks", MakeTraceSourceAccessor (&Nacks::m_dropNacks))
67 
68  .AddAttribute ("EnableNACKs", "Enabling support of NACKs",
69  BooleanValue (false),
70  MakeBooleanAccessor (&Nacks::m_nacksEnabled),
71  MakeBooleanChecker ())
72  ;
73  return tid;
74 }
75 
76 void
77 Nacks::OnInterest (Ptr<Face> inFace,
78  Ptr<Interest> interest)
79 {
80  if (interest->GetNack () > 0)
81  OnNack (inFace, interest);
82  else
83  super::OnInterest (inFace, interest);
84 }
85 
86 void
87 Nacks::OnNack (Ptr<Face> inFace,
88  Ptr<Interest> nack)
89 {
90  // NS_LOG_FUNCTION (inFace << nack->GetName ());
91  m_inNacks (nack, inFace);
92 
93  Ptr<pit::Entry> pitEntry = m_pit->Lookup (*nack);
94  if (pitEntry == 0)
95  {
96  // somebody is doing something bad
97  m_dropNacks (nack, inFace);
98  return;
99  }
100 
101  DidReceiveValidNack (inFace, nack->GetNack (), nack, pitEntry);
102 }
103 
104 void
106  Ptr<const Interest> interest,
107  Ptr<pit::Entry> pitEntry)
108 {
109  super::DidReceiveDuplicateInterest (inFace, interest, pitEntry);
110 
111  if (m_nacksEnabled)
112  {
113  NS_LOG_DEBUG ("Sending NACK_LOOP");
114  Ptr<Interest> nack = Create<Interest> (*interest);
115  nack->SetNack (Interest::NACK_LOOP);
116 
117  inFace->SendInterest (nack);
118  m_outNacks (nack, inFace);
119  }
120 }
121 
122 void
124  Ptr<const Interest> interest,
125  Ptr<pit::Entry> pitEntry)
126 {
127  if (m_nacksEnabled)
128  {
129  Ptr<Interest> nack = Create<Interest> (*interest);
130  nack->SetNack (Interest::NACK_GIVEUP_PIT);
131 
132  BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
133  {
134  NS_LOG_DEBUG ("Send NACK for " << boost::cref (nack->GetName ()) << " to " << boost::cref (*incoming.m_face));
135  incoming.m_face->SendInterest (nack);
136  m_outNacks (nack, incoming.m_face);
137  }
138 
139  pitEntry->ClearOutgoing (); // to force erasure of the record
140  }
141 
142  super::DidExhaustForwardingOptions (inFace, interest, pitEntry);
143 }
144 
145 void
146 Nacks::DidReceiveValidNack (Ptr<Face> inFace,
147  uint32_t nackCode,
148  Ptr<const Interest> nack,
149  Ptr<pit::Entry> pitEntry)
150 {
151  NS_LOG_DEBUG ("nackCode: " << nackCode << " for [" << nack->GetName () << "]");
152 
153  // If NACK is NACK_GIVEUP_PIT, then neighbor gave up trying to and removed it's PIT entry.
154  // So, if we had an incoming entry to this neighbor, then we can remove it now
155  if (nackCode == Interest::NACK_GIVEUP_PIT)
156  {
157  pitEntry->RemoveIncoming (inFace);
158  }
159 
160  if (nackCode == Interest::NACK_LOOP ||
161  nackCode == Interest::NACK_CONGESTION ||
162  nackCode == Interest::NACK_GIVEUP_PIT)
163  {
164  pitEntry->SetWaitingInVain (inFace);
165 
166  if (!pitEntry->AreAllOutgoingInVain ()) // not all ougtoing are in vain
167  {
168  NS_LOG_DEBUG ("Not all outgoing are in vain");
169  // suppress
170  // Don't do anything, we are still expecting data from some other face
171  m_dropNacks (nack, inFace);
172  return;
173  }
174 
175  Ptr<Interest> interest = Create<Interest> (*nack);
176  interest->SetNack (Interest::NORMAL_INTEREST);
177 
178  bool propagated = DoPropagateInterest (inFace, interest, pitEntry);
179  if (!propagated)
180  {
181  DidExhaustForwardingOptions (inFace, interest, pitEntry);
182  }
183  }
184 }
185 
186 } // namespace fw
187 } // namespace ndn
188 } // namespace ns3
virtual void OnInterest(Ptr< Face > face, Ptr< Interest > interest)
Actual processing of incoming Ndn interests.
virtual bool DoPropagateInterest(Ptr< Face > inFace, Ptr< const Interest > interest, Ptr< pit::Entry > pitEntry)=0
Virtual method to perform Interest propagation according to the forwarding strategy logic...
TracedCallback< Ptr< const Interest >, Ptr< const Face > > m_outNacks
trace of outgoing NACKs
Definition: nacks.h:75
virtual void DidExhaustForwardingOptions(Ptr< Face > inFace, Ptr< const Interest > interest, Ptr< pit::Entry > pitEntry)
An even that is fired when Interest cannot be forwarded.
Ptr< Face > m_face
face of the incoming Interest
TracedCallback< Ptr< const Interest >, Ptr< const Face > > m_dropNacks
trace of dropped NACKs
Definition: nacks.h:81
virtual void DidReceiveDuplicateInterest(Ptr< Face > inFace, Ptr< const Interest > interest, Ptr< pit::Entry > pitEntry)
An event that is fired every time a duplicated Interest is received.
ForwardingStrategy()
Default constructor.
TracedCallback< Ptr< const Interest >, Ptr< const Face > > m_inNacks
trace of incoming NACKs
Definition: nacks.h:78
Ptr< Pit > m_pit
Reference to PIT to which this forwarding strategy is associated.
virtual void DidExhaustForwardingOptions(Ptr< Face > inFace, Ptr< const Interest > interest, Ptr< pit::Entry > pitEntry)
An even that is fired when Interest cannot be forwarded.
Definition: nacks.cc:123
virtual void OnInterest(Ptr< Face > face, Ptr< Interest > interest)
Actual processing of incoming Ndn interests.
Definition: nacks.cc:77
virtual void DidReceiveDuplicateInterest(Ptr< Face > inFace, Ptr< const Interest > interest, Ptr< pit::Entry > pitEntry)
An event that is fired every time a duplicated Interest is received.
Definition: nacks.cc:105
PIT state component for each incoming interest (not including duplicates)