NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
ndn-fib-entry.cc
1 /* -*- 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 "ndn-fib-entry.h"
22 #include "ndn-fib.h"
23 
24 #include "ns3/ndn-name.h"
25 #include "ns3/log.h"
26 #include "ns3/simulator.h"
27 
28 #define NDN_RTO_ALPHA 0.125
29 #define NDN_RTO_BETA 0.25
30 #define NDN_RTO_K 4
31 
32 #include <boost/ref.hpp>
33 #include <boost/lambda/lambda.hpp>
34 #include <boost/lambda/bind.hpp>
35 namespace ll = boost::lambda;
36 
37 NS_LOG_COMPONENT_DEFINE ("ndn.fib.Entry");
38 
39 namespace ns3 {
40 namespace ndn {
41 namespace fib {
42 
44 // Helpers
46 
48 {
49  typedef FaceMetricContainer::type::index<i_face>::type
50  type;
51 };
52 
53 
54 void
55 FaceMetric::UpdateRtt (const Time &rttSample)
56 {
57  // const Time & this->m_rttSample
58 
59  //update srtt and rttvar (RFC 2988)
60  if (m_sRtt.IsZero ())
61  {
62  //first RTT measurement
63  NS_ASSERT_MSG (m_rttVar.IsZero (), "SRTT is zero, but variation is not");
64 
65  m_sRtt = rttSample;
66  m_rttVar = Time (m_sRtt / 2.0);
67  }
68  else
69  {
70  m_rttVar = Time ((1 - NDN_RTO_BETA) * m_rttVar + 1.0 * NDN_RTO_BETA * Abs(m_sRtt - rttSample));
71  m_sRtt = Time ((1 - NDN_RTO_ALPHA) * m_sRtt + 1.0 * NDN_RTO_ALPHA * rttSample);
72  }
73 }
74 
76 
77 void
78 Entry::UpdateFaceRtt (Ptr<Face> face, const Time &sample)
79 {
80  FaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
81  if (record == m_faces.get<i_face> ().end ())
82  {
83  return;
84  }
85 
86  m_faces.modify (record,
87  ll::bind (&FaceMetric::UpdateRtt, ll::_1, sample));
88 
89  // reordering random access index same way as by metric index
90  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
91 }
92 
93 void
94 Entry::UpdateStatus (Ptr<Face> face, FaceMetric::Status status)
95 {
96  NS_LOG_FUNCTION (this << boost::cref(*face) << status);
97 
98  FaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
99  if (record == m_faces.get<i_face> ().end ())
100  {
101  return;
102  }
103 
104  m_faces.modify (record,
105  ll::bind (&FaceMetric::SetStatus, ll::_1, status));
106 
107  // reordering random access index same way as by metric index
108  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
109 }
110 
111 void
112 Entry::AddOrUpdateRoutingMetric (Ptr<Face> face, int32_t metric)
113 {
114  NS_LOG_FUNCTION (this);
115  NS_ASSERT_MSG (face != NULL, "Trying to Add or Update NULL face");
116 
117  FaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
118  if (record == m_faces.get<i_face> ().end ())
119  {
120  m_faces.insert (FaceMetric (face, metric));
121  }
122  else
123  {
124  // don't update metric to higher value
125  if (record->GetRoutingCost () > metric || record->GetStatus () == FaceMetric::NDN_FIB_RED)
126  {
127  m_faces.modify (record,
128  ll::bind (&FaceMetric::SetRoutingCost, ll::_1, metric));
129 
130  m_faces.modify (record,
131  ll::bind (&FaceMetric::SetStatus, ll::_1, FaceMetric::NDN_FIB_YELLOW));
132  }
133  }
134 
135  // reordering random access index same way as by metric index
136  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
137 }
138 
139 void
140 Entry::SetRealDelayToProducer (Ptr<Face> face, Time delay)
141 {
142  NS_LOG_FUNCTION (this);
143  NS_ASSERT_MSG (face != NULL, "Trying to Update NULL face");
144 
145  FaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
146  if (record != m_faces.get<i_face> ().end ())
147  {
148  m_faces.modify (record,
149  ll::bind (&FaceMetric::SetRealDelay, ll::_1, delay));
150  }
151 }
152 
153 
154 void
156 {
157  for (FaceMetricByFace::type::iterator face = m_faces.begin ();
158  face != m_faces.end ();
159  face++)
160  {
161  m_faces.modify (face,
162  ll::bind (&FaceMetric::SetRoutingCost, ll::_1, std::numeric_limits<uint16_t>::max ()));
163 
164  m_faces.modify (face,
165  ll::bind (&FaceMetric::SetStatus, ll::_1, FaceMetric::NDN_FIB_RED));
166  }
167 }
168 
169 const FaceMetric &
170 Entry::FindBestCandidate (uint32_t skip/* = 0*/) const
171 {
172  if (m_faces.size () == 0) throw Entry::NoFaces ();
173  skip = skip % m_faces.size();
174  return m_faces.get<i_nth> () [skip];
175 }
176 
177 Ptr<Fib>
179 {
180  return m_fib;
181 }
182 
183 
184 std::ostream& operator<< (std::ostream& os, const Entry &entry)
185 {
186  for (FaceMetricContainer::type::index<i_nth>::type::iterator metric =
187  entry.m_faces.get<i_nth> ().begin ();
188  metric != entry.m_faces.get<i_nth> ().end ();
189  metric++)
190  {
191  if (metric != entry.m_faces.get<i_nth> ().begin ())
192  os << ", ";
193 
194  os << *metric;
195  }
196  return os;
197 }
198 
199 std::ostream& operator<< (std::ostream& os, const FaceMetric &metric)
200 {
201  static const std::string statusString[] = {"","g","y","r"};
202 
203  os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << "," << metric.m_face->GetMetric () << ")";
204  return os;
205 }
206 
207 } // namespace fib
208 } // namespace ndn
209 } // namespace ns3
Exception class for the case when FIB entry is not found.
Status
Color codes for FIB face status.
Definition: ndn-fib-entry.h:64
Structure for FIB table entry, holding indexed list of available faces and their respective metrics...
void UpdateStatus(Ptr< Face > face, FaceMetric::Status status)
Update status of FIB next hop.
void SetStatus(Status status)
Set current status of FIB entry.
void AddOrUpdateRoutingMetric(Ptr< Face > face, int32_t metric)
Add or update routing metric of FIB next hop.
void Invalidate()
Invalidate face.
FaceMetricContainer::type m_faces
Indexed list of faces.
void UpdateRtt(const Time &rttSample)
Recalculate smoothed RTT and RTT variation.
Structure holding various parameters associated with a (FibEntry, Face) tuple.
Definition: ndn-fib-entry.h:58
Ptr< Fib > GetFib()
Get pointer to access FIB, to which this entry is added.
void SetRealDelay(Time realDelay)
Set real propagation delay to the producer, calculated based on NS-3 p2p link delays.
void SetRealDelayToProducer(Ptr< Face > face, Time delay)
Set real delay to the producer.
void SetRoutingCost(int32_t routingCost)
Set routing cost.
Ptr< Fib > m_fib
FIB to which entry is added.
const FaceMetric & FindBestCandidate(uint32_t skip=0) const
Find "best route" candidate, skipping `skip' first candidates (modulo # of faces) ...
void UpdateFaceRtt(Ptr< Face > face, const Time &sample)
Update RTT averages for the face.