blob: a2d8b4b99499ac7cb43a37e06de1c945893ec781 [file] [log] [blame]
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -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 */
20
21#include "ccnx-fib.h"
22
23#include "ccnx.h"
24#include "ccnx-face.h"
25#include "ccnx-interest-header.h"
26
27#include "ns3/node.h"
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070028#include "ns3/assert.h"
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -070029#include "ns3/names.h"
Ilya Moiseenko00b30482011-11-15 17:58:00 -080030#include "ns3/log.h"
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070031
32#define NDN_RTO_ALPHA 0.125
33#define NDN_RTO_BETA 0.25
34#define NDN_RTO_K 4
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070035
36//#define NDN_DEBUG_OSPF 0
37//#define NDN_DEBUG_OSPF_NODES 0
38
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080039#include <boost/lambda/lambda.hpp>
40
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -080041using namespace boost;
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080042
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070043//#define NDN_DUMP_FIB 0
44namespace ns3 {
45
46
47//////////////////////////////////////////////////////////////////////
48// Helpers
49//////////////////////////////////////////////////////////////////////
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070050namespace __ccnx_private {
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070051
52struct CcnxFibFaceMetricByFace
53{
54 typedef CcnxFibFaceMetricContainer::type::index<i_face>::type
55 type;
56};
57
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070058}
59//////////////////////////////////////////////////////////////////////
60//////////////////////////////////////////////////////////////////////
Ilya Moiseenko00b30482011-11-15 17:58:00 -080061NS_LOG_COMPONENT_DEFINE ("CcnxFib");
62
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070063using namespace __ccnx_private;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070064
Alexander Afanasyevcf133f02011-09-06 12:13:48 -070065TypeId
66CcnxFib::GetTypeId (void)
67{
68 static TypeId tid = TypeId ("ns3::CcnxFib")
69 .SetParent<Object> ()
70 .SetGroupName ("Ccnx")
71 .AddConstructor<CcnxFib> ()
72
73 ;
74 return tid;
75}
76
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080077/////////////////////////////////////////////////////////////////////
78
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070079void
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080080CcnxFibFaceMetric::UpdateRtt (const Time &rttSample)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070081{
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070082 // const Time & this->m_rttSample
83
84 //update srtt and rttvar (RFC 2988)
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080085 if (m_sRtt.IsZero ())
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070086 {
87 //first RTT measurement
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080088 NS_ASSERT_MSG (m_rttVar.IsZero (), "SRTT is zero, but variation is not");
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070089
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080090 m_sRtt = rttSample;
91 m_rttVar = Time (m_sRtt / 2.0);
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070092 }
93 else
94 {
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080095 m_rttVar = Time ((1 - NDN_RTO_BETA) * m_rttVar + NDN_RTO_BETA * Abs(m_sRtt - rttSample));
96 m_sRtt = Time ((1 - NDN_RTO_ALPHA) * m_sRtt + NDN_RTO_ALPHA * rttSample);
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070097 }
98}
99
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800100/////////////////////////////////////////////////////////////////////
101
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700102void
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800103CcnxFibEntry::UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample)
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700104{
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800105 CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
106 NS_ASSERT_MSG (record != m_faces.get<i_face> ().end (),
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700107 "Update status can be performed only on existing faces of CcxnFibEntry");
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700108
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800109 m_faces.modify (record,
110 bind (&CcnxFibFaceMetric::UpdateRtt, lambda::_1, sample));
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700111
112 // reordering random access index same way as by metric index
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800113 m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700114}
115
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800116void
117CcnxFibEntry::UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status)
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700118{
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800119 CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
120 NS_ASSERT_MSG (record != m_faces.get<i_face> ().end (),
121 "Update status can be performed only on existing faces of CcxnFibEntry");
122
123 m_faces.modify (record,
124 (&lambda::_1)->*&CcnxFibFaceMetric::m_status = status);
125
126 // reordering random access index same way as by metric index
127 m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
128}
129
130void
131CcnxFibEntry::AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
132{
133 NS_LOG_FUNCTION (this);
134 NS_ASSERT_MSG (face != NULL, "Trying to Add or Update NULL face");
135
136 CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
137 if (record == m_faces.get<i_face> ().end ())
138 {
139 m_faces.insert (CcnxFibFaceMetric (face, metric));
140 }
141 else
142 {
143 m_faces.modify (record,
144 (&lambda::_1)->*&CcnxFibFaceMetric::m_routingCost = metric);
145 }
146
147 // reordering random access index same way as by metric index
148 m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
149}
150
151const CcnxFibFaceMetric &
152CcnxFibEntry::FindBestCandidate (uint32_t skip/* = 0*/) const
153{
154 if (m_faces.size () == 0) throw CcnxFibEntry::NoFaces ();
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700155 skip = skip % m_faces.size();
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800156 return m_faces.get<i_nth> () [skip];
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700157}
158
159
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700160CcnxFib::CcnxFib ()
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700161{
162}
163
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700164void
165CcnxFib::NotifyNewAggregate ()
166{
167 if (m_node == 0)
168 m_node = this->GetObject<Node>();
169 Object::NotifyNewAggregate ();
170}
171
172void
173CcnxFib::DoDispose (void)
174{
Alexander Afanasyev4fa5e842011-11-21 13:38:39 -0800175 clear ();
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700176 m_node = 0;
Alexander Afanasyev18252852011-11-21 13:35:31 -0800177 clear ();
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700178 Object::DoDispose ();
179}
180
181
182CcnxFibEntryContainer::type::iterator
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700183CcnxFib::LongestPrefixMatch (const CcnxInterestHeader &interest) const
184{
185 const CcnxNameComponents &name = interest.GetName ();
186 for (size_t componentsCount = name.GetComponents ().size ();
187 componentsCount > 0;
188 componentsCount--)
189 {
190 CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700191 CcnxFibEntryContainer::type::iterator match = find (subPrefix);
192 if (match != end())
193 return match;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700194 }
195
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700196 return end ();
197}
198
199
200CcnxFibEntryContainer::type::iterator
201CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
202{
203// CcnxFibFaceMetric
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800204 NS_LOG_FUNCTION(this << prefix << face << metric);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700205 CcnxFibEntryContainer::type::iterator entry = find (prefix);
206 if (entry == end ())
207 {
208 entry = insert (end (), CcnxFibEntry (prefix));
209 // insert new
210 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700211
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800212 NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800213 modify (entry,
214 bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, lambda::_1, face, metric));
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800215
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700216 return entry;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700217}
Ilya Moiseenko4e473482011-10-31 17:58:14 -0700218
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700219
220std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
221{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700222 os << "Node " << Names::FindName (fib.m_node) << "\n";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700223 os << " Dest prefix Interfaces(Costs) \n";
224 os << "+-------------+--------------------------------------+\n";
225
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700226 for (CcnxFibEntryContainer::type::iterator entry = fib.begin ();
227 entry != fib.end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700228 entry++)
229 {
230 os << *entry << "\n";
231 }
232 return os;
233}
234
235std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry)
236{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700237 os << *entry.m_prefix << "\t";
238
239 for (CcnxFibFaceMetricContainer::type::index<i_nth>::type::iterator metric =
240 entry.m_faces.get<i_nth> ().begin ();
241 metric != entry.m_faces.get<i_nth> ().end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700242 metric++)
243 {
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700244 if (metric != entry.m_faces.get<i_nth> ().begin ())
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700245 os << ", ";
246
247 os << *metric;
248 }
249 return os;
250}
251
252std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric)
253{
254 static const std::string statusString[] = {"","g","y","r"};
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700255
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700256 os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << ")";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700257 return os;
258}
259
260// void CcnxFib::resetProbing()
261// {
262// for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
263// VALUE(fib).needsProbing = true;
264// }
265
266// void CcnxFib::updateInterfaceStatus( int interface, int status )
267// {
268// for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
269// {
270// VALUE(fib).updateStatus( interface, status );
271// }
272// }
273
274} // namespace ns3