blob: 1d6bcda7191a0e5fe79a68adb48d0bd4182abf7e [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"
Alexander Afanasyevbd9c18e2012-11-19 15:23:41 -080026#include "ns3/ndn-interest.h"
27#include "ns3/ndn-content-object.h"
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070028#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
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -080040#include "ns3/ndnSIM/utils/ndn-fw-hop-count-tag.h"
41
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070042#include <boost/ref.hpp>
43#include <boost/foreach.hpp>
44#include <boost/lambda/lambda.hpp>
45#include <boost/lambda/bind.hpp>
46#include <boost/tuple/tuple.hpp>
47namespace ll = boost::lambda;
48
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070049namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070050namespace ndn {
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070051
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070052NS_OBJECT_ENSURE_REGISTERED (ForwardingStrategy);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070053
Alexander Afanasyev042b4a72012-11-09 17:47:48 -080054NS_LOG_COMPONENT_DEFINE (ForwardingStrategy::GetLogName ().c_str ());
55
56std::string
57ForwardingStrategy::GetLogName ()
58{
59 return "ndn.fw";
60}
61
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070062TypeId ForwardingStrategy::GetTypeId (void)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070063{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070064 static TypeId tid = TypeId ("ns3::ndn::ForwardingStrategy")
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070065 .SetGroupName ("Ndn")
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070066 .SetParent<Object> ()
67
68 ////////////////////////////////////////////////////////////////////
69 ////////////////////////////////////////////////////////////////////
70
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070071 .AddTraceSource ("OutInterests", "OutInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_outInterests))
72 .AddTraceSource ("InInterests", "InInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_inInterests))
73 .AddTraceSource ("DropInterests", "DropInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_dropInterests))
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -080074
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070075 ////////////////////////////////////////////////////////////////////
76 ////////////////////////////////////////////////////////////////////
77
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070078 .AddTraceSource ("OutData", "OutData", MakeTraceSourceAccessor (&ForwardingStrategy::m_outData))
79 .AddTraceSource ("InData", "InData", MakeTraceSourceAccessor (&ForwardingStrategy::m_inData))
80 .AddTraceSource ("DropData", "DropData", MakeTraceSourceAccessor (&ForwardingStrategy::m_dropData))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070081
Alexander Afanasyev37b84c52013-04-26 13:38:52 -070082 ////////////////////////////////////////////////////////////////////
83 ////////////////////////////////////////////////////////////////////
84
85 .AddTraceSource ("SatisfiedInterests", "SatisfiedInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_satisfiedInterests))
86 .AddTraceSource ("TimedOutInterests", "TimedOutInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_timedOutInterests))
Alexander Afanasyevdd9fa4f2013-05-15 16:35:04 -070087
88 .AddAttribute ("CacheUnsolicitedDataFromApps", "Cache unsolicited data that has been pushed from applications",
89 BooleanValue (true),
90 MakeBooleanAccessor (&ForwardingStrategy::m_cacheUnsolicitedDataFromApps),
91 MakeBooleanChecker ())
Alexander Afanasyev37b84c52013-04-26 13:38:52 -070092
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070093 .AddAttribute ("CacheUnsolicitedData", "Cache overheard data that have not been requested",
94 BooleanValue (false),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070095 MakeBooleanAccessor (&ForwardingStrategy::m_cacheUnsolicitedData),
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070096 MakeBooleanChecker ())
97
Alexander Afanasyev996b4872012-07-17 17:07:56 -070098 .AddAttribute ("DetectRetransmissions", "If non-duplicate interest is received on the same face more than once, "
99 "it is considered a retransmission",
100 BooleanValue (true),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700101 MakeBooleanAccessor (&ForwardingStrategy::m_detectRetransmissions),
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700102 MakeBooleanChecker ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700103 ;
104 return tid;
105}
106
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700107ForwardingStrategy::ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700108{
109}
110
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700111ForwardingStrategy::~ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700112{
113}
114
115void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700116ForwardingStrategy::NotifyNewAggregate ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700117{
118 if (m_pit == 0)
119 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700120 m_pit = GetObject<Pit> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700121 }
122 if (m_fib == 0)
123 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700124 m_fib = GetObject<Fib> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700125 }
126 if (m_contentStore == 0)
127 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700128 m_contentStore = GetObject<ContentStore> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700129 }
130
131 Object::NotifyNewAggregate ();
132}
133
134void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700135ForwardingStrategy::DoDispose ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700136{
137 m_pit = 0;
138 m_contentStore = 0;
139 m_fib = 0;
140
141 Object::DoDispose ();
142}
143
144void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700145ForwardingStrategy::OnInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700146 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700147 Ptr<const Packet> payload)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700148{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700149 m_inInterests (header, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700150
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700151 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700152 bool similarInterest = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700153 if (pitEntry == 0)
154 {
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700155 similarInterest = false;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700156 pitEntry = m_pit->Create (header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700157 if (pitEntry != 0)
158 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700159 DidCreatePitEntry (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700160 }
161 else
162 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700163 FailedToCreatePitEntry (inFace, header, origPacket);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700164 return;
165 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700166 }
167
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700168 bool isDuplicated = true;
169 if (!pitEntry->IsNonceSeen (header->GetNonce ()))
170 {
171 pitEntry->AddSeenNonce (header->GetNonce ());
172 isDuplicated = false;
173 }
174
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800175 if (isDuplicated)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700176 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700177 DidReceiveDuplicateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700178 return;
179 }
180
181 Ptr<Packet> contentObject;
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700182 Ptr<const ContentObject> contentObjectHeader; // used for tracing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700183 Ptr<const Packet> payload; // used for tracing
184 boost::tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
185 if (contentObject != 0)
186 {
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800187 NS_ASSERT (contentObjectHeader != 0);
188
189 FwHopCountTag hopCountTag;
190 if (origPacket->PeekPacketTag (hopCountTag))
191 {
192 contentObject->AddPacketTag (hopCountTag);
193 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700194
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700195 pitEntry->AddIncoming (inFace/*, Seconds (1.0)*/);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700196
197 // Do data plane performance measurements
198 WillSatisfyPendingInterest (0, pitEntry);
199
200 // Actually satisfy pending interest
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700201 SatisfyPendingInterest (0, contentObjectHeader, payload, contentObject, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700202 return;
203 }
204
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700205 if (similarInterest && ShouldSuppressIncomingInterest (inFace, header, origPacket, pitEntry))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700206 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700207 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700208 // update PIT entry lifetime
209 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700210
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700211 // Suppress this interest if we're still expecting data from some other face
212 NS_LOG_DEBUG ("Suppress interests");
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700213 m_dropInterests (header, inFace);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700214
215 DidSuppressSimilarInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700216 return;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700217 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700218
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700219 if (similarInterest)
220 {
221 DidForwardSimilarInterest (inFace, header, origPacket, pitEntry);
222 }
223
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700224 PropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700225}
226
227void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700228ForwardingStrategy::OnData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700229 Ptr<const ContentObject> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700230 Ptr<Packet> payload)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700231{
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700232 NS_LOG_FUNCTION (inFace << header->GetName () << payload);
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700233 m_inData (header, payload, inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800234
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700235 // Lookup PIT entry
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700236 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700237 if (pitEntry == 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700238 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800239 bool cached = false;
240
Alexander Afanasyevdd9fa4f2013-05-15 16:35:04 -0700241 if (m_cacheUnsolicitedData || (m_cacheUnsolicitedDataFromApps && (inFace->GetFlags () | Face::APPLICATION)))
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800242 {
243 FwHopCountTag hopCountTag;
244
245 Ptr<Packet> payloadCopy = payload->Copy ();
246 payloadCopy->RemovePacketTag (hopCountTag);
247
248 // Optimistically add or update entry in the content store
249 cached = m_contentStore->Add (header, payloadCopy);
250 }
251 else
252 {
253 // Drop data packet if PIT entry is not found
254 // (unsolicited data packets should not "poison" content store)
255
256 //drop dulicated or not requested data packet
257 m_dropData (header, payload, inFace);
258 }
259
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700260 DidReceiveUnsolicitedData (inFace, header, payload, cached);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700261 return;
262 }
263 else
264 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800265 bool cached = false;
266
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800267 FwHopCountTag hopCountTag;
268 if (payload->PeekPacketTag (hopCountTag))
269 {
270 Ptr<Packet> payloadCopy = payload->Copy ();
271 payloadCopy->RemovePacketTag (hopCountTag);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800272
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800273 // Add or update entry in the content store
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800274 cached = m_contentStore->Add (header, payloadCopy);
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800275 }
276 else
277 {
278 // Add or update entry in the content store
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800279 cached = m_contentStore->Add (header, payload); // no need for extra copy
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800280 }
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800281
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700282 DidReceiveSolicitedData (inFace, header, payload, cached);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700283 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700284
285 while (pitEntry != 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700286 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700287 // Do data plane performance measurements
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700288 WillSatisfyPendingInterest (inFace, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700289
290 // Actually satisfy pending interest
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700291 SatisfyPendingInterest (inFace, header, payload, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700292
293 // Lookup another PIT entry
294 pitEntry = m_pit->Lookup (*header);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700295 }
296}
297
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700298void
299ForwardingStrategy::DidCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700300 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700301 Ptr<const Packet> payload,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700302 Ptr<pit::Entry> pitEntrypitEntry)
303{
304}
305
306void
307ForwardingStrategy::FailedToCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700308 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700309 Ptr<const Packet> payload)
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700310{
311 m_dropInterests (header, inFace);
312}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700313
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700314void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700315ForwardingStrategy::DidReceiveDuplicateInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700316 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700317 Ptr<const Packet> payload,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700318 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700319{
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700320 /////////////////////////////////////////////////////////////////////////////////////////
321 // //
322 // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
323 // //
324 /////////////////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700325 pitEntry->AddIncoming (inFace);
326 m_dropInterests (header, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700327}
328
329void
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700330ForwardingStrategy::DidSuppressSimilarInterest (Ptr<Face> face,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700331 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700332 Ptr<const Packet> payload,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700333 Ptr<pit::Entry> pitEntry)
334{
335}
336
337void
338ForwardingStrategy::DidForwardSimilarInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700339 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700340 Ptr<const Packet> payload,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700341 Ptr<pit::Entry> pitEntry)
342{
343}
344
345void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700346ForwardingStrategy::DidExhaustForwardingOptions (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700347 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700348 Ptr<const Packet> payload,
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700349 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700350{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700351 NS_LOG_FUNCTION (this << boost::cref (*inFace));
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800352 if (pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700353 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700354 m_dropInterests (header, inFace);
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700355
356 // All incoming interests cannot be satisfied. Remove them
357 pitEntry->ClearIncoming ();
358
359 // Remove also outgoing
360 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800361
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700362 // Set pruning timout on PIT entry (instead of deleting the record)
363 m_pit->MarkErased (pitEntry);
364 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700365}
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800366
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700367
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700368
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700369bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700370ForwardingStrategy::DetectRetransmittedInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700371 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700372 Ptr<const Packet> payload,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700373 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700374{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700375 pit::Entry::in_iterator existingInFace = pitEntry->GetIncoming ().find (inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700376
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700377 bool isRetransmitted = false;
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800378
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700379 if (existingInFace != pitEntry->GetIncoming ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700380 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700381 // this is almost definitely a retransmission. But should we trust the user on that?
382 isRetransmitted = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700383 }
384
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700385 return isRetransmitted;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700386}
387
388void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700389ForwardingStrategy::SatisfyPendingInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700390 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700391 Ptr<const Packet> payload,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700392 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700393{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700394 if (inFace != 0)
395 pitEntry->RemoveIncoming (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700396
397 //satisfy all pending incoming Interests
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700398 BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700399 {
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700400 bool ok = incoming.m_face->SendData (header, payload);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800401
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600402 DidSendOutData (inFace, incoming.m_face, header, payload, origPacket, pitEntry);
403 NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
404
405 if (!ok)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700406 {
407 m_dropData (header, payload, incoming.m_face);
408 NS_LOG_DEBUG ("Cannot satisfy data to " << *incoming.m_face);
409 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700410 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700411
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700412 // All incoming interests are satisfied. Remove them
413 pitEntry->ClearIncoming ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700414
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700415 // Remove all outgoing faces
416 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800417
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700418 // Set pruning timout on PIT entry (instead of deleting the record)
419 m_pit->MarkErased (pitEntry);
420}
421
422void
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800423ForwardingStrategy::DidReceiveSolicitedData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700424 Ptr<const ContentObject> header,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800425 Ptr<const Packet> payload,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800426 bool didCreateCacheEntry)
427{
428 // do nothing
429}
430
431void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700432ForwardingStrategy::DidReceiveUnsolicitedData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700433 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700434 Ptr<const Packet> payload,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800435 bool didCreateCacheEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700436{
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800437 // do nothing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700438}
439
440void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700441ForwardingStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
442 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700443{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700444 pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800445
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700446 // If we have sent interest for this data via this face, then update stats.
447 if (out != pitEntry->GetOutgoing ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700448 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700449 pitEntry->GetFibEntry ()->UpdateFaceRtt (inFace, Simulator::Now () - out->m_sendTime);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800450 }
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700451
452 m_satisfiedInterests (pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700453}
454
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700455bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700456ForwardingStrategy::ShouldSuppressIncomingInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700457 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700458 Ptr<const Packet> payload,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700459 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700460{
461 bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
462
463 if (isNew) return false; // never suppress new interests
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800464
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700465 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800466 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700467
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700468 if (pitEntry->GetOutgoing ().find (inFace) != pitEntry->GetOutgoing ().end ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700469 {
470 NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
471 // got a non-duplicate interest from the face we have sent interest to
472 // Probably, there is no point in waiting data from that face... Not sure yet
473
474 // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
475 // Mark interface YELLOW, but keep a small hope that data will come eventually.
476
477 // ?? not sure if we need to do that ?? ...
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800478
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700479 // pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700480 }
481 else
482 if (!isNew && !isRetransmitted)
483 {
484 return true;
485 }
486
487 return false;
488}
489
490void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700491ForwardingStrategy::PropagateInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700492 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700493 Ptr<const Packet> payload,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700494 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700495{
496 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800497 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
498
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700499 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700500 /// @todo Make lifetime per incoming interface
501 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800502
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700503 bool propagated = DoPropagateInterest (inFace, header, payload, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700504
505 if (!propagated && isRetransmitted) //give another chance if retransmitted
506 {
507 // increase max number of allowed retransmissions
508 pitEntry->IncreaseAllowedRetxCount ();
509
510 // try again
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700511 propagated = DoPropagateInterest (inFace, header, payload, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700512 }
513
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800514 // if (!propagated)
515 // {
516 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
517 // NS_LOG_DEBUG ("+++ Not propagated ["<< header->GetName () <<"], but number of outgoing faces: " << pitEntry->GetOutgoing ().size ());
518 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
519 // }
520
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700521 // ForwardingStrategy will try its best to forward packet to at least one interface.
522 // If no interests was propagated, then there is not other option for forwarding or
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800523 // ForwardingStrategy failed to find it.
524 if (!propagated && pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700525 {
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700526 DidExhaustForwardingOptions (inFace, header, payload, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700527 }
528}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700529
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700530bool
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800531ForwardingStrategy::CanSendOutInterest (Ptr<Face> inFace,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700532 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700533 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700534 Ptr<const Packet> payload,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700535 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700536{
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800537 if (outFace == inFace)
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700538 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800539 // NS_LOG_DEBUG ("Same as incoming");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700540 return false; // same face as incoming, don't forward
541 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800542
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700543 pit::Entry::out_iterator outgoing =
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700544 pitEntry->GetOutgoing ().find (outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700545
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700546 if (outgoing != pitEntry->GetOutgoing ().end ())
547 {
548 if (!m_detectRetransmissions)
549 return false; // suppress
550 else if (outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
551 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800552 // NS_LOG_DEBUG ("Already forwarded before during this retransmission cycle (" <<outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount () << ")");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700553 return false; // already forwarded before during this retransmission cycle
554 }
555 }
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800556
557 return true;
558}
559
560
561bool
562ForwardingStrategy::TrySendOutInterest (Ptr<Face> inFace,
563 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700564 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700565 Ptr<const Packet> payload,
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800566 Ptr<pit::Entry> pitEntry)
567{
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700568 if (!CanSendOutInterest (inFace, outFace, header, payload, pitEntry))
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800569 {
570 return false;
571 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800572
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700573 pitEntry->AddOutgoing (outFace);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700574
575 //transmission
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700576 bool successSend = outFace->SendInterest (header, payload);
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600577 if (!successSend)
578 {
579 m_dropInterests (header, outFace);
580 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700581
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700582 DidSendOutInterest (inFace, outFace, header, payload, pitEntry);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700583
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700584 return true;
585}
586
587void
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800588ForwardingStrategy::DidSendOutInterest (Ptr<Face> inFace,
589 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700590 Ptr<const Interest> header,
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700591 Ptr<const Packet> payload,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700592 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700593{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700594 m_outInterests (header, outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700595}
596
597void
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800598ForwardingStrategy::DidSendOutData (Ptr<Face> inFace,
599 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700600 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700601 Ptr<const Packet> payload,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700602 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700603{
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600604 m_outData (header, payload, inFace == 0, outFace);
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700605}
606
607void
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700608ForwardingStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700609{
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700610 m_timedOutInterests (pitEntry);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700611}
612
Alexander Afanasyevf5c07742012-10-31 13:13:05 -0700613void
614ForwardingStrategy::AddFace (Ptr<Face> face)
615{
616 // do nothing here
617}
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700618
619void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700620ForwardingStrategy::RemoveFace (Ptr<Face> face)
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700621{
622 // do nothing here
623}
624
Alexander Afanasyevadcccf42012-11-26 23:55:34 -0800625void
626ForwardingStrategy::DidAddFibEntry (Ptr<fib::Entry> fibEntry)
627{
628 // do nothing here
629}
630
631void
632ForwardingStrategy::WillRemoveFibEntry (Ptr<fib::Entry> fibEntry)
633{
634 // do nothing here
635}
636
637
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700638} // namespace ndn
639} // namespace ns3