blob: d473197d2348ec417c9009276db60e64940181e3 [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
39//#define NDN_DUMP_FIB 0
40namespace ns3 {
41
42
43//////////////////////////////////////////////////////////////////////
44// Helpers
45//////////////////////////////////////////////////////////////////////
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070046namespace __ccnx_private {
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070047
48struct CcnxFibFaceMetricByFace
49{
50 typedef CcnxFibFaceMetricContainer::type::index<i_face>::type
51 type;
52};
53
54struct ChangeStatus
55{
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070056 ChangeStatus (CcnxFibFaceMetric::Status status) : m_status (status) { }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070057 void operator() (CcnxFibFaceMetric &entry)
58 {
59 entry.m_status = m_status;
60 }
61private:
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070062 CcnxFibFaceMetric::Status m_status;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070063};
64
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -070065struct ChangeMetric
66{
67 ChangeMetric (int32_t metric) : m_metric (metric) { }
68 void operator() (CcnxFibFaceMetric &entry)
69 {
70 entry.m_routingCost = m_metric;
71 }
72private:
73 int32_t m_metric;
74};
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070075
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070076// struct SearchByFace {
77// /**
78// * \brief To perform effective searches by CcnxFace
79// */
80// bool
81// operator() (const CcnxFibFaceMetric &m, const Ptr<CcnxFace> &face) const
82// {
83// return *(m.m_face) < *face;
84// }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070085
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070086// /**
87// * \brief To perform effective searches by CcnxFace
88// */
89// bool
90// operator() (const Ptr<CcnxFace> &face, const CcnxFibFaceMetric &m) const
91// {
92// return *face < *(m.m_face);
93// }
94// };
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070095
96}
97//////////////////////////////////////////////////////////////////////
98//////////////////////////////////////////////////////////////////////
Ilya Moiseenko00b30482011-11-15 17:58:00 -080099NS_LOG_COMPONENT_DEFINE ("CcnxFib");
100
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700101using namespace __ccnx_private;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700102
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700103TypeId
104CcnxFib::GetTypeId (void)
105{
106 static TypeId tid = TypeId ("ns3::CcnxFib")
107 .SetParent<Object> ()
108 .SetGroupName ("Ccnx")
109 .AddConstructor<CcnxFib> ()
110
111 ;
112 return tid;
113}
114
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700115void
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700116CcnxFibFaceMetric::UpdateRtt::operator() (CcnxFibFaceMetric &entry)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700117{
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700118 // const Time & this->m_rttSample
119
120 //update srtt and rttvar (RFC 2988)
121 if (entry.m_sRtt.IsZero ())
122 {
123 //first RTT measurement
124 NS_ASSERT_MSG (entry.m_rttVar.IsZero (), "SRTT is zero, but variation is not");
125
126 entry.m_sRtt = m_rttSample;
127 entry.m_rttVar = Time (entry.m_sRtt / 2.0);
128 }
129 else
130 {
131 entry.m_rttVar = Time ((1 - NDN_RTO_BETA) * entry.m_rttVar + NDN_RTO_BETA * Abs(entry.m_sRtt - m_rttSample));
132 entry.m_sRtt = Time ((1 - NDN_RTO_ALPHA) * entry.m_sRtt + NDN_RTO_ALPHA * m_rttSample);
133 }
134}
135
136void
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700137CcnxFibEntry::UpdateStatus::operator () (CcnxFibEntry &entry)
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700138{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700139 CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
140 NS_ASSERT_MSG (record != entry.m_faces.get<i_face> ().end (),
141 "Update status can be performed only on existing faces of CcxnFibEntry");
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700142
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700143 entry.m_faces.modify (record, ChangeStatus (m_status));
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700144
145 // reordering random access index same way as by metric index
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700146 entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700147}
148
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700149void
150CcnxFibEntry::AddOrUpdateRoutingMetric::operator () (CcnxFibEntry &entry)
151{
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800152 NS_LOG_FUNCTION(this);
153 NS_ASSERT_MSG (m_face != NULL, "Trying to Add or Update NULL face");
154
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700155 CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
156 if (record == entry.m_faces.get<i_face> ().end ())
157 {
158 entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
159 }
160 else
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800161 {
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700162 entry.m_faces.modify (record, ChangeMetric (m_metric));
163 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700164 // reordering random access index same way as by metric index
165 entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
166}
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700167
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700168void
169CcnxFibEntry::UpdateFaceRtt::operator() (CcnxFibEntry &entry)
170{
171 CcnxFibFaceMetricContainer::type::iterator metric = entry.m_faces.find (m_face);
172 NS_ASSERT_MSG (metric != entry.m_faces.end (),
173 "Something wrong. Cannot find entry for the face in FIB");
174
175 entry.m_faces.modify (metric, CcnxFibFaceMetric::UpdateRtt (m_rttSample));
176}
177
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700178Ptr<CcnxFace>
Ilya Moiseenko4e473482011-10-31 17:58:14 -0700179CcnxFibEntry::FindBestCandidate (int skip/* = 0*/) const
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700180{
181 skip = skip % m_faces.size();
182 return m_faces.get<i_nth> () [skip].GetFace ();
183}
184
185
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700186CcnxFib::CcnxFib ()
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700187{
188}
189
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700190void
191CcnxFib::NotifyNewAggregate ()
192{
193 if (m_node == 0)
194 m_node = this->GetObject<Node>();
195 Object::NotifyNewAggregate ();
196}
197
198void
199CcnxFib::DoDispose (void)
200{
201 m_node = 0;
Alexander Afanasyev18252852011-11-21 13:35:31 -0800202 clear ();
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700203 Object::DoDispose ();
204}
205
206
207CcnxFibEntryContainer::type::iterator
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700208CcnxFib::LongestPrefixMatch (const CcnxInterestHeader &interest) const
209{
210 const CcnxNameComponents &name = interest.GetName ();
211 for (size_t componentsCount = name.GetComponents ().size ();
212 componentsCount > 0;
213 componentsCount--)
214 {
215 CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700216 CcnxFibEntryContainer::type::iterator match = find (subPrefix);
217 if (match != end())
218 return match;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700219 }
220
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700221 return end ();
222}
223
224
225CcnxFibEntryContainer::type::iterator
226CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
227{
228// CcnxFibFaceMetric
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800229 NS_LOG_FUNCTION(this << prefix << face << metric);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700230 CcnxFibEntryContainer::type::iterator entry = find (prefix);
231 if (entry == end ())
232 {
233 entry = insert (end (), CcnxFibEntry (prefix));
234 // insert new
235 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700236
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800237 NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
238 modify (entry, CcnxFibEntry::AddOrUpdateRoutingMetric (face, metric));
239
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700240 return entry;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700241}
Ilya Moiseenko4e473482011-10-31 17:58:14 -0700242
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700243
244std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
245{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700246 os << "Node " << Names::FindName (fib.m_node) << "\n";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700247 os << " Dest prefix Interfaces(Costs) \n";
248 os << "+-------------+--------------------------------------+\n";
249
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700250 for (CcnxFibEntryContainer::type::iterator entry = fib.begin ();
251 entry != fib.end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700252 entry++)
253 {
254 os << *entry << "\n";
255 }
256 return os;
257}
258
259std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry)
260{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700261 os << *entry.m_prefix << "\t";
262
263 for (CcnxFibFaceMetricContainer::type::index<i_nth>::type::iterator metric =
264 entry.m_faces.get<i_nth> ().begin ();
265 metric != entry.m_faces.get<i_nth> ().end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700266 metric++)
267 {
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700268 if (metric != entry.m_faces.get<i_nth> ().begin ())
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700269 os << ", ";
270
271 os << *metric;
272 }
273 return os;
274}
275
276std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric)
277{
278 static const std::string statusString[] = {"","g","y","r"};
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700279
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700280 os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << ")";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700281 return os;
282}
283
284// void CcnxFib::resetProbing()
285// {
286// for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
287// VALUE(fib).needsProbing = true;
288// }
289
290// void CcnxFib::updateInterfaceStatus( int interface, int status )
291// {
292// for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
293// {
294// VALUE(fib).updateStatus( interface, status );
295// }
296// }
297
298} // namespace ns3