blob: 770613bfdb6e8616ec37405b06752ef2e76f9a9d [file] [log] [blame]
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -07001/* -*- 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 * Ilya Moiseenko <iliamo@cs.ucla.edu>
20 */
21
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070022#include "ndn-forwarding-strategy.h"
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070023
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070024#include "ns3/ndn-pit.h"
25#include "ns3/ndn-pit-entry.h"
26#include "ns3/ndn-interest-header.h"
27#include "ns3/ndn-content-object-header.h"
28#include "ns3/ndn-pit.h"
29#include "ns3/ndn-fib.h"
30#include "ns3/ndn-content-store.h"
31#include "ns3/ndn-face.h"
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070032
33#include "ns3/assert.h"
34#include "ns3/ptr.h"
35#include "ns3/log.h"
36#include "ns3/simulator.h"
37#include "ns3/boolean.h"
38#include "ns3/string.h"
39
40#include <boost/ref.hpp>
41#include <boost/foreach.hpp>
42#include <boost/lambda/lambda.hpp>
43#include <boost/lambda/bind.hpp>
44#include <boost/tuple/tuple.hpp>
45namespace ll = boost::lambda;
46
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070047namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070048namespace ndn {
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070049
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070050NS_OBJECT_ENSURE_REGISTERED (ForwardingStrategy);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070051
Alexander Afanasyev042b4a72012-11-09 17:47:48 -080052NS_LOG_COMPONENT_DEFINE (ForwardingStrategy::GetLogName ().c_str ());
53
54std::string
55ForwardingStrategy::GetLogName ()
56{
57 return "ndn.fw";
58}
59
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070060TypeId ForwardingStrategy::GetTypeId (void)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070061{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070062 static TypeId tid = TypeId ("ns3::ndn::ForwardingStrategy")
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070063 .SetGroupName ("Ndn")
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070064 .SetParent<Object> ()
65
66 ////////////////////////////////////////////////////////////////////
67 ////////////////////////////////////////////////////////////////////
68
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070069 .AddTraceSource ("OutInterests", "OutInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_outInterests))
70 .AddTraceSource ("InInterests", "InInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_inInterests))
71 .AddTraceSource ("DropInterests", "DropInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_dropInterests))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070072
73 ////////////////////////////////////////////////////////////////////
74 ////////////////////////////////////////////////////////////////////
75
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070076 .AddTraceSource ("OutData", "OutData", MakeTraceSourceAccessor (&ForwardingStrategy::m_outData))
77 .AddTraceSource ("InData", "InData", MakeTraceSourceAccessor (&ForwardingStrategy::m_inData))
78 .AddTraceSource ("DropData", "DropData", MakeTraceSourceAccessor (&ForwardingStrategy::m_dropData))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070079
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070080 .AddAttribute ("CacheUnsolicitedData", "Cache overheard data that have not been requested",
81 BooleanValue (false),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070082 MakeBooleanAccessor (&ForwardingStrategy::m_cacheUnsolicitedData),
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070083 MakeBooleanChecker ())
84
Alexander Afanasyev996b4872012-07-17 17:07:56 -070085 .AddAttribute ("DetectRetransmissions", "If non-duplicate interest is received on the same face more than once, "
86 "it is considered a retransmission",
87 BooleanValue (true),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070088 MakeBooleanAccessor (&ForwardingStrategy::m_detectRetransmissions),
Alexander Afanasyev996b4872012-07-17 17:07:56 -070089 MakeBooleanChecker ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070090 ;
91 return tid;
92}
93
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070094ForwardingStrategy::ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070095{
96}
97
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070098ForwardingStrategy::~ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070099{
100}
101
102void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700103ForwardingStrategy::NotifyNewAggregate ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700104{
105 if (m_pit == 0)
106 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700107 m_pit = GetObject<Pit> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700108 }
109 if (m_fib == 0)
110 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700111 m_fib = GetObject<Fib> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700112 }
113 if (m_contentStore == 0)
114 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700115 m_contentStore = GetObject<ContentStore> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700116 }
117
118 Object::NotifyNewAggregate ();
119}
120
121void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700122ForwardingStrategy::DoDispose ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700123{
124 m_pit = 0;
125 m_contentStore = 0;
126 m_fib = 0;
127
128 Object::DoDispose ();
129}
130
131void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700132ForwardingStrategy::OnInterest (Ptr<Face> inFace,
133 Ptr<const InterestHeader> header,
134 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700135{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700136 m_inInterests (header, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700137
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700138 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700139 bool similarInterest = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700140 if (pitEntry == 0)
141 {
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700142 similarInterest = false;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700143 pitEntry = m_pit->Create (header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700144 if (pitEntry != 0)
145 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700146 DidCreatePitEntry (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700147 }
148 else
149 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700150 FailedToCreatePitEntry (inFace, header, origPacket);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700151 return;
152 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700153 }
154
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700155 bool isDuplicated = true;
156 if (!pitEntry->IsNonceSeen (header->GetNonce ()))
157 {
158 pitEntry->AddSeenNonce (header->GetNonce ());
159 isDuplicated = false;
160 }
161
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700162 if (isDuplicated)
163 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700164 DidReceiveDuplicateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700165 return;
166 }
167
168 Ptr<Packet> contentObject;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700169 Ptr<const ContentObjectHeader> contentObjectHeader; // used for tracing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700170 Ptr<const Packet> payload; // used for tracing
171 boost::tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
172 if (contentObject != 0)
173 {
174 NS_ASSERT (contentObjectHeader != 0);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700175
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700176 pitEntry->AddIncoming (inFace/*, Seconds (1.0)*/);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700177
178 // Do data plane performance measurements
179 WillSatisfyPendingInterest (0, pitEntry);
180
181 // Actually satisfy pending interest
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700182 SatisfyPendingInterest (0, contentObjectHeader, payload, contentObject, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700183 return;
184 }
185
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700186 if (similarInterest && ShouldSuppressIncomingInterest (inFace, header, origPacket, pitEntry))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700187 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700188 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700189 // update PIT entry lifetime
190 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700191
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700192 // Suppress this interest if we're still expecting data from some other face
193 NS_LOG_DEBUG ("Suppress interests");
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700194 m_dropInterests (header, inFace);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700195
196 DidSuppressSimilarInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700197 return;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700198 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700199
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700200 if (similarInterest)
201 {
202 DidForwardSimilarInterest (inFace, header, origPacket, pitEntry);
203 }
204
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700205 PropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700206}
207
208void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700209ForwardingStrategy::OnData (Ptr<Face> inFace,
210 Ptr<const ContentObjectHeader> header,
211 Ptr<Packet> payload,
212 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700213{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700214 NS_LOG_FUNCTION (inFace << header->GetName () << payload << origPacket);
215 m_inData (header, payload, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700216
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700217 // Lookup PIT entry
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700218 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700219 if (pitEntry == 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700220 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700221 DidReceiveUnsolicitedData (inFace, header, payload, origPacket);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700222 return;
223 }
224 else
225 {
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700226 // Add or update entry in the content store
227 m_contentStore->Add (header, payload);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700228 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700229
230 while (pitEntry != 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700231 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700232 // Do data plane performance measurements
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700233 WillSatisfyPendingInterest (inFace, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700234
235 // Actually satisfy pending interest
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700236 SatisfyPendingInterest (inFace, header, payload, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700237
238 // Lookup another PIT entry
239 pitEntry = m_pit->Lookup (*header);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700240 }
241}
242
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700243void
244ForwardingStrategy::DidCreatePitEntry (Ptr<Face> inFace,
245 Ptr<const InterestHeader> header,
246 Ptr<const Packet> origPacket,
247 Ptr<pit::Entry> pitEntrypitEntry)
248{
249}
250
251void
252ForwardingStrategy::FailedToCreatePitEntry (Ptr<Face> inFace,
253 Ptr<const InterestHeader> header,
254 Ptr<const Packet> origPacket)
255{
256 m_dropInterests (header, inFace);
257}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700258
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700259void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700260ForwardingStrategy::DidReceiveDuplicateInterest (Ptr<Face> inFace,
261 Ptr<const InterestHeader> header,
262 Ptr<const Packet> origPacket,
263 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700264{
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700265 /////////////////////////////////////////////////////////////////////////////////////////
266 // //
267 // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
268 // //
269 /////////////////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700270 pitEntry->AddIncoming (inFace);
271 m_dropInterests (header, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700272}
273
274void
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700275ForwardingStrategy::DidSuppressSimilarInterest (Ptr<Face> face,
276 Ptr<const InterestHeader> header,
277 Ptr<const Packet> origPacket,
278 Ptr<pit::Entry> pitEntry)
279{
280}
281
282void
283ForwardingStrategy::DidForwardSimilarInterest (Ptr<Face> inFace,
284 Ptr<const InterestHeader> header,
285 Ptr<const Packet> origPacket,
286 Ptr<pit::Entry> pitEntry)
287{
288}
289
290void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700291ForwardingStrategy::DidExhaustForwardingOptions (Ptr<Face> inFace,
292 Ptr<const InterestHeader> header,
293 Ptr<const Packet> origPacket,
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700294 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700295{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700296 NS_LOG_FUNCTION (this << boost::cref (*inFace));
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700297 if (pitEntry->GetOutgoing ().size () == 0)
298 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700299 m_dropInterests (header, inFace);
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700300
301 // All incoming interests cannot be satisfied. Remove them
302 pitEntry->ClearIncoming ();
303
304 // Remove also outgoing
305 pitEntry->ClearOutgoing ();
306
307 // Set pruning timout on PIT entry (instead of deleting the record)
308 m_pit->MarkErased (pitEntry);
309 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700310}
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700311
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700312
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700313
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700314bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700315ForwardingStrategy::DetectRetransmittedInterest (Ptr<Face> inFace,
316 Ptr<const InterestHeader> header,
317 Ptr<const Packet> packet,
318 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700319{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700320 pit::Entry::in_iterator existingInFace = pitEntry->GetIncoming ().find (inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700321
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700322 bool isRetransmitted = false;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700323
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700324 if (existingInFace != pitEntry->GetIncoming ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700325 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700326 // this is almost definitely a retransmission. But should we trust the user on that?
327 isRetransmitted = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700328 }
329
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700330 return isRetransmitted;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700331}
332
333void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700334ForwardingStrategy::SatisfyPendingInterest (Ptr<Face> inFace,
335 Ptr<const ContentObjectHeader> header,
336 Ptr<const Packet> payload,
337 Ptr<const Packet> origPacket,
338 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700339{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700340 if (inFace != 0)
341 pitEntry->RemoveIncoming (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700342
343 //satisfy all pending incoming Interests
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700344 BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700345 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700346 bool ok = incoming.m_face->Send (origPacket->Copy ());
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700347 if (ok)
348 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700349 m_outData (header, payload, inFace == 0, incoming.m_face);
350 DidSendOutData (incoming.m_face, header, payload, origPacket, pitEntry);
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700351
352 NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
353 }
354 else
355 {
356 m_dropData (header, payload, incoming.m_face);
357 NS_LOG_DEBUG ("Cannot satisfy data to " << *incoming.m_face);
358 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700359
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700360 // successfull forwarded data trace
361 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700362
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700363 // All incoming interests are satisfied. Remove them
364 pitEntry->ClearIncoming ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700365
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700366 // Remove all outgoing faces
367 pitEntry->ClearOutgoing ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700368
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700369 // Set pruning timout on PIT entry (instead of deleting the record)
370 m_pit->MarkErased (pitEntry);
371}
372
373void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700374ForwardingStrategy::DidReceiveUnsolicitedData (Ptr<Face> inFace,
375 Ptr<const ContentObjectHeader> header,
376 Ptr<const Packet> payload,
377 Ptr<const Packet> origPacket)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700378{
379 if (m_cacheUnsolicitedData)
380 {
381 // Optimistically add or update entry in the content store
382 m_contentStore->Add (header, payload);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700383 }
384 else
385 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700386 // Drop data packet if PIT entry is not found
387 // (unsolicited data packets should not "poison" content store)
388
389 //drop dulicated or not requested data packet
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700390 m_dropData (header, payload, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700391 }
392}
393
394void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700395ForwardingStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
396 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700397{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700398 pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700399
400 // If we have sent interest for this data via this face, then update stats.
401 if (out != pitEntry->GetOutgoing ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700402 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700403 pitEntry->GetFibEntry ()->UpdateFaceRtt (inFace, Simulator::Now () - out->m_sendTime);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700404 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700405}
406
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700407bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700408ForwardingStrategy::ShouldSuppressIncomingInterest (Ptr<Face> inFace,
409 Ptr<const InterestHeader> header,
410 Ptr<const Packet> origPacket,
411 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700412{
413 bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
414
415 if (isNew) return false; // never suppress new interests
416
417 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700418 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700419
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700420 if (pitEntry->GetOutgoing ().find (inFace) != pitEntry->GetOutgoing ().end ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700421 {
422 NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
423 // got a non-duplicate interest from the face we have sent interest to
424 // Probably, there is no point in waiting data from that face... Not sure yet
425
426 // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
427 // Mark interface YELLOW, but keep a small hope that data will come eventually.
428
429 // ?? not sure if we need to do that ?? ...
430
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700431 // pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700432 }
433 else
434 if (!isNew && !isRetransmitted)
435 {
436 return true;
437 }
438
439 return false;
440}
441
442void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700443ForwardingStrategy::PropagateInterest (Ptr<Face> inFace,
444 Ptr<const InterestHeader> header,
445 Ptr<const Packet> origPacket,
446 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700447{
448 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700449 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700450
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700451 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700452 /// @todo Make lifetime per incoming interface
453 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
454
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700455 bool propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700456
457 if (!propagated && isRetransmitted) //give another chance if retransmitted
458 {
459 // increase max number of allowed retransmissions
460 pitEntry->IncreaseAllowedRetxCount ();
461
462 // try again
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700463 propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700464 }
465
466 // ForwardingStrategy will try its best to forward packet to at least one interface.
467 // If no interests was propagated, then there is not other option for forwarding or
468 // ForwardingStrategy failed to find it.
469 if (!propagated && pitEntry->GetOutgoing ().size () == 0)
470 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700471 DidExhaustForwardingOptions (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700472 }
473}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700474
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700475bool
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800476ForwardingStrategy::CanSendOutInterest (Ptr<Face> inFace,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700477 Ptr<Face> outFace,
478 Ptr<const InterestHeader> header,
479 Ptr<const Packet> origPacket,
480 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700481{
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700482 if (outFace == inFace)
483 {
484 NS_LOG_DEBUG ("Same as incoming");
485 return false; // same face as incoming, don't forward
486 }
487
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700488 pit::Entry::out_iterator outgoing =
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700489 pitEntry->GetOutgoing ().find (outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700490
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700491 if (outgoing != pitEntry->GetOutgoing ().end ())
492 {
493 if (!m_detectRetransmissions)
494 return false; // suppress
495 else if (outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
496 {
497 NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount ());
498 return false; // already forwarded before during this retransmission cycle
499 }
500 }
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800501
502 return true;
503}
504
505
506bool
507ForwardingStrategy::TrySendOutInterest (Ptr<Face> inFace,
508 Ptr<Face> outFace,
509 Ptr<const InterestHeader> header,
510 Ptr<const Packet> origPacket,
511 Ptr<pit::Entry> pitEntry)
512{
513 if (!CanSendOutInterest (inFace, outFace, header, origPacket, pitEntry))
514 {
515 return false;
516 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700517
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700518 pitEntry->AddOutgoing (outFace);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700519
520 //transmission
521 Ptr<Packet> packetToSend = origPacket->Copy ();
522 outFace->Send (packetToSend);
523
524 DidSendOutInterest (outFace, header, origPacket, pitEntry);
525
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700526 return true;
527}
528
529void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700530ForwardingStrategy::DidSendOutInterest (Ptr<Face> outFace,
531 Ptr<const InterestHeader> header,
532 Ptr<const Packet> origPacket,
533 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700534{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700535 m_outInterests (header, outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700536}
537
538void
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800539ForwardingStrategy::DidSendOutData (Ptr<Face> outFace,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700540 Ptr<const ContentObjectHeader> header,
541 Ptr<const Packet> payload,
542 Ptr<const Packet> origPacket,
543 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700544{
545}
546
547void
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700548ForwardingStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700549{
550 // do nothing for now. may be need to do some logging
551}
552
Alexander Afanasyevf5c07742012-10-31 13:13:05 -0700553void
554ForwardingStrategy::AddFace (Ptr<Face> face)
555{
556 // do nothing here
557}
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700558
559void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700560ForwardingStrategy::RemoveFace (Ptr<Face> face)
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700561{
562 // do nothing here
563}
564
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700565} // namespace ndn
566} // namespace ns3