blob: 38f0c656b0a8b9f05a969323dce0328558107a47 [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"
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070030
31#define NDN_RTO_ALPHA 0.125
32#define NDN_RTO_BETA 0.25
33#define NDN_RTO_K 4
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070034
35//#define NDN_DEBUG_OSPF 0
36//#define NDN_DEBUG_OSPF_NODES 0
37
38//#define NDN_DUMP_FIB 0
39namespace ns3 {
40
41
42//////////////////////////////////////////////////////////////////////
43// Helpers
44//////////////////////////////////////////////////////////////////////
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070045namespace __ccnx_private {
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070046
47struct CcnxFibFaceMetricByFace
48{
49 typedef CcnxFibFaceMetricContainer::type::index<i_face>::type
50 type;
51};
52
53struct ChangeStatus
54{
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070055 ChangeStatus (CcnxFibFaceMetric::Status status) : m_status (status) { }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070056 void operator() (CcnxFibFaceMetric &entry)
57 {
58 entry.m_status = m_status;
59 }
60private:
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070061 CcnxFibFaceMetric::Status m_status;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070062};
63
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -070064struct ChangeMetric
65{
66 ChangeMetric (int32_t metric) : m_metric (metric) { }
67 void operator() (CcnxFibFaceMetric &entry)
68 {
69 entry.m_routingCost = m_metric;
70 }
71private:
72 int32_t m_metric;
73};
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070074
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070075// struct SearchByFace {
76// /**
77// * \brief To perform effective searches by CcnxFace
78// */
79// bool
80// operator() (const CcnxFibFaceMetric &m, const Ptr<CcnxFace> &face) const
81// {
82// return *(m.m_face) < *face;
83// }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070084
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070085// /**
86// * \brief To perform effective searches by CcnxFace
87// */
88// bool
89// operator() (const Ptr<CcnxFace> &face, const CcnxFibFaceMetric &m) const
90// {
91// return *face < *(m.m_face);
92// }
93// };
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070094
95}
96//////////////////////////////////////////////////////////////////////
97//////////////////////////////////////////////////////////////////////
98
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070099using namespace __ccnx_private;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700100
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700101TypeId
102CcnxFib::GetTypeId (void)
103{
104 static TypeId tid = TypeId ("ns3::CcnxFib")
105 .SetParent<Object> ()
106 .SetGroupName ("Ccnx")
107 .AddConstructor<CcnxFib> ()
108
109 ;
110 return tid;
111}
112
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700113void
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700114CcnxFibFaceMetric::UpdateRtt::operator() (CcnxFibFaceMetric &entry)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700115{
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700116 // const Time & this->m_rttSample
117
118 //update srtt and rttvar (RFC 2988)
119 if (entry.m_sRtt.IsZero ())
120 {
121 //first RTT measurement
122 NS_ASSERT_MSG (entry.m_rttVar.IsZero (), "SRTT is zero, but variation is not");
123
124 entry.m_sRtt = m_rttSample;
125 entry.m_rttVar = Time (entry.m_sRtt / 2.0);
126 }
127 else
128 {
129 entry.m_rttVar = Time ((1 - NDN_RTO_BETA) * entry.m_rttVar + NDN_RTO_BETA * Abs(entry.m_sRtt - m_rttSample));
130 entry.m_sRtt = Time ((1 - NDN_RTO_ALPHA) * entry.m_sRtt + NDN_RTO_ALPHA * m_rttSample);
131 }
132}
133
134void
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700135CcnxFibEntry::UpdateStatus::operator () (CcnxFibEntry &entry)
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700136{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700137 CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
138 NS_ASSERT_MSG (record != entry.m_faces.get<i_face> ().end (),
139 "Update status can be performed only on existing faces of CcxnFibEntry");
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700140
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700141 entry.m_faces.modify (record, ChangeStatus (m_status));
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700142
143 // reordering random access index same way as by metric index
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700144 entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700145}
146
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700147void
148CcnxFibEntry::AddOrUpdateRoutingMetric::operator () (CcnxFibEntry &entry)
149{
150 CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
151 if (record == entry.m_faces.get<i_face> ().end ())
152 {
153 entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
154 }
155 else
156 {
157 entry.m_faces.modify (record, ChangeMetric (m_metric));
158 }
159
160 // reordering random access index same way as by metric index
161 entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
162}
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700163
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700164void
165CcnxFibEntry::UpdateFaceRtt::operator() (CcnxFibEntry &entry)
166{
167 CcnxFibFaceMetricContainer::type::iterator metric = entry.m_faces.find (m_face);
168 NS_ASSERT_MSG (metric != entry.m_faces.end (),
169 "Something wrong. Cannot find entry for the face in FIB");
170
171 entry.m_faces.modify (metric, CcnxFibFaceMetric::UpdateRtt (m_rttSample));
172}
173
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700174Ptr<CcnxFace>
175CcnxFibEntry::FindBestCandidate (int skip/* = 0*/)
176{
177 skip = skip % m_faces.size();
178 return m_faces.get<i_nth> () [skip].GetFace ();
179}
180
181
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700182CcnxFib::CcnxFib ()
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700183{
184}
185
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700186void
187CcnxFib::NotifyNewAggregate ()
188{
189 if (m_node == 0)
190 m_node = this->GetObject<Node>();
191 Object::NotifyNewAggregate ();
192}
193
194void
195CcnxFib::DoDispose (void)
196{
197 m_node = 0;
198 Object::DoDispose ();
199}
200
201
202CcnxFibEntryContainer::type::iterator
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700203CcnxFib::LongestPrefixMatch (const CcnxInterestHeader &interest) const
204{
205 const CcnxNameComponents &name = interest.GetName ();
206 for (size_t componentsCount = name.GetComponents ().size ();
207 componentsCount > 0;
208 componentsCount--)
209 {
210 CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700211 CcnxFibEntryContainer::type::iterator match = find (subPrefix);
212 if (match != end())
213 return match;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700214 }
215
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700216 return end ();
217}
218
219
220CcnxFibEntryContainer::type::iterator
221CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
222{
223// CcnxFibFaceMetric
224 CcnxFibEntryContainer::type::iterator entry = find (prefix);
225 if (entry == end ())
226 {
227 entry = insert (end (), CcnxFibEntry (prefix));
228 // insert new
229 }
230 modify (entry, CcnxFibEntry::AddOrUpdateRoutingMetric (face, metric));
231
232 return entry;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700233}
234
235std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
236{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700237 os << "Node " << Names::FindName (fib.m_node) << "\n";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700238 os << " Dest prefix Interfaces(Costs) \n";
239 os << "+-------------+--------------------------------------+\n";
240
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700241 for (CcnxFibEntryContainer::type::iterator entry = fib.begin ();
242 entry != fib.end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700243 entry++)
244 {
245 os << *entry << "\n";
246 }
247 return os;
248}
249
250std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry)
251{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700252 os << *entry.m_prefix << "\t";
253
254 for (CcnxFibFaceMetricContainer::type::index<i_nth>::type::iterator metric =
255 entry.m_faces.get<i_nth> ().begin ();
256 metric != entry.m_faces.get<i_nth> ().end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700257 metric++)
258 {
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700259 if (metric != entry.m_faces.get<i_nth> ().begin ())
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700260 os << ", ";
261
262 os << *metric;
263 }
264 return os;
265}
266
267std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric)
268{
269 static const std::string statusString[] = {"","g","y","r"};
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700270
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700271 os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << ")";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700272 return os;
273}
274
275// void CcnxFib::resetProbing()
276// {
277// for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
278// VALUE(fib).needsProbing = true;
279// }
280
281// void CcnxFib::updateInterfaceStatus( int interface, int status )
282// {
283// for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
284// {
285// VALUE(fib).updateStatus( interface, status );
286// }
287// }
288
289} // namespace ns3