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
ndn-pit-entry.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 "ndn-pit-entry.h"
22 
23 #include "ns3/ndn-pit.h"
24 #include "ns3/ndn-fib.h"
25 #include "ns3/ndn-name.h"
26 #include "ns3/ndn-interest.h"
27 
28 #include "ns3/packet.h"
29 #include "ns3/simulator.h"
30 #include "ns3/log.h"
31 
32 #include <boost/lambda/lambda.hpp>
33 #include <boost/lambda/bind.hpp>
34 #include <boost/foreach.hpp>
35 namespace ll = boost::lambda;
36 
37 NS_LOG_COMPONENT_DEFINE ("ndn.pit.Entry");
38 
39 namespace ns3 {
40 namespace ndn {
41 namespace pit {
42 
43 Entry::Entry (Pit &container,
44  Ptr<const Interest> header,
45  Ptr<fib::Entry> fibEntry)
46  : m_container (container)
47  , m_interest (header)
48  , m_fibEntry (fibEntry)
49  , m_maxRetxCount (0)
50 {
51  NS_LOG_FUNCTION (this);
52 
53  // UpdateLifetime is (and should) be called from the forwarding strategy
54 
55  UpdateLifetime ((!header->GetInterestLifetime ().IsZero ()?
56  header->GetInterestLifetime ():
57  Seconds (1.0)));
58 }
59 
61 {
62  NS_LOG_FUNCTION (GetPrefix ());
63 }
64 
65 void
66 Entry::UpdateLifetime (const Time &offsetTime)
67 {
68  NS_LOG_FUNCTION (this);
69 
70  Time newExpireTime = Simulator::Now () + (m_container.GetMaxPitEntryLifetime ().IsZero () ?
71  offsetTime :
72  std::min (m_container.GetMaxPitEntryLifetime (), offsetTime));
73  if (newExpireTime > m_expireTime)
74  m_expireTime = newExpireTime;
75 
76  NS_LOG_INFO (this->GetPrefix () << ", Updated lifetime to " << m_expireTime.ToDouble (Time::S) << "s, " << (m_expireTime-Simulator::Now ()).ToDouble (Time::S) << "s left");
77 }
78 
79 void
80 Entry::OffsetLifetime (const Time &offsetTime)
81 {
82  m_expireTime += offsetTime;
83  if (m_expireTime < Simulator::Now ())
84  {
85  m_expireTime = Simulator::Now ();
86  }
87  NS_LOG_INFO (this->GetPrefix () << ", Offsetting lifetime to " << m_expireTime.ToDouble (Time::S) << "s, " << (m_expireTime-Simulator::Now ()).ToDouble (Time::S) << "s left");
88 }
89 
90 
91 const Name &
93 {
94  return m_interest->GetName ();
95 }
96 
97 const Time &
99 {
100  return m_expireTime;
101 }
102 
103 bool
104 Entry::IsNonceSeen (uint32_t nonce) const
105 {
106  return m_seenNonces.find (nonce) != m_seenNonces.end ();
107 }
108 
109 void
110 Entry::AddSeenNonce (uint32_t nonce)
111 {
112  m_seenNonces.insert (nonce);
113 }
114 
115 
117 Entry::AddIncoming (Ptr<Face> face)
118 {
119  std::pair<in_iterator,bool> ret =
120  m_incoming.insert (IncomingFace (face));
121 
122  // NS_ASSERT_MSG (ret.second, "Something is wrong");
123 
124  return ret.first;
125 }
126 
127 void
128 Entry::RemoveIncoming (Ptr<Face> face)
129 {
130  m_incoming.erase (face);
131 }
132 
133 void
135 {
136  m_incoming.clear ();
137 }
138 
140 Entry::AddOutgoing (Ptr<Face> face)
141 {
142  std::pair<out_iterator,bool> ret =
143  m_outgoing.insert (OutgoingFace (face));
144 
145  if (!ret.second)
146  { // outgoing face already exists
147  const_cast<OutgoingFace&>(*ret.first).UpdateOnRetransmit ();
148  // m_outgoing.modify (ret.first,
149  // ll::bind (&OutgoingFace::UpdateOnRetransmit, ll::_1));
150  }
151 
152  return ret.first;
153 }
154 
155 void
157 {
158  m_outgoing.clear ();
159 }
160 
161 void
163 {
164  in_iterator incoming = m_incoming.find (face);
165 
166  if (incoming != m_incoming.end ())
167  m_incoming.erase (incoming);
168 
169  out_iterator outgoing =
170  m_outgoing.find (face);
171 
172  if (outgoing != m_outgoing.end ())
173  m_outgoing.erase (outgoing);
174 }
175 
176 // void
177 // Entry::SetWaitingInVain (Entry::out_iterator face)
178 // {
179 // NS_LOG_DEBUG (boost::cref (*face->m_face));
180 
181 // m_outgoing.modify (face,
182 // (&ll::_1)->*&EntryOutgoingFace::m_waitingInVain = true);
183 // }
184 
185 void
186 Entry::SetWaitingInVain (Ptr<Face> face)
187 {
188  // NS_LOG_DEBUG (boost::cref (*face->m_face));
189 
190  out_iterator item = m_outgoing.find (face);
191  if (item == m_outgoing.end ())
192  return;
193 
194  const_cast<OutgoingFace&>(*item).m_waitingInVain = true;
195  // m_outgoing.modify (item,
196  // (&ll::_1)->*&OutgoingFace::m_waitingInVain = true);
197 }
198 
199 
200 bool
202 {
203  NS_LOG_DEBUG (m_outgoing.size ());
204 
205  bool inVain = true;
206  std::for_each (m_outgoing.begin (), m_outgoing.end (),
207  ll::var(inVain) &= (&ll::_1)->*&OutgoingFace::m_waitingInVain);
208 
209  NS_LOG_DEBUG ("inVain " << inVain);
210  return inVain;
211 }
212 
213 bool
215 {
216  bool inVain = true;
217  std::for_each (m_outgoing.begin (), m_outgoing.end (),
218  ll::var(inVain) &=
219  ((&ll::_1)->*&OutgoingFace::m_face == face ||
220  (&ll::_1)->*&OutgoingFace::m_waitingInVain));
221 
222  return !inVain;
223 }
224 
225 void
227 {
228  if (Simulator::Now () - m_lastRetransmission >= MilliSeconds (100))
229  {
230  // cheat:
231  // don't allow retransmission faster than every 100ms
232  m_maxRetxCount++;
233  m_lastRetransmission = Simulator::Now ();
234  }
235 }
236 
237 Ptr<fib::Entry>
239 {
240  return m_fibEntry;
241 };
242 
243 const Entry::in_container &
245 {
246  return m_incoming;
247 }
248 
249 const Entry::out_container &
251 {
252  return m_outgoing;
253 }
254 
255 uint32_t
257 {
258  return m_outgoing.size ();
259 }
260 
261 
262 uint32_t
264 {
265  return m_maxRetxCount;
266 }
267 
268 Ptr<const Interest>
270 {
271  return m_interest;
272 }
273 
274 std::ostream& operator<< (std::ostream& os, const Entry &entry)
275 {
276  os << "Prefix: " << entry.GetPrefix () << "\n";
277  os << "In: ";
278  bool first = true;
279  BOOST_FOREACH (const IncomingFace &face, entry.m_incoming)
280  {
281  if (!first)
282  os << ",";
283  else
284  first = false;
285 
286  os << *face.m_face;
287  }
288 
289  os << "\nOut: ";
290  first = true;
291  BOOST_FOREACH (const OutgoingFace &face, entry.m_outgoing)
292  {
293  if (!first)
294  os << ",";
295  else
296  first = false;
297 
298  os << *face.m_face;
299  }
300  os << "\nNonces: ";
301  first = true;
302  BOOST_FOREACH (uint32_t nonce, entry.m_seenNonces)
303  {
304  if (!first)
305  os << ",";
306  else
307  first = false;
308 
309  os << nonce;
310  }
311 
312  return os;
313 }
314 
315 
316 } // namespace pit
317 } // namespace ndn
318 } // namespace ns3
bool AreTherePromisingOutgoingFacesExcept(Ptr< Face > face) const
Similar to AreAllOutgoingInVain, but ignores face
Ptr< fib::Entry > m_fibEntry
FIB entry related to this prefix.
Class for NDN Name.
Definition: name.h:29
structure for PIT entry
Definition: ndn-pit-entry.h:57
Entry(Pit &container, Ptr< const Interest > header, Ptr< fib::Entry > fibEntry)
PIT entry constructor.
out_container m_outgoing
container for outgoing interests
Ptr< const Interest > m_interest
Interest of the PIT entry (if several interests are received, then nonce is from the first Interest) ...
PIT state component for each outgoing interest.
virtual in_iterator AddIncoming(Ptr< Face > face)
Add face to the list of incoming faces.
virtual void RemoveAllReferencesToFace(Ptr< Face > face)
Remove all references to face.
virtual ~Entry()
Virtual destructor.
std::set< OutgoingFace > out_container
outgoing faces container type
Definition: ndn-pit-entry.h:64
Class implementing Pending Interests Table.
Definition: ndn-pit.h:60
Time m_lastRetransmission
Last time when number of retransmissions were increased.
Ptr< Face > m_face
face of the incoming Interest
const Time & GetMaxPitEntryLifetime() const
Get maximum PIT entry lifetime.
Definition: ndn-pit.h:211
virtual out_iterator AddOutgoing(Ptr< Face > face)
Add face to the list of outgoing faces.
Ptr< fib::Entry > GetFibEntry()
Get associated FIB entry.
virtual void ClearIncoming()
Clear all incoming faces either after all of them were satisfied or NACKed.
bool AreAllOutgoingInVain() const
Check if all outgoing faces are NACKed.
in_container::iterator in_iterator
iterator to incoming faces
Definition: ndn-pit-entry.h:61
Ptr< Face > m_face
face of the outgoing Interest
virtual void RemoveIncoming(Ptr< Face > face)
Remove incoming entry for face face
in_container m_incoming
container for incoming interests
virtual void OffsetLifetime(const Time &offsetTime)
Offset the currently set PIT lifetime (allowed both negative and positive offsets) ...
bool m_waitingInVain
when flag is set, we do not expect data for this interest, only a small hope that it will happen ...
std::set< IncomingFace > in_container
incoming faces container type
Definition: ndn-pit-entry.h:60
Ptr< const Interest > GetInterest() const
Get Interest (if several interests are received, then nonce is from the first Interest) ...
Time m_expireTime
Time when PIT entry will be removed.
const in_container & GetIncoming() const
Get associated list (const reference) of incoming faces.
virtual void ClearOutgoing()
Clear all incoming faces either after all of them were satisfied or NACKed.
const out_container & GetOutgoing() const
Get associated list (const reference) of outgoing faces.
uint32_t m_maxRetxCount
Maximum allowed number of retransmissions via outgoing faces.
virtual void AddSeenNonce(uint32_t nonce)
Add nonce to the list of seen nonces.
virtual void UpdateLifetime(const Time &lifetime)
Update lifetime of PIT entry.
nonce_container m_seenNonces
map of nonces that were seen for this prefix
const Name & GetPrefix() const
Get prefix of the PIT entry.
virtual void SetWaitingInVain(Ptr< Face > face)
Flag outgoing face as hopeless.
uint32_t GetOutgoingCount() const
Get number of outgoing faces (needed for python bindings)
Pit & m_container
Reference to the container (to rearrange indexes, if necessary)
const Time & GetExpireTime() const
Get current expiration time of the record.
virtual void IncreaseAllowedRetxCount()
Increase maximum limit of allowed retransmission per outgoing face.
uint32_t GetMaxRetxCount() const
Get maximum allowed number of retransmissions via outgoing faces.
bool IsNonceSeen(uint32_t nonce) const
Check if nonce nonce for the same prefix has already been seen.
out_container::iterator out_iterator
iterator to outgoing faces
Definition: ndn-pit-entry.h:65
PIT state component for each incoming interest (not including duplicates)