blob: 9f23a83e3f21d2f9930c63aed4de04adeecc9091 [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
41using namespace boost::lambda;
42
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 Afanasyeva46844b2011-11-21 19:13:26 -0800103CcnxFibEntry::UpdateStatus (const CcnxFace &face, CcnxFibFaceMetric::Status status)
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 Afanasyeva46844b2011-11-21 19:13:26 -0800109 m_faces.modify (record, _1->m_status = status);
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700110
111 // reordering random access index same way as by metric index
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800112 m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700113}
114
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800115// void
116// CcnxFibEntry::AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
117// {
118// NS_LOG_FUNCTION(this);
119// NS_ASSERT_MSG (m_face != NULL, "Trying to Add or Update NULL face");
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800120
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800121// CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
122// if (record == entry.m_faces.get<i_face> ().end ())
123// {
124// entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
125// }
126// else
127// {
128// entry.m_faces.modify (record, ChangeMetric (m_metric));
129// }
130// // reordering random access index same way as by metric index
131// entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
132// }
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700133
134Ptr<CcnxFace>
Ilya Moiseenko4e473482011-10-31 17:58:14 -0700135CcnxFibEntry::FindBestCandidate (int skip/* = 0*/) const
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700136{
137 skip = skip % m_faces.size();
138 return m_faces.get<i_nth> () [skip].GetFace ();
139}
140
141
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700142CcnxFib::CcnxFib ()
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700143{
144}
145
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700146void
147CcnxFib::NotifyNewAggregate ()
148{
149 if (m_node == 0)
150 m_node = this->GetObject<Node>();
151 Object::NotifyNewAggregate ();
152}
153
154void
155CcnxFib::DoDispose (void)
156{
Alexander Afanasyev4fa5e842011-11-21 13:38:39 -0800157 clear ();
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700158 m_node = 0;
Alexander Afanasyev18252852011-11-21 13:35:31 -0800159 clear ();
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700160 Object::DoDispose ();
161}
162
163
164CcnxFibEntryContainer::type::iterator
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700165CcnxFib::LongestPrefixMatch (const CcnxInterestHeader &interest) const
166{
167 const CcnxNameComponents &name = interest.GetName ();
168 for (size_t componentsCount = name.GetComponents ().size ();
169 componentsCount > 0;
170 componentsCount--)
171 {
172 CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700173 CcnxFibEntryContainer::type::iterator match = find (subPrefix);
174 if (match != end())
175 return match;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700176 }
177
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700178 return end ();
179}
180
181
182CcnxFibEntryContainer::type::iterator
183CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
184{
185// CcnxFibFaceMetric
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800186 NS_LOG_FUNCTION(this << prefix << face << metric);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700187 CcnxFibEntryContainer::type::iterator entry = find (prefix);
188 if (entry == end ())
189 {
190 entry = insert (end (), CcnxFibEntry (prefix));
191 // insert new
192 }
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700193
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800194 NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
195 modify (entry, CcnxFibEntry::AddOrUpdateRoutingMetric (face, metric));
196
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700197 return entry;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700198}
Ilya Moiseenko4e473482011-10-31 17:58:14 -0700199
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700200
201std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
202{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700203 os << "Node " << Names::FindName (fib.m_node) << "\n";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700204 os << " Dest prefix Interfaces(Costs) \n";
205 os << "+-------------+--------------------------------------+\n";
206
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700207 for (CcnxFibEntryContainer::type::iterator entry = fib.begin ();
208 entry != fib.end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700209 entry++)
210 {
211 os << *entry << "\n";
212 }
213 return os;
214}
215
216std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry)
217{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700218 os << *entry.m_prefix << "\t";
219
220 for (CcnxFibFaceMetricContainer::type::index<i_nth>::type::iterator metric =
221 entry.m_faces.get<i_nth> ().begin ();
222 metric != entry.m_faces.get<i_nth> ().end ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700223 metric++)
224 {
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700225 if (metric != entry.m_faces.get<i_nth> ().begin ())
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700226 os << ", ";
227
228 os << *metric;
229 }
230 return os;
231}
232
233std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric)
234{
235 static const std::string statusString[] = {"","g","y","r"};
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700236
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700237 os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << ")";
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700238 return os;
239}
240
241// void CcnxFib::resetProbing()
242// {
243// for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
244// VALUE(fib).needsProbing = true;
245// }
246
247// void CcnxFib::updateInterfaceStatus( int interface, int status )
248// {
249// for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
250// {
251// VALUE(fib).updateStatus( interface, status );
252// }
253// }
254
255} // namespace ns3