blob: 4219deb9cecbf001afd7466d690dd4bbe4f95d08 [file] [log] [blame]
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 * Ilya Moiseenko <iliamo@cs.ucla.edu>
20 */
21
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070022#include "ndn-forwarding-strategy.h"
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070023
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070024#include "ns3/ndn-pit.h"
25#include "ns3/ndn-pit-entry.h"
26#include "ns3/ndn-interest-header.h"
27#include "ns3/ndn-content-object-header.h"
28#include "ns3/ndn-pit.h"
29#include "ns3/ndn-fib.h"
30#include "ns3/ndn-content-store.h"
31#include "ns3/ndn-face.h"
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070032
33#include "ns3/assert.h"
34#include "ns3/ptr.h"
35#include "ns3/log.h"
36#include "ns3/simulator.h"
37#include "ns3/boolean.h"
38#include "ns3/string.h"
39
40#include <boost/ref.hpp>
41#include <boost/foreach.hpp>
42#include <boost/lambda/lambda.hpp>
43#include <boost/lambda/bind.hpp>
44#include <boost/tuple/tuple.hpp>
45namespace ll = boost::lambda;
46
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070047NS_LOG_COMPONENT_DEFINE ("ndn.ForwardingStrategy");
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070048
49namespace 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 Afanasyev2b4c9472012-08-09 15:00:38 -070054TypeId ForwardingStrategy::GetTypeId (void)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070055{
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070056 static TypeId tid = TypeId ("ns3::ndn::ForwardingStrategy")
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070057 .SetGroupName ("Ndn")
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070058 .SetParent<Object> ()
59
60 ////////////////////////////////////////////////////////////////////
61 ////////////////////////////////////////////////////////////////////
62
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070063 .AddTraceSource ("OutInterests", "OutInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_outInterests))
64 .AddTraceSource ("InInterests", "InInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_inInterests))
65 .AddTraceSource ("DropInterests", "DropInterests", MakeTraceSourceAccessor (&ForwardingStrategy::m_dropInterests))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070066
67 ////////////////////////////////////////////////////////////////////
68 ////////////////////////////////////////////////////////////////////
69
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070070 .AddTraceSource ("OutData", "OutData", MakeTraceSourceAccessor (&ForwardingStrategy::m_outData))
71 .AddTraceSource ("InData", "InData", MakeTraceSourceAccessor (&ForwardingStrategy::m_inData))
72 .AddTraceSource ("DropData", "DropData", MakeTraceSourceAccessor (&ForwardingStrategy::m_dropData))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070073
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070074 .AddAttribute ("CacheUnsolicitedData", "Cache overheard data that have not been requested",
75 BooleanValue (false),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070076 MakeBooleanAccessor (&ForwardingStrategy::m_cacheUnsolicitedData),
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070077 MakeBooleanChecker ())
78
Alexander Afanasyev996b4872012-07-17 17:07:56 -070079 .AddAttribute ("DetectRetransmissions", "If non-duplicate interest is received on the same face more than once, "
80 "it is considered a retransmission",
81 BooleanValue (true),
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070082 MakeBooleanAccessor (&ForwardingStrategy::m_detectRetransmissions),
Alexander Afanasyev996b4872012-07-17 17:07:56 -070083 MakeBooleanChecker ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070084 ;
85 return tid;
86}
87
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070088ForwardingStrategy::ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070089{
90}
91
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070092ForwardingStrategy::~ForwardingStrategy ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070093{
94}
95
96void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070097ForwardingStrategy::NotifyNewAggregate ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070098{
99 if (m_pit == 0)
100 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700101 m_pit = GetObject<Pit> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700102 }
103 if (m_fib == 0)
104 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700105 m_fib = GetObject<Fib> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700106 }
107 if (m_contentStore == 0)
108 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700109 m_contentStore = GetObject<ContentStore> ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700110 }
111
112 Object::NotifyNewAggregate ();
113}
114
115void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700116ForwardingStrategy::DoDispose ()
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700117{
118 m_pit = 0;
119 m_contentStore = 0;
120 m_fib = 0;
121
122 Object::DoDispose ();
123}
124
125void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700126ForwardingStrategy::OnInterest (Ptr<Face> inFace,
127 Ptr<const InterestHeader> header,
128 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700129{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700130 m_inInterests (header, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700131
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700132 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700133 if (pitEntry == 0)
134 {
135 pitEntry = m_pit->Create (header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700136 if (pitEntry != 0)
137 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700138 DidCreatePitEntry (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700139 }
140 else
141 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700142 FailedToCreatePitEntry (inFace, header, origPacket);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700143 return;
144 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700145 }
146
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700147 bool isDuplicated = true;
148 if (!pitEntry->IsNonceSeen (header->GetNonce ()))
149 {
150 pitEntry->AddSeenNonce (header->GetNonce ());
151 isDuplicated = false;
152 }
153
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700154 if (isDuplicated)
155 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700156 DidReceiveDuplicateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700157 return;
158 }
159
160 Ptr<Packet> contentObject;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700161 Ptr<const ContentObjectHeader> contentObjectHeader; // used for tracing
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700162 Ptr<const Packet> payload; // used for tracing
163 boost::tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
164 if (contentObject != 0)
165 {
166 NS_ASSERT (contentObjectHeader != 0);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700167
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700168 pitEntry->AddIncoming (inFace/*, Seconds (1.0)*/);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700169
170 // Do data plane performance measurements
171 WillSatisfyPendingInterest (0, pitEntry);
172
173 // Actually satisfy pending interest
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700174 SatisfyPendingInterest (0, contentObjectHeader, payload, contentObject, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700175 return;
176 }
177
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700178 if (ShouldSuppressIncomingInterest (inFace, header, origPacket, pitEntry))
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700179 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700180 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700181 // update PIT entry lifetime
182 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700183
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700184 // Suppress this interest if we're still expecting data from some other face
185 NS_LOG_DEBUG ("Suppress interests");
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700186 m_dropInterests (header, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700187 return;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700188 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700189
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700190 PropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700191}
192
193void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700194ForwardingStrategy::OnData (Ptr<Face> inFace,
195 Ptr<const ContentObjectHeader> header,
196 Ptr<Packet> payload,
197 Ptr<const Packet> origPacket)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700198{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700199 NS_LOG_FUNCTION (inFace << header->GetName () << payload << origPacket);
200 m_inData (header, payload, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700201
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700202 // Lookup PIT entry
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700203 Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700204 if (pitEntry == 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700205 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700206 DidReceiveUnsolicitedData (inFace, header, payload, origPacket);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700207 return;
208 }
209 else
210 {
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700211 // Add or update entry in the content store
212 m_contentStore->Add (header, payload);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700213 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700214
215 while (pitEntry != 0)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700216 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700217 // Do data plane performance measurements
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700218 WillSatisfyPendingInterest (inFace, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700219
220 // Actually satisfy pending interest
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700221 SatisfyPendingInterest (inFace, header, payload, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700222
223 // Lookup another PIT entry
224 pitEntry = m_pit->Lookup (*header);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700225 }
226}
227
228
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700229void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700230ForwardingStrategy::DidReceiveDuplicateInterest (Ptr<Face> inFace,
231 Ptr<const InterestHeader> header,
232 Ptr<const Packet> origPacket,
233 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700234{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700235 NS_LOG_FUNCTION (this << boost::cref (*inFace));
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700236 /////////////////////////////////////////////////////////////////////////////////////////
237 // //
238 // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
239 // //
240 /////////////////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700241 pitEntry->AddIncoming (inFace);
242 m_dropInterests (header, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700243}
244
245void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700246ForwardingStrategy::DidExhaustForwardingOptions (Ptr<Face> inFace,
247 Ptr<const InterestHeader> header,
248 Ptr<const Packet> origPacket,
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700249 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700250{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700251 NS_LOG_FUNCTION (this << boost::cref (*inFace));
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700252 if (pitEntry->GetOutgoing ().size () == 0)
253 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700254 m_dropInterests (header, inFace);
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700255
256 // All incoming interests cannot be satisfied. Remove them
257 pitEntry->ClearIncoming ();
258
259 // Remove also outgoing
260 pitEntry->ClearOutgoing ();
261
262 // Set pruning timout on PIT entry (instead of deleting the record)
263 m_pit->MarkErased (pitEntry);
264 }
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700265}
266
267void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700268ForwardingStrategy::FailedToCreatePitEntry (Ptr<Face> inFace,
269 Ptr<const InterestHeader> header,
270 Ptr<const Packet> origPacket)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700271{
272 NS_LOG_FUNCTION (this);
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700273 m_dropInterests (header, inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700274}
275
276void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700277ForwardingStrategy::DidCreatePitEntry (Ptr<Face> inFace,
278 Ptr<const InterestHeader> header,
279 Ptr<const Packet> origPacket,
280 Ptr<pit::Entry> pitEntrypitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700281{
282}
283
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700284bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700285ForwardingStrategy::DetectRetransmittedInterest (Ptr<Face> inFace,
286 Ptr<const InterestHeader> header,
287 Ptr<const Packet> packet,
288 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700289{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700290 pit::Entry::in_iterator existingInFace = pitEntry->GetIncoming ().find (inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700291
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700292 bool isRetransmitted = false;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700293
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700294 if (existingInFace != pitEntry->GetIncoming ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700295 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700296 // this is almost definitely a retransmission. But should we trust the user on that?
297 isRetransmitted = true;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700298 }
299
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700300 return isRetransmitted;
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700301}
302
303void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700304ForwardingStrategy::SatisfyPendingInterest (Ptr<Face> inFace,
305 Ptr<const ContentObjectHeader> header,
306 Ptr<const Packet> payload,
307 Ptr<const Packet> origPacket,
308 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700309{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700310 if (inFace != 0)
311 pitEntry->RemoveIncoming (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700312
313 //satisfy all pending incoming Interests
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700314 BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700315 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700316 bool ok = incoming.m_face->Send (origPacket->Copy ());
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700317 if (ok)
318 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700319 m_outData (header, payload, inFace == 0, incoming.m_face);
320 DidSendOutData (incoming.m_face, header, payload, origPacket, pitEntry);
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700321
322 NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
323 }
324 else
325 {
326 m_dropData (header, payload, incoming.m_face);
327 NS_LOG_DEBUG ("Cannot satisfy data to " << *incoming.m_face);
328 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700329
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700330 // successfull forwarded data trace
331 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700332
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700333 // All incoming interests are satisfied. Remove them
334 pitEntry->ClearIncoming ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700335
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700336 // Remove all outgoing faces
337 pitEntry->ClearOutgoing ();
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700338
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700339 // Set pruning timout on PIT entry (instead of deleting the record)
340 m_pit->MarkErased (pitEntry);
341}
342
343void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700344ForwardingStrategy::DidReceiveUnsolicitedData (Ptr<Face> inFace,
345 Ptr<const ContentObjectHeader> header,
346 Ptr<const Packet> payload,
347 Ptr<const Packet> origPacket)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700348{
349 if (m_cacheUnsolicitedData)
350 {
351 // Optimistically add or update entry in the content store
352 m_contentStore->Add (header, payload);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700353 }
354 else
355 {
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700356 // Drop data packet if PIT entry is not found
357 // (unsolicited data packets should not "poison" content store)
358
359 //drop dulicated or not requested data packet
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700360 m_dropData (header, payload, inFace);
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700361 }
362}
363
364void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700365ForwardingStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
366 Ptr<pit::Entry> pitEntry)
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700367{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700368 pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (inFace);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700369
370 // If we have sent interest for this data via this face, then update stats.
371 if (out != pitEntry->GetOutgoing ().end ())
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700372 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700373 pitEntry->GetFibEntry ()->UpdateFaceRtt (inFace, Simulator::Now () - out->m_sendTime);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700374 }
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700375}
376
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700377bool
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700378ForwardingStrategy::ShouldSuppressIncomingInterest (Ptr<Face> inFace,
379 Ptr<const InterestHeader> header,
380 Ptr<const Packet> origPacket,
381 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700382{
383 bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
384
385 if (isNew) return false; // never suppress new interests
386
387 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700388 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700389
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700390 if (pitEntry->GetOutgoing ().find (inFace) != pitEntry->GetOutgoing ().end ())
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700391 {
392 NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
393 // got a non-duplicate interest from the face we have sent interest to
394 // Probably, there is no point in waiting data from that face... Not sure yet
395
396 // If we're expecting data from the interface we got the interest from ("producer" asks us for "his own" data)
397 // Mark interface YELLOW, but keep a small hope that data will come eventually.
398
399 // ?? not sure if we need to do that ?? ...
400
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700401 // pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700402 }
403 else
404 if (!isNew && !isRetransmitted)
405 {
406 return true;
407 }
408
409 return false;
410}
411
412void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700413ForwardingStrategy::PropagateInterest (Ptr<Face> inFace,
414 Ptr<const InterestHeader> header,
415 Ptr<const Packet> origPacket,
416 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700417{
418 bool isRetransmitted = m_detectRetransmissions && // a small guard
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700419 DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700420
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700421 pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700422 /// @todo Make lifetime per incoming interface
423 pitEntry->UpdateLifetime (header->GetInterestLifetime ());
424
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700425 bool propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700426
427 if (!propagated && isRetransmitted) //give another chance if retransmitted
428 {
429 // increase max number of allowed retransmissions
430 pitEntry->IncreaseAllowedRetxCount ();
431
432 // try again
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700433 propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700434 }
435
436 // ForwardingStrategy will try its best to forward packet to at least one interface.
437 // If no interests was propagated, then there is not other option for forwarding or
438 // ForwardingStrategy failed to find it.
439 if (!propagated && pitEntry->GetOutgoing ().size () == 0)
440 {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700441 DidExhaustForwardingOptions (inFace, header, origPacket, pitEntry);
Alexander Afanasyev996b4872012-07-17 17:07:56 -0700442 }
443}
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -0700444
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700445bool
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700446ForwardingStrategy::TrySendOutInterest (Ptr<Face> inFace,
447 Ptr<Face> outFace,
448 Ptr<const InterestHeader> header,
449 Ptr<const Packet> origPacket,
450 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700451{
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700452 if (outFace == inFace)
453 {
454 NS_LOG_DEBUG ("Same as incoming");
455 return false; // same face as incoming, don't forward
456 }
457
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700458 pit::Entry::out_iterator outgoing =
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700459 pitEntry->GetOutgoing ().find (outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700460
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700461 if (outgoing != pitEntry->GetOutgoing ().end ())
462 {
463 if (!m_detectRetransmissions)
464 return false; // suppress
465 else if (outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
466 {
467 NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount ());
468 return false; // already forwarded before during this retransmission cycle
469 }
470 }
471
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700472 pitEntry->AddOutgoing (outFace);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700473
474 //transmission
475 Ptr<Packet> packetToSend = origPacket->Copy ();
476 outFace->Send (packetToSend);
477
478 DidSendOutInterest (outFace, header, origPacket, pitEntry);
479
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700480 return true;
481}
482
483void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700484ForwardingStrategy::DidSendOutInterest (Ptr<Face> outFace,
485 Ptr<const InterestHeader> header,
486 Ptr<const Packet> origPacket,
487 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700488{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700489 m_outInterests (header, outFace);
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700490}
491
492void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700493ForwardingStrategy::DidSendOutData (Ptr<Face> inFace,
494 Ptr<const ContentObjectHeader> header,
495 Ptr<const Packet> payload,
496 Ptr<const Packet> origPacket,
497 Ptr<pit::Entry> pitEntry)
Alexander Afanasyev1c0248b2012-07-24 15:59:50 -0700498{
499}
500
501void
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700502ForwardingStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700503{
504 // do nothing for now. may be need to do some logging
505}
506
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700507
508void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700509ForwardingStrategy::RemoveFace (Ptr<Face> face)
Alexander Afanasyev33364b62012-07-26 17:53:56 -0700510{
511 // do nothing here
512}
513
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700514} // namespace ndn
515} // namespace ns3