blob: 5b519937dcd6b8acfa9edb378f5daf5559644c33 [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 Afanasyeve3d126f2012-07-16 17:07:31 -070082 .AddAttribute ("CacheUnsolicitedData", "Cache overheard data that have not been requested",
83 BooleanValue (false),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070084 MakeBooleanAccessor (&ForwardingStrategy::m_cacheUnsolicitedData),
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070085 MakeBooleanChecker ())
86
Alexander Afanasyev996b4872012-07-17 17:07:56 -070087 .AddAttribute ("DetectRetransmissions", "If non-duplicate interest is received on the same face more than once, "
88 "it is considered a retransmission",
89 BooleanValue (true),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070090 MakeBooleanAccessor (&ForwardingStrategy::m_detectRetransmissions),
Alexander Afanasyev996b4872012-07-17 17:07:56 -070091 MakeBooleanChecker ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070092 ;
93 return tid;
94}
95
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070096ForwardingStrategy::ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070097{
98}
99
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700100ForwardingStrategy::~ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700101{
102}
103
104void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700105ForwardingStrategy::NotifyNewAggregate ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700106{
107 if (m_pit == 0)
108 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700109 m_pit = GetObject<Pit> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700110 }
111 if (m_fib == 0)
112 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700113 m_fib = GetObject<Fib> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700114 }
115 if (m_contentStore == 0)
116 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700117 m_contentStore = GetObject<ContentStore> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700118 }
119
120 Object::NotifyNewAggregate ();
121}
122
123void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700124ForwardingStrategy::DoDispose ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700125{
126 m_pit = 0;
127 m_contentStore = 0;
128 m_fib = 0;
129
130 Object::DoDispose ();
131}
132
133void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700134ForwardingStrategy::OnInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700135 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700136 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700137{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700138 m_inInterests (header, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700139
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700140 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700141 bool similarInterest = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700142 if (pitEntry == 0)
143 {
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700144 similarInterest = false;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700145 pitEntry = m_pit->Create (header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700146 if (pitEntry != 0)
147 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700148 DidCreatePitEntry (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700149 }
150 else
151 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700152 FailedToCreatePitEntry (inFace, header, origPacket);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700153 return;
154 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700155 }
156
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700157 bool isDuplicated = true;
158 if (!pitEntry->IsNonceSeen (header->GetNonce ()))
159 {
160 pitEntry->AddSeenNonce (header->GetNonce ());
161 isDuplicated = false;
162 }
163
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800164 if (isDuplicated)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700165 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700166 DidReceiveDuplicateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700167 return;
168 }
169
170 Ptr<Packet> contentObject;
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700171 Ptr<const ContentObject> contentObjectHeader; // used for tracing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700172 Ptr<const Packet> payload; // used for tracing
173 boost::tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
174 if (contentObject != 0)
175 {
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800176 NS_ASSERT (contentObjectHeader != 0);
177
178 FwHopCountTag hopCountTag;
179 if (origPacket->PeekPacketTag (hopCountTag))
180 {
181 contentObject->AddPacketTag (hopCountTag);
182 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700183
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700184 pitEntry->AddIncoming (inFace/*, Seconds (1.0)*/);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700185
186 // Do data plane performance measurements
187 WillSatisfyPendingInterest (0, pitEntry);
188
189 // Actually satisfy pending interest
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700190 SatisfyPendingInterest (0, contentObjectHeader, payload, contentObject, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700191 return;
192 }
193
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700194 if (similarInterest && ShouldSuppressIncomingInterest (inFace, header, origPacket, pitEntry))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700195 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700196 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700197 // update PIT entry lifetime
198 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700199
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700200 // Suppress this interest if we're still expecting data from some other face
201 NS_LOG_DEBUG ("Suppress interests");
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700202 m_dropInterests (header, inFace);
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700203
204 DidSuppressSimilarInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700205 return;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700206 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700207
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700208 if (similarInterest)
209 {
210 DidForwardSimilarInterest (inFace, header, origPacket, pitEntry);
211 }
212
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700213 PropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700214}
215
216void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700217ForwardingStrategy::OnData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700218 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700219 Ptr<Packet> payload,
220 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700221{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700222 NS_LOG_FUNCTION (inFace << header->GetName () << payload << origPacket);
223 m_inData (header, payload, inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800224
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700225 // Lookup PIT entry
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700226 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700227 if (pitEntry == 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700228 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800229 bool cached = false;
230
231 if (m_cacheUnsolicitedData)
232 {
233 FwHopCountTag hopCountTag;
234
235 Ptr<Packet> payloadCopy = payload->Copy ();
236 payloadCopy->RemovePacketTag (hopCountTag);
237
238 // Optimistically add or update entry in the content store
239 cached = m_contentStore->Add (header, payloadCopy);
240 }
241 else
242 {
243 // Drop data packet if PIT entry is not found
244 // (unsolicited data packets should not "poison" content store)
245
246 //drop dulicated or not requested data packet
247 m_dropData (header, payload, inFace);
248 }
249
250 DidReceiveUnsolicitedData (inFace, header, payload, origPacket, cached);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700251 return;
252 }
253 else
254 {
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800255 bool cached = false;
256
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800257 FwHopCountTag hopCountTag;
258 if (payload->PeekPacketTag (hopCountTag))
259 {
260 Ptr<Packet> payloadCopy = payload->Copy ();
261 payloadCopy->RemovePacketTag (hopCountTag);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800262
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800263 // Add or update entry in the content store
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800264 cached = m_contentStore->Add (header, payloadCopy);
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800265 }
266 else
267 {
268 // Add or update entry in the content store
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800269 cached = m_contentStore->Add (header, payload); // no need for extra copy
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800270 }
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800271
272 DidReceiveSolicitedData (inFace, header, payload, origPacket, cached);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700273 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700274
275 while (pitEntry != 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700276 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700277 // Do data plane performance measurements
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700278 WillSatisfyPendingInterest (inFace, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700279
280 // Actually satisfy pending interest
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700281 SatisfyPendingInterest (inFace, header, payload, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700282
283 // Lookup another PIT entry
284 pitEntry = m_pit->Lookup (*header);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700285 }
286}
287
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700288void
289ForwardingStrategy::DidCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700290 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700291 Ptr<const Packet> origPacket,
292 Ptr<pit::Entry> pitEntrypitEntry)
293{
294}
295
296void
297ForwardingStrategy::FailedToCreatePitEntry (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700298 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700299 Ptr<const Packet> origPacket)
300{
301 m_dropInterests (header, inFace);
302}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700303
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700304void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700305ForwardingStrategy::DidReceiveDuplicateInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700306 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700307 Ptr<const Packet> origPacket,
308 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700309{
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700310 /////////////////////////////////////////////////////////////////////////////////////////
311 // //
312 // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
313 // //
314 /////////////////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700315 pitEntry->AddIncoming (inFace);
316 m_dropInterests (header, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700317}
318
319void
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700320ForwardingStrategy::DidSuppressSimilarInterest (Ptr<Face> face,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700321 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700322 Ptr<const Packet> origPacket,
323 Ptr<pit::Entry> pitEntry)
324{
325}
326
327void
328ForwardingStrategy::DidForwardSimilarInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700329 Ptr<const Interest> header,
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700330 Ptr<const Packet> origPacket,
331 Ptr<pit::Entry> pitEntry)
332{
333}
334
335void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700336ForwardingStrategy::DidExhaustForwardingOptions (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700337 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700338 Ptr<const Packet> origPacket,
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700339 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700340{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700341 NS_LOG_FUNCTION (this << boost::cref (*inFace));
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800342 if (pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700343 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700344 m_dropInterests (header, inFace);
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700345
346 // All incoming interests cannot be satisfied. Remove them
347 pitEntry->ClearIncoming ();
348
349 // Remove also outgoing
350 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800351
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700352 // Set pruning timout on PIT entry (instead of deleting the record)
353 m_pit->MarkErased (pitEntry);
354 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700355}
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800356
Alexander Afanasyev6466fff2012-10-24 22:51:57 -0700357
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700358
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700359bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700360ForwardingStrategy::DetectRetransmittedInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700361 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700362 Ptr<const Packet> packet,
363 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700364{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700365 pit::Entry::in_iterator existingInFace = pitEntry->GetIncoming ().find (inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700366
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700367 bool isRetransmitted = false;
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800368
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700369 if (existingInFace != pitEntry->GetIncoming ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700370 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700371 // this is almost definitely a retransmission. But should we trust the user on that?
372 isRetransmitted = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700373 }
374
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700375 return isRetransmitted;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700376}
377
378void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700379ForwardingStrategy::SatisfyPendingInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700380 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700381 Ptr<const Packet> payload,
382 Ptr<const Packet> origPacket,
383 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700384{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700385 if (inFace != 0)
386 pitEntry->RemoveIncoming (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700387
388 //satisfy all pending incoming Interests
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700389 BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700390 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700391 bool ok = incoming.m_face->Send (origPacket->Copy ());
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800392
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600393 DidSendOutData (inFace, incoming.m_face, header, payload, origPacket, pitEntry);
394 NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
395
396 if (!ok)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700397 {
398 m_dropData (header, payload, incoming.m_face);
399 NS_LOG_DEBUG ("Cannot satisfy data to " << *incoming.m_face);
400 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700401 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700402
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700403 // All incoming interests are satisfied. Remove them
404 pitEntry->ClearIncoming ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700405
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700406 // Remove all outgoing faces
407 pitEntry->ClearOutgoing ();
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800408
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700409 // Set pruning timout on PIT entry (instead of deleting the record)
410 m_pit->MarkErased (pitEntry);
411}
412
413void
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800414ForwardingStrategy::DidReceiveSolicitedData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700415 Ptr<const ContentObject> header,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800416 Ptr<const Packet> payload,
417 Ptr<const Packet> origPacket,
418 bool didCreateCacheEntry)
419{
420 // do nothing
421}
422
423void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700424ForwardingStrategy::DidReceiveUnsolicitedData (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700425 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700426 Ptr<const Packet> payload,
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800427 Ptr<const Packet> origPacket,
428 bool didCreateCacheEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700429{
Alexander Afanasyeve6c07b52013-02-12 11:05:14 -0800430 // do nothing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700431}
432
433void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700434ForwardingStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
435 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700436{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700437 pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (inFace);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800438
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700439 // If we have sent interest for this data via this face, then update stats.
440 if (out != pitEntry->GetOutgoing ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700441 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700442 pitEntry->GetFibEntry ()->UpdateFaceRtt (inFace, Simulator::Now () - out->m_sendTime);
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800443 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700444}
445
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700446bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700447ForwardingStrategy::ShouldSuppressIncomingInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700448 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700449 Ptr<const Packet> origPacket,
450 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700451{
452 bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
453
454 if (isNew) return false; // never suppress new interests
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800455
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700456 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800457 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700458
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700459 if (pitEntry->GetOutgoing ().find (inFace) != pitEntry->GetOutgoing ().end ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700460 {
461 NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
462 // got a non-duplicate interest from the face we have sent interest to
463 // Probably, there is no point in waiting data from that face... Not sure yet
464
465 // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
466 // Mark interface YELLOW, but keep a small hope that data will come eventually.
467
468 // ?? not sure if we need to do that ?? ...
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800469
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700470 // pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700471 }
472 else
473 if (!isNew && !isRetransmitted)
474 {
475 return true;
476 }
477
478 return false;
479}
480
481void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700482ForwardingStrategy::PropagateInterest (Ptr<Face> inFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700483 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700484 Ptr<const Packet> origPacket,
485 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700486{
487 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800488 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
489
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700490 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700491 /// @todo Make lifetime per incoming interface
492 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800493
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700494 bool propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700495
496 if (!propagated && isRetransmitted) //give another chance if retransmitted
497 {
498 // increase max number of allowed retransmissions
499 pitEntry->IncreaseAllowedRetxCount ();
500
501 // try again
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700502 propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700503 }
504
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800505 // if (!propagated)
506 // {
507 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
508 // NS_LOG_DEBUG ("+++ Not propagated ["<< header->GetName () <<"], but number of outgoing faces: " << pitEntry->GetOutgoing ().size ());
509 // NS_LOG_DEBUG ("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
510 // }
511
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700512 // ForwardingStrategy will try its best to forward packet to at least one interface.
513 // If no interests was propagated, then there is not other option for forwarding or
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800514 // ForwardingStrategy failed to find it.
515 if (!propagated && pitEntry->AreAllOutgoingInVain ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700516 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700517 DidExhaustForwardingOptions (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700518 }
519}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700520
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700521bool
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800522ForwardingStrategy::CanSendOutInterest (Ptr<Face> inFace,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700523 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700524 Ptr<const Interest> header,
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700525 Ptr<const Packet> origPacket,
526 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700527{
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800528 if (outFace == inFace)
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700529 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800530 // NS_LOG_DEBUG ("Same as incoming");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700531 return false; // same face as incoming, don't forward
532 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800533
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700534 pit::Entry::out_iterator outgoing =
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700535 pitEntry->GetOutgoing ().find (outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700536
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700537 if (outgoing != pitEntry->GetOutgoing ().end ())
538 {
539 if (!m_detectRetransmissions)
540 return false; // suppress
541 else if (outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
542 {
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800543 // NS_LOG_DEBUG ("Already forwarded before during this retransmission cycle (" <<outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount () << ")");
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700544 return false; // already forwarded before during this retransmission cycle
545 }
546 }
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800547
548 return true;
549}
550
551
552bool
553ForwardingStrategy::TrySendOutInterest (Ptr<Face> inFace,
554 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700555 Ptr<const Interest> header,
Alexander Afanasyevdb15acb2012-11-09 14:16:27 -0800556 Ptr<const Packet> origPacket,
557 Ptr<pit::Entry> pitEntry)
558{
559 if (!CanSendOutInterest (inFace, outFace, header, origPacket, pitEntry))
560 {
561 return false;
562 }
Alexander Afanasyev3a3ce1a2013-01-31 11:26:11 -0800563
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700564 pitEntry->AddOutgoing (outFace);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700565
566 //transmission
567 Ptr<Packet> packetToSend = origPacket->Copy ();
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600568 bool successSend = outFace->Send (packetToSend);
569 if (!successSend)
570 {
571 m_dropInterests (header, outFace);
572 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700573
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800574 DidSendOutInterest (inFace, outFace, header, origPacket, pitEntry);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700575
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700576 return true;
577}
578
579void
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800580ForwardingStrategy::DidSendOutInterest (Ptr<Face> inFace,
581 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700582 Ptr<const Interest> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700583 Ptr<const Packet> origPacket,
584 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700585{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700586 m_outInterests (header, outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700587}
588
589void
Alexander Afanasyev67f4a4a2012-11-24 17:18:17 -0800590ForwardingStrategy::DidSendOutData (Ptr<Face> inFace,
591 Ptr<Face> outFace,
Alexander Afanasyeveae83ee2013-03-15 15:01:10 -0700592 Ptr<const ContentObject> header,
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700593 Ptr<const Packet> payload,
594 Ptr<const Packet> origPacket,
595 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700596{
Alexander Afanasyevd0887982013-03-18 11:47:58 -0600597 m_outData (header, payload, inFace == 0, outFace);
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700598}
599
600void
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700601ForwardingStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700602{
603 // do nothing for now. may be need to do some logging
604}
605
Alexander Afanasyevf5c07742012-10-31 13:13:05 -0700606void
607ForwardingStrategy::AddFace (Ptr<Face> face)
608{
609 // do nothing here
610}
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700611
612void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700613ForwardingStrategy::RemoveFace (Ptr<Face> face)
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700614{
615 // do nothing here
616}
617
Alexander Afanasyevadcccf42012-11-26 23:55:34 -0800618void
619ForwardingStrategy::DidAddFibEntry (Ptr<fib::Entry> fibEntry)
620{
621 // do nothing here
622}
623
624void
625ForwardingStrategy::WillRemoveFibEntry (Ptr<fib::Entry> fibEntry)
626{
627 // do nothing here
628}
629
630
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700631} // namespace ndn
632} // namespace ns3