blob: 6bfee78712404736e55265bf9861b1428cd2efad [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))
87
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070088 .AddAttribute ("CacheUnsolicitedData", "Cache overheard data that have not been requested",
89 BooleanValue (false),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070090 MakeBooleanAccessor (&ForwardingStrategy::m_cacheUnsolicitedData),
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070091 MakeBooleanChecker ())
92
Alexander Afanasyev996b4872012-07-17 17:07:56 -070093 .AddAttribute ("DetectRetransmissions", "If non-duplicate interest is received on the same face more than once, "
94 "it is considered a retransmission",
95 BooleanValue (true),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070096 MakeBooleanAccessor (&ForwardingStrategy::m_detectRetransmissions),
Alexander Afanasyev996b4872012-07-17 17:07:56 -070097 MakeBooleanChecker ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070098 ;
99 return tid;
100}
101
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700102ForwardingStrategy::ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700103{
104}
105
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700106ForwardingStrategy::~ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700107{
108}
109
110void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700111ForwardingStrategy::NotifyNewAggregate ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700112{
113 if (m_pit == 0)
114 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700115 m_pit = GetObject<Pit> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700116 }
117 if (m_fib == 0)
118 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700119 m_fib = GetObject<Fib> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700120 }
121 if (m_contentStore == 0)
122 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700123 m_contentStore = GetObject<ContentStore> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700124 }
125
126 Object::NotifyNewAggregate ();
127}
128
129void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700130ForwardingStrategy::DoDispose ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700131{
132 m_pit = 0;
133 m_contentStore = 0;
134 m_fib = 0;
135
136 Object::DoDispose ();
137}
138
139void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700140ForwardingStrategy::OnInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700141 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700142 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700143{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700144 m_inInterests (header, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700145
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700146 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700147 bool similarInterest = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700148 if (pitEntry == 0)
149 {
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700150 similarInterest = false;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700151 pitEntry = m_pit->Create (header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700152 if (pitEntry != 0)
153 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700154 DidCreatePitEntry (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700155 }
156 else
157 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700158 FailedToCreatePitEntry (inFace, header, origPacket);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700159 return;
160 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700161 }
162
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700163 bool isDuplicated = true;
164 if (!pitEntry->IsNonceSeen (header->GetNonce ()))
165 {
166 pitEntry->AddSeenNonce (header->GetNonce ());
167 isDuplicated = false;
168 }
169
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800170 if (isDuplicated)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700171 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700172 DidReceiveDuplicateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700173 return;
174 }
175
176 Ptr<Packet> contentObject;
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700177 Ptr<const ContentObject> contentObjectHeader; // used for tracing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700178 Ptr<const Packet> payload; // used for tracing
179 boost::tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
180 if (contentObject != 0)
181 {
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800182 NS_ASSERT (contentObjectHeader != 0);
183
184 FwHopCountTag hopCountTag;
185 if (origPacket->PeekPacketTag (hopCountTag))
186 {
187 contentObject->AddPacketTag (hopCountTag);
188 }
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 Afanasyev996b4872012-07-17 17:07:56 -0700196 SatisfyPendingInterest (0, contentObjectHeader, payload, contentObject, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700197 return;
198 }
199
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700200 if (similarInterest && ShouldSuppressIncomingInterest (inFace, header, origPacket, pitEntry))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700201 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700202 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700203 // update PIT entry lifetime
204 pitEntry->UpdateLifetime (header->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 Afanasyev31cb4692012-08-17 13:08:20 -0700208 m_dropInterests (header, inFace);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700209
210 DidSuppressSimilarInterest (inFace, header, origPacket, 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 {
216 DidForwardSimilarInterest (inFace, header, origPacket, pitEntry);
217 }
218
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700219 PropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700220}
221
222void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700223ForwardingStrategy::OnData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700224 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700225 Ptr<Packet> payload,
226 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700227{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700228 NS_LOG_FUNCTION (inFace << header->GetName () << payload << origPacket);
229 m_inData (header, payload, inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800230
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700231 // Lookup PIT entry
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700232 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700233 if (pitEntry == 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700234 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800235 bool cached = false;
236
237 if (m_cacheUnsolicitedData)
238 {
239 FwHopCountTag hopCountTag;
240
241 Ptr<Packet> payloadCopy = payload->Copy ();
242 payloadCopy->RemovePacketTag (hopCountTag);
243
244 // Optimistically add or update entry in the content store
245 cached = m_contentStore->Add (header, payloadCopy);
246 }
247 else
248 {
249 // Drop data packet if PIT entry is not found
250 // (unsolicited data packets should not "poison" content store)
251
252 //drop dulicated or not requested data packet
253 m_dropData (header, payload, inFace);
254 }
255
256 DidReceiveUnsolicitedData (inFace, header, payload, origPacket, cached);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700257 return;
258 }
259 else
260 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800261 bool cached = false;
262
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800263 FwHopCountTag hopCountTag;
264 if (payload->PeekPacketTag (hopCountTag))
265 {
266 Ptr<Packet> payloadCopy = payload->Copy ();
267 payloadCopy->RemovePacketTag (hopCountTag);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800268
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800269 // Add or update entry in the content store
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800270 cached = m_contentStore->Add (header, payloadCopy);
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800271 }
272 else
273 {
274 // Add or update entry in the content store
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800275 cached = m_contentStore->Add (header, payload); // no need for extra copy
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800276 }
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800277
278 DidReceiveSolicitedData (inFace, header, payload, origPacket, cached);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700279 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700280
281 while (pitEntry != 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700282 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700283 // Do data plane performance measurements
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700284 WillSatisfyPendingInterest (inFace, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700285
286 // Actually satisfy pending interest
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700287 SatisfyPendingInterest (inFace, header, payload, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700288
289 // Lookup another PIT entry
290 pitEntry = m_pit->Lookup (*header);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700291 }
292}
293
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700294void
295ForwardingStrategy::DidCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700296 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700297 Ptr<const Packet> origPacket,
298 Ptr<pit::Entry> pitEntrypitEntry)
299{
300}
301
302void
303ForwardingStrategy::FailedToCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700304 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700305 Ptr<const Packet> origPacket)
306{
307 m_dropInterests (header, inFace);
308}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700309
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700310void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700311ForwardingStrategy::DidReceiveDuplicateInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700312 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700313 Ptr<const Packet> origPacket,
314 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700315{
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700316 /////////////////////////////////////////////////////////////////////////////////////////
317 // //
318 // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
319 // //
320 /////////////////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700321 pitEntry->AddIncoming (inFace);
322 m_dropInterests (header, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700323}
324
325void
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700326ForwardingStrategy::DidSuppressSimilarInterest (Ptr<Face> face,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700327 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700328 Ptr<const Packet> origPacket,
329 Ptr<pit::Entry> pitEntry)
330{
331}
332
333void
334ForwardingStrategy::DidForwardSimilarInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700335 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700336 Ptr<const Packet> origPacket,
337 Ptr<pit::Entry> pitEntry)
338{
339}
340
341void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700342ForwardingStrategy::DidExhaustForwardingOptions (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700343 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700344 Ptr<const Packet> origPacket,
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700345 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700346{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700347 NS_LOG_FUNCTION (this << boost::cref (*inFace));
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800348 if (pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700349 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700350 m_dropInterests (header, inFace);
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700351
352 // All incoming interests cannot be satisfied. Remove them
353 pitEntry->ClearIncoming ();
354
355 // Remove also outgoing
356 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800357
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700358 // Set pruning timout on PIT entry (instead of deleting the record)
359 m_pit->MarkErased (pitEntry);
360 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700361}
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800362
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700363
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700364
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700365bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700366ForwardingStrategy::DetectRetransmittedInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700367 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700368 Ptr<const Packet> packet,
369 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700370{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700371 pit::Entry::in_iterator existingInFace = pitEntry->GetIncoming ().find (inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700372
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700373 bool isRetransmitted = false;
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800374
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700375 if (existingInFace != pitEntry->GetIncoming ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700376 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700377 // this is almost definitely a retransmission. But should we trust the user on that?
378 isRetransmitted = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700379 }
380
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700381 return isRetransmitted;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700382}
383
384void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700385ForwardingStrategy::SatisfyPendingInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700386 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700387 Ptr<const Packet> payload,
388 Ptr<const Packet> origPacket,
389 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700390{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700391 if (inFace != 0)
392 pitEntry->RemoveIncoming (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700393
394 //satisfy all pending incoming Interests
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700395 BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700396 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700397 bool ok = incoming.m_face->Send (origPacket->Copy ());
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800398
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600399 DidSendOutData (inFace, incoming.m_face, header, payload, origPacket, pitEntry);
400 NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
401
402 if (!ok)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700403 {
404 m_dropData (header, payload, incoming.m_face);
405 NS_LOG_DEBUG ("Cannot satisfy data to " << *incoming.m_face);
406 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700407 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700408
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700409 // All incoming interests are satisfied. Remove them
410 pitEntry->ClearIncoming ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700411
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700412 // Remove all outgoing faces
413 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800414
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700415 // Set pruning timout on PIT entry (instead of deleting the record)
416 m_pit->MarkErased (pitEntry);
417}
418
419void
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800420ForwardingStrategy::DidReceiveSolicitedData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700421 Ptr<const ContentObject> header,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800422 Ptr<const Packet> payload,
423 Ptr<const Packet> origPacket,
424 bool didCreateCacheEntry)
425{
426 // do nothing
427}
428
429void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700430ForwardingStrategy::DidReceiveUnsolicitedData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700431 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700432 Ptr<const Packet> payload,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800433 Ptr<const Packet> origPacket,
434 bool didCreateCacheEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700435{
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800436 // do nothing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700437}
438
439void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700440ForwardingStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
441 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700442{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700443 pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800444
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700445 // If we have sent interest for this data via this face, then update stats.
446 if (out != pitEntry->GetOutgoing ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700447 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700448 pitEntry->GetFibEntry ()->UpdateFaceRtt (inFace, Simulator::Now () - out->m_sendTime);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800449 }
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700450
451 m_satisfiedInterests (pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700452}
453
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700454bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700455ForwardingStrategy::ShouldSuppressIncomingInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700456 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700457 Ptr<const Packet> origPacket,
458 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700459{
460 bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
461
462 if (isNew) return false; // never suppress new interests
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800463
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700464 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800465 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700466
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700467 if (pitEntry->GetOutgoing ().find (inFace) != pitEntry->GetOutgoing ().end ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700468 {
469 NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
470 // got a non-duplicate interest from the face we have sent interest to
471 // Probably, there is no point in waiting data from that face... Not sure yet
472
473 // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
474 // Mark interface YELLOW, but keep a small hope that data will come eventually.
475
476 // ?? not sure if we need to do that ?? ...
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800477
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700478 // pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700479 }
480 else
481 if (!isNew && !isRetransmitted)
482 {
483 return true;
484 }
485
486 return false;
487}
488
489void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700490ForwardingStrategy::PropagateInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700491 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700492 Ptr<const Packet> origPacket,
493 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700494{
495 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800496 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
497
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700498 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700499 /// @todo Make lifetime per incoming interface
500 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800501
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700502 bool propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700503
504 if (!propagated && isRetransmitted) //give another chance if retransmitted
505 {
506 // increase max number of allowed retransmissions
507 pitEntry->IncreaseAllowedRetxCount ();
508
509 // try again
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700510 propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700511 }
512
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800513 // if (!propagated)
514 // {
515 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
516 // NS_LOG_DEBUG ("+++ Not propagated ["<< header->GetName () <<"], but number of outgoing faces: " << pitEntry->GetOutgoing ().size ());
517 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
518 // }
519
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700520 // ForwardingStrategy will try its best to forward packet to at least one interface.
521 // If no interests was propagated, then there is not other option for forwarding or
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800522 // ForwardingStrategy failed to find it.
523 if (!propagated && pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700524 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700525 DidExhaustForwardingOptions (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700526 }
527}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700528
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700529bool
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800530ForwardingStrategy::CanSendOutInterest (Ptr<Face> inFace,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700531 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700532 Ptr<const Interest> header,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700533 Ptr<const Packet> origPacket,
534 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700535{
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800536 if (outFace == inFace)
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700537 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800538 // NS_LOG_DEBUG ("Same as incoming");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700539 return false; // same face as incoming, don't forward
540 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800541
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700542 pit::Entry::out_iterator outgoing =
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700543 pitEntry->GetOutgoing ().find (outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700544
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700545 if (outgoing != pitEntry->GetOutgoing ().end ())
546 {
547 if (!m_detectRetransmissions)
548 return false; // suppress
549 else if (outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
550 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800551 // NS_LOG_DEBUG ("Already forwarded before during this retransmission cycle (" <<outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount () << ")");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700552 return false; // already forwarded before during this retransmission cycle
553 }
554 }
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800555
556 return true;
557}
558
559
560bool
561ForwardingStrategy::TrySendOutInterest (Ptr<Face> inFace,
562 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700563 Ptr<const Interest> header,
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800564 Ptr<const Packet> origPacket,
565 Ptr<pit::Entry> pitEntry)
566{
567 if (!CanSendOutInterest (inFace, outFace, header, origPacket, pitEntry))
568 {
569 return false;
570 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800571
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700572 pitEntry->AddOutgoing (outFace);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700573
574 //transmission
575 Ptr<Packet> packetToSend = origPacket->Copy ();
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600576 bool successSend = outFace->Send (packetToSend);
577 if (!successSend)
578 {
579 m_dropInterests (header, outFace);
580 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700581
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800582 DidSendOutInterest (inFace, outFace, header, origPacket, 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 Afanasyev31cb4692012-08-17 13:08:20 -0700591 Ptr<const Packet> origPacket,
592 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,
602 Ptr<const Packet> origPacket,
603 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700604{
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600605 m_outData (header, payload, inFace == 0, outFace);
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700606}
607
608void
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700609ForwardingStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700610{
Alexander Afanasyev37b84c52013-04-26 13:38:52 -0700611 m_timedOutInterests (pitEntry);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700612}
613
Alexander Afanasyevf5c07742012-10-31 13:13:05 -0700614void
615ForwardingStrategy::AddFace (Ptr<Face> face)
616{
617 // do nothing here
618}
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700619
620void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700621ForwardingStrategy::RemoveFace (Ptr<Face> face)
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700622{
623 // do nothing here
624}
625
Alexander Afanasyevadcccf42012-11-26 23:55:34 -0800626void
627ForwardingStrategy::DidAddFibEntry (Ptr<fib::Entry> fibEntry)
628{
629 // do nothing here
630}
631
632void
633ForwardingStrategy::WillRemoveFibEntry (Ptr<fib::Entry> fibEntry)
634{
635 // do nothing here
636}
637
638
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700639} // namespace ndn
640} // namespace ns3