blob: ba11f7f5fe2bd24c0a325f01c9c84de261e01013 [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>
19 * Ilya Moiseenko <iliamo@cs.ucla.edu>
20 */
21
22#include "per-fib-limits.h"
23
24#include "ns3/ndn-interest-header.h"
25#include "ns3/ndn-content-object-header.h"
26#include "ns3/ndn-pit.h"
27#include "ns3/ndn-pit-entry.h"
28
29#include "ns3/assert.h"
30#include "ns3/log.h"
31#include "ns3/simulator.h"
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -070032#include "ns3/random-variable.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")
52 .SetParent <FwStats> ()
53 .AddConstructor <PerFibLimits> ()
54 ;
55 return tid;
56}
57
58PerFibLimits::PerFibLimits ()
59{
60}
61
62void
63PerFibLimits::DoDispose ()
64{
65 BestRoute::DoDispose ();
66 m_decayLimitsEvent.Cancel ();
67}
68
69bool
70PerFibLimits::WillSendOutInterest (const Ptr<Face> &outgoingFace,
71 Ptr<InterestHeader> header,
72 Ptr<pit::Entry> pitEntry)
73{
74 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
75 // override all (if any) parent processing
76
77 pit::Entry::out_iterator outgoing =
78 pitEntry->GetOutgoing ().find (outgoingFace);
79
80 if (outgoing != pitEntry->GetOutgoing ().end ())
81 {
82 return false;
83 }
84
85 if (pitEntry->GetFibEntry ()->GetLimits ().IsBelowLimit ())
86 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -070087 if (outgoingFace->GetLimits ().IsBelowLimit ())
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070088 {
89 pitEntry->AddOutgoing (outgoingFace);
90 return true;
91 }
92 else
93 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -070094 NS_LOG_DEBUG ("Face limit. Reverting back per-prefix allowance");
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070095 pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
96 }
97 }
98
99 return false;
100}
101
102void
103PerFibLimits::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
104{
105 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
106
107 for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
108 face != pitEntry->GetOutgoing ().end ();
109 face ++)
110 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700111 face->m_face->GetLimits ().RemoveOutstanding ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700112 // face->m_face->GetLimits ()->DecreaseLimit (); !!! do not decrease per-face limit. it doesn't make sense !!!
113 }
114
115 pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
116 pitEntry->GetFibEntry ()->GetLimits ().DecreaseLimit (); // multiplicative decrease
117
118 if (!m_decayLimitsEvent.IsRunning ())
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700119 {
120 UniformVariable rand (0,5);
121 m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0) + Seconds (0.001 * rand.GetValue ()), &PerFibLimits::DecayLimits, this);
122 }
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700123}
124
125
126void
127PerFibLimits::WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
128 Ptr<pit::Entry> pitEntry)
129{
130 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
131
132 super::WillSatisfyPendingInterest (incomingFace, pitEntry);
133
134 for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
135 face != pitEntry->GetOutgoing ().end ();
136 face ++)
137 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700138 face->m_face->GetLimits ().RemoveOutstanding ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700139 // face->m_face->GetLimits ()->IncreaseLimit (); !!! do not increase (as do not decrease) per-face limit. again, it doesn't make sense
140 }
141
142 pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
143 pitEntry->GetFibEntry ()->GetLimits ().IncreaseLimit (); // additive increase
144}
145
146
147// void
148// PerFibLimits::DidReceiveValidNack (const Ptr<Face> &incomingFace,
149// uint32_t nackCode,
150// Ptr<pit::Entry> pitEntry)
151// {
152// // super::DidReceiveValidNack (incomingFace, nackCode, pitEntry);
153
154// // ??
155// }
156
157void
158PerFibLimits::DecayLimits ()
159{
160 for (Ptr<fib::Entry> entry = m_fib->Begin ();
161 entry != m_fib->End ();
162 entry = m_fib->Next (entry))
163 {
164 entry->GetLimits ().DecayCurrentLimit ();
165 }
166
167 m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0), &PerFibLimits::DecayLimits, this);
168}
169
170
171} // namespace fw
172} // namespace ndn
173} // namespace ns3