blob: ef61593cbcd7dfe39a812bbf16260b4c20c3fa0a [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 Afanasyevb989b122013-07-10 17:15:46 -0700146 Ptr<Interest> interest)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700147{
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700148 m_inInterests (interest, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700149
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700150 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*interest);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700151 bool similarInterest = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700152 if (pitEntry == 0)
153 {
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700154 similarInterest = false;
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700155 pitEntry = m_pit->Create (interest);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700156 if (pitEntry != 0)
157 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700158 DidCreatePitEntry (inFace, interest, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700159 }
160 else
161 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700162 FailedToCreatePitEntry (inFace, interest);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700163 return;
164 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700165 }
166
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700167 bool isDuplicated = true;
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700168 if (!pitEntry->IsNonceSeen (interest->GetNonce ()))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700169 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700170 pitEntry->AddSeenNonce (interest->GetNonce ());
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700171 isDuplicated = false;
172 }
173
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800174 if (isDuplicated)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700175 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700176 DidReceiveDuplicateInterest (inFace, interest, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700177 return;
178 }
179
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700180 Ptr<ContentObject> contentObject;
181 contentObject = m_contentStore->Lookup (interest);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700182 if (contentObject != 0)
183 {
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800184 FwHopCountTag hopCountTag;
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700185 if (interest->GetPayload ()->PeekPacketTag (hopCountTag))
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800186 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700187 contentObject->GetPayload ()->AddPacketTag (hopCountTag);
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800188 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700189
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700190 pitEntry->AddIncoming (inFace/*, Seconds (1.0)*/);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700191
192 // Do data plane performance measurements
193 WillSatisfyPendingInterest (0, pitEntry);
194
195 // Actually satisfy pending interest
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700196 SatisfyPendingInterest (0, contentObject, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700197 return;
198 }
199
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700200 if (similarInterest && ShouldSuppressIncomingInterest (inFace, interest, pitEntry))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700201 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700202 pitEntry->AddIncoming (inFace/*, interest->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700203 // update PIT entry lifetime
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700204 pitEntry->UpdateLifetime (interest->GetInterestLifetime ());
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700205
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700206 // Suppress this interest if we're still expecting data from some other face
207 NS_LOG_DEBUG ("Suppress interests");
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700208 m_dropInterests (interest, inFace);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700209
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700210 DidSuppressSimilarInterest (inFace, interest, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700211 return;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700212 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700213
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700214 if (similarInterest)
215 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700216 DidForwardSimilarInterest (inFace, interest, pitEntry);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700217 }
218
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700219 PropagateInterest (inFace, interest, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700220}
221
222void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700223ForwardingStrategy::OnData (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700224 Ptr<ContentObject> data)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700225{
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700226 NS_LOG_FUNCTION (inFace << data->GetName ());
227 m_inData (data, inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800228
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700229 // Lookup PIT entry
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700230 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*data);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700231 if (pitEntry == 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700232 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800233 bool cached = false;
234
Alexander Afanasyevdd9fa4f2013-05-15 16:35:04 -0700235 if (m_cacheUnsolicitedData || (m_cacheUnsolicitedDataFromApps && (inFace->GetFlags () | Face::APPLICATION)))
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800236 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800237 // Optimistically add or update entry in the content store
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700238 cached = m_contentStore->Add (data);
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800239 }
240 else
241 {
242 // Drop data packet if PIT entry is not found
243 // (unsolicited data packets should not "poison" content store)
244
245 //drop dulicated or not requested data packet
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700246 m_dropData (data, inFace);
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800247 }
248
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700249 DidReceiveUnsolicitedData (inFace, data, cached);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700250 return;
251 }
252 else
253 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700254 bool cached = m_contentStore->Add (data);
255 DidReceiveSolicitedData (inFace, data, cached);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700256 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700257
258 while (pitEntry != 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700259 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700260 // Do data plane performance measurements
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700261 WillSatisfyPendingInterest (inFace, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700262
263 // Actually satisfy pending interest
Alexander Afanasyev5bee19e2013-07-10 14:33:57 -0700264 SatisfyPendingInterest (inFace, header, payload, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700265
266 // Lookup another PIT entry
267 pitEntry = m_pit->Lookup (*header);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700268 }
269}
270
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700271void
272ForwardingStrategy::DidCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700273 Ptr<const Interest> interest,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700274 Ptr<pit::Entry> pitEntrypitEntry)
275{
276}
277
278void
279ForwardingStrategy::FailedToCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700280 Ptr<const Interest> interest)
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700281{
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700282 m_dropInterests (interest, inFace);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700283}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700284
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700285void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700286ForwardingStrategy::DidReceiveDuplicateInterest (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700287 Ptr<const Interest> interest,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700288 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700289{
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700290 /////////////////////////////////////////////////////////////////////////////////////////
291 // //
292 // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
293 // //
294 /////////////////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700295 pitEntry->AddIncoming (inFace);
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700296 m_dropInterests (interest, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700297}
298
299void
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700300ForwardingStrategy::DidSuppressSimilarInterest (Ptr<Face> face,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700301 Ptr<const Interest> interest,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700302 Ptr<pit::Entry> pitEntry)
303{
304}
305
306void
307ForwardingStrategy::DidForwardSimilarInterest (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700308 Ptr<const Interest> interest,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700309 Ptr<pit::Entry> pitEntry)
310{
311}
312
313void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700314ForwardingStrategy::DidExhaustForwardingOptions (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700315 Ptr<const Interest> interest,
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700316 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700317{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700318 NS_LOG_FUNCTION (this << boost::cref (*inFace));
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800319 if (pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700320 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700321 m_dropInterests (interest, inFace);
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700322
323 // All incoming interests cannot be satisfied. Remove them
324 pitEntry->ClearIncoming ();
325
326 // Remove also outgoing
327 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800328
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700329 // Set pruning timout on PIT entry (instead of deleting the record)
330 m_pit->MarkErased (pitEntry);
331 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700332}
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800333
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700334
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700335
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700336bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700337ForwardingStrategy::DetectRetransmittedInterest (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700338 Ptr<const Interest> interest,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700339 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700340{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700341 pit::Entry::in_iterator existingInFace = pitEntry->GetIncoming ().find (inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700342
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700343 bool isRetransmitted = false;
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800344
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700345 if (existingInFace != pitEntry->GetIncoming ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700346 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700347 // this is almost definitely a retransmission. But should we trust the user on that?
348 isRetransmitted = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700349 }
350
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700351 return isRetransmitted;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700352}
353
354void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700355ForwardingStrategy::SatisfyPendingInterest (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700356 Ptr<const ContentObject> data,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700357 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700358{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700359 if (inFace != 0)
360 pitEntry->RemoveIncoming (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700361
362 //satisfy all pending incoming Interests
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700363 BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700364 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700365 bool ok = incoming.m_face->SendData (data);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800366
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700367 DidSendOutData (inFace, incoming.m_face, data, pitEntry);
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600368 NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
369
370 if (!ok)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700371 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700372 m_dropData (data, incoming.m_face);
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700373 NS_LOG_DEBUG ("Cannot satisfy data to " << *incoming.m_face);
374 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700375 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700376
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700377 // All incoming interests are satisfied. Remove them
378 pitEntry->ClearIncoming ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700379
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700380 // Remove all outgoing faces
381 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800382
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700383 // Set pruning timout on PIT entry (instead of deleting the record)
384 m_pit->MarkErased (pitEntry);
385}
386
387void
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800388ForwardingStrategy::DidReceiveSolicitedData (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700389 Ptr<const ContentObject> data,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800390 bool didCreateCacheEntry)
391{
392 // do nothing
393}
394
395void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700396ForwardingStrategy::DidReceiveUnsolicitedData (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700397 Ptr<const ContentObject> data,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800398 bool didCreateCacheEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700399{
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800400 // do nothing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700401}
402
403void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700404ForwardingStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
405 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700406{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700407 pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800408
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700409 // If we have sent interest for this data via this face, then update stats.
410 if (out != pitEntry->GetOutgoing ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700411 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700412 pitEntry->GetFibEntry ()->UpdateFaceRtt (inFace, Simulator::Now () - out->m_sendTime);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800413 }
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700414
415 m_satisfiedInterests (pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700416}
417
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700418bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700419ForwardingStrategy::ShouldSuppressIncomingInterest (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700420 Ptr<const Interest> interest,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700421 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700422{
423 bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
424
425 if (isNew) return false; // never suppress new interests
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800426
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700427 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700428 DetectRetransmittedInterest (inFace, interest, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700429
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700430 if (pitEntry->GetOutgoing ().find (inFace) != pitEntry->GetOutgoing ().end ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700431 {
432 NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
433 // got a non-duplicate interest from the face we have sent interest to
434 // Probably, there is no point in waiting data from that face... Not sure yet
435
436 // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
437 // Mark interface YELLOW, but keep a small hope that data will come eventually.
438
439 // ?? not sure if we need to do that ?? ...
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800440
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700441 // pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700442 }
443 else
444 if (!isNew && !isRetransmitted)
445 {
446 return true;
447 }
448
449 return false;
450}
451
452void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700453ForwardingStrategy::PropagateInterest (Ptr<Face> inFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700454 Ptr<const Interest> interest,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700455 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700456{
457 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700458 DetectRetransmittedInterest (inFace, interest, pitEntry);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800459
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700460 pitEntry->AddIncoming (inFace/*, interest->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700461 /// @todo Make lifetime per incoming interface
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700462 pitEntry->UpdateLifetime (interest->GetInterestLifetime ());
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800463
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700464 bool propagated = DoPropagateInterest (inFace, interest, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700465
466 if (!propagated && isRetransmitted) //give another chance if retransmitted
467 {
468 // increase max number of allowed retransmissions
469 pitEntry->IncreaseAllowedRetxCount ();
470
471 // try again
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700472 propagated = DoPropagateInterest (inFace, interest, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700473 }
474
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800475 // if (!propagated)
476 // {
477 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700478 // NS_LOG_DEBUG ("+++ Not propagated ["<< interest->GetName () <<"], but number of outgoing faces: " << pitEntry->GetOutgoing ().size ());
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800479 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
480 // }
481
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700482 // ForwardingStrategy will try its best to forward packet to at least one interface.
483 // If no interests was propagated, then there is not other option for forwarding or
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800484 // ForwardingStrategy failed to find it.
485 if (!propagated && pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700486 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700487 DidExhaustForwardingOptions (inFace, interest, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700488 }
489}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700490
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700491bool
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800492ForwardingStrategy::CanSendOutInterest (Ptr<Face> inFace,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700493 Ptr<Face> outFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700494 Ptr<const Interest> interest,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700495 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700496{
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800497 if (outFace == inFace)
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700498 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800499 // NS_LOG_DEBUG ("Same as incoming");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700500 return false; // same face as incoming, don't forward
501 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800502
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700503 pit::Entry::out_iterator outgoing =
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700504 pitEntry->GetOutgoing ().find (outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700505
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700506 if (outgoing != pitEntry->GetOutgoing ().end ())
507 {
508 if (!m_detectRetransmissions)
509 return false; // suppress
510 else if (outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
511 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800512 // NS_LOG_DEBUG ("Already forwarded before during this retransmission cycle (" <<outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount () << ")");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700513 return false; // already forwarded before during this retransmission cycle
514 }
515 }
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800516
517 return true;
518}
519
520
521bool
522ForwardingStrategy::TrySendOutInterest (Ptr<Face> inFace,
523 Ptr<Face> outFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700524 Ptr<const Interest> interest,
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800525 Ptr<pit::Entry> pitEntry)
526{
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700527 if (!CanSendOutInterest (inFace, outFace, interest, pitEntry))
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800528 {
529 return false;
530 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800531
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700532 pitEntry->AddOutgoing (outFace);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700533
534 //transmission
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700535 bool successSend = outFace->SendInterest (interest);
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600536 if (!successSend)
537 {
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700538 m_dropInterests (interest, outFace);
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600539 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700540
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700541 DidSendOutInterest (inFace, outFace, interest, pitEntry);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700542
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700543 return true;
544}
545
546void
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800547ForwardingStrategy::DidSendOutInterest (Ptr<Face> inFace,
548 Ptr<Face> outFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700549 Ptr<const Interest> interest,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700550 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700551{
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700552 m_outInterests (interest, outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700553}
554
555void
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800556ForwardingStrategy::DidSendOutData (Ptr<Face> inFace,
557 Ptr<Face> outFace,
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700558 Ptr<const ContentObject> data,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700559 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700560{
Alexander Afanasyevb989b122013-07-10 17:15:46 -0700561 m_outData (data, inFace == 0, outFace);
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700562}
563
564void
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700565ForwardingStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700566{
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700567 m_timedOutInterests (pitEntry);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700568}
569
Alexander Afanasyevf5c07742012-10-31 13:13:05 -0700570void
571ForwardingStrategy::AddFace (Ptr<Face> face)
572{
573 // do nothing here
574}
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700575
576void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700577ForwardingStrategy::RemoveFace (Ptr<Face> face)
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700578{
579 // do nothing here
580}
581
Alexander Afanasyevadcccf42012-11-26 23:55:34 -0800582void
583ForwardingStrategy::DidAddFibEntry (Ptr<fib::Entry> fibEntry)
584{
585 // do nothing here
586}
587
588void
589ForwardingStrategy::WillRemoveFibEntry (Ptr<fib::Entry> fibEntry)
590{
591 // do nothing here
592}
593
594
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700595} // namespace ndn
596} // namespace ns3