blob: d56d48cb83e57661f5ca3fd15128c684b2bd5fd5 [file] [log] [blame]
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -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>
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070019 */
20
21#include "per-fib-limits.h"
22
23#include "ns3/ndn-interest-header.h"
24#include "ns3/ndn-content-object-header.h"
25#include "ns3/ndn-pit.h"
26#include "ns3/ndn-pit-entry.h"
27
28#include "ns3/assert.h"
29#include "ns3/log.h"
30#include "ns3/simulator.h"
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -070031#include "ns3/random-variable.h"
Alexander Afanasyevccbd8342012-08-16 16:54:39 -070032#include "ns3/double.h"
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070033
34#include <boost/foreach.hpp>
35#include <boost/lambda/lambda.hpp>
36#include <boost/lambda/bind.hpp>
37namespace ll = boost::lambda;
38
39NS_LOG_COMPONENT_DEFINE ("ndn.fw.PerFibLimits");
40
41namespace ns3 {
42namespace ndn {
43namespace fw {
44
45NS_OBJECT_ENSURE_REGISTERED (PerFibLimits);
46
47TypeId
48PerFibLimits::GetTypeId (void)
49{
50 static TypeId tid = TypeId ("ns3::ndn::fw::PerFibLimits")
51 .SetGroupName ("Ndn")
Alexander Afanasyev31cb4692012-08-17 13:08:20 -070052 .SetParent <super> ()
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070053 .AddConstructor <PerFibLimits> ()
54 ;
55 return tid;
56}
57
58PerFibLimits::PerFibLimits ()
59{
60}
61
62void
63PerFibLimits::DoDispose ()
64{
Alexander Afanasyev31cb4692012-08-17 13:08:20 -070065 super::DoDispose ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070066}
67
Alexander Afanasyev5db92172012-08-21 16:52:07 -070068void
69PerFibLimits::RemoveFace (Ptr<Face> face)
70{
71 super::RemoveFace (face);
72
73 for (PitQueueMap::iterator item = m_pitQueues.begin ();
74 item != m_pitQueues.end ();
75 item ++)
76 {
77 item->second.Remove (face);
78 }
79 m_pitQueues.erase (face);
80}
81
82
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070083bool
Alexander Afanasyev5db92172012-08-21 16:52:07 -070084PerFibLimits::TrySendOutInterest (Ptr<Face> inFace,
85 Ptr<Face> outFace,
86 Ptr<const InterestHeader> header,
87 Ptr<const Packet> origPacket,
88 Ptr<pit::Entry> pitEntry)
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070089{
90 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
Alexander Afanasyev5db92172012-08-21 16:52:07 -070091 // totally override all (if any) parent processing
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070092
93 pit::Entry::out_iterator outgoing =
Alexander Afanasyev31cb4692012-08-17 13:08:20 -070094 pitEntry->GetOutgoing ().find (outFace);
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070095
96 if (outgoing != pitEntry->GetOutgoing ().end ())
97 {
Alexander Afanasyev5db92172012-08-21 16:52:07 -070098 // just suppress without any other action
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070099 return false;
100 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700101
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700102 NS_LOG_DEBUG ("Limit: " << outFace->GetLimits ().m_curMaxLimit << ", outstanding: " << outFace->GetLimits ().m_outstanding);
103
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700104 if (outFace->GetLimits ().IsBelowLimit ())
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700105 {
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700106 pitEntry->AddOutgoing (outFace);
107
108 //transmission
109 Ptr<Packet> packetToSend = origPacket->Copy ();
110 outFace->Send (packetToSend);
111
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700112 DidSendOutInterest (outFace, header, origPacket, pitEntry);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700113 return true;
114 }
115 else
116 {
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700117 NS_LOG_DEBUG ("Face limit for " << header->GetName ());
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700118 }
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700119
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700120 bool enqueued = m_pitQueues[outFace].Enqueue (inFace, pitEntry);
121 if (enqueued)
122 {
123 NS_LOG_DEBUG ("PIT entry is enqueued for delayed processing. Telling that we forwarding possible");
124 return true;
125 }
126 else
127 return false;
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700128}
129
130void
131PerFibLimits::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
132{
133 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700134 super::WillEraseTimedOutPendingInterest (pitEntry);
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700135
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700136 PitQueue::Remove (pitEntry);
137
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700138 for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
139 face != pitEntry->GetOutgoing ().end ();
140 face ++)
141 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700142 face->m_face->GetLimits ().RemoveOutstanding ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700143 }
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700144
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700145 ProcessFromQueue ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700146}
147
148
149void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700150PerFibLimits::WillSatisfyPendingInterest (Ptr<Face> inFace,
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700151 Ptr<pit::Entry> pitEntry)
152{
153 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700154 super::WillSatisfyPendingInterest (inFace, pitEntry);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700155
156 PitQueue::Remove (pitEntry);
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700157
158 for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
159 face != pitEntry->GetOutgoing ().end ();
160 face ++)
161 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700162 face->m_face->GetLimits ().RemoveOutstanding ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700163 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700164
165 ProcessFromQueue ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700166}
167
168
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700169void
170PerFibLimits::ProcessFromQueue ()
171{
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700172 NS_LOG_FUNCTION (this);
173
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700174 for (PitQueueMap::iterator queue = m_pitQueues.begin ();
175 queue != m_pitQueues.end ();
176 queue++)
177 {
Alexander Afanasyev91e11282012-08-21 17:23:11 -0700178 Ptr<Face> outFace = queue->first;
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700179
180 NS_LOG_DEBUG ("Processing " << *outFace);
Alexander Afanasyev91e11282012-08-21 17:23:11 -0700181
182 while (!queue->second.IsEmpty () && outFace->GetLimits ().IsBelowLimit ())
183 {
184 // now we have enqueued packet and have slot available. Send out delayed packet
185 Ptr<pit::Entry> pitEntry = queue->second.Pop ();
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700186
187 // wrong, but for experimental purposes
188 // pitEntry->UpdateLifetime (pitEntry->GetInterest ()->GetInterestLifetime ());
189
190 NS_ASSERT_MSG (pitEntry != 0, "There *have to* be an entry in queue");
191
Alexander Afanasyev91e11282012-08-21 17:23:11 -0700192 pitEntry->AddOutgoing (outFace);
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700193
Alexander Afanasyev91e11282012-08-21 17:23:11 -0700194 Ptr<Packet> packetToSend = Create<Packet> ();
195 packetToSend->AddHeader (*pitEntry->GetInterest ());
Alexander Afanasyev0ffa7162012-08-21 22:39:22 -0700196
197 NS_LOG_DEBUG ("Delayed sending for " << pitEntry->GetPrefix ());
Alexander Afanasyev91e11282012-08-21 17:23:11 -0700198 outFace->Send (packetToSend);
199 DidSendOutInterest (outFace, pitEntry->GetInterest (), packetToSend, pitEntry);
200 }
Alexander Afanasyev5db92172012-08-21 16:52:07 -0700201 }
202}
203
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700204// void
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700205// PerFibLimits::DidReceiveValidNack (Ptr<Face> inFace,
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700206// uint32_t nackCode,
207// Ptr<pit::Entry> pitEntry)
208// {
Alexander Afanasyev31cb4692012-08-17 13:08:20 -0700209// // super::DidReceiveValidNack (inFace, nackCode, pitEntry);
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700210
211// // ??
212// }
213
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700214
215} // namespace fw
216} // namespace ndn
217} // namespace ns3