blob: 0b1a6bc02f12667ef9955fda81b31d1d3723284d [file] [log] [blame]
Alexander Afanasyev78057c32012-07-06 15:18:46 -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
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070021#ifndef _NDN_FIB_ENTRY_H_
22#define _NDN_FIB_ENTRY_H_
Alexander Afanasyev78057c32012-07-06 15:18:46 -070023
24#include "ns3/ptr.h"
25#include "ns3/nstime.h"
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070026#include "ns3/ndn-face.h"
Alexander Afanasyevcfdc14f2013-03-15 14:38:44 -070027#include "ns3/ndn-name.h"
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070028#include "ns3/ndn-limits.h"
Alexander Afanasyeve6dc0ac2013-02-21 14:00:48 -080029#include "ns3/traced-value.h"
Alexander Afanasyev78057c32012-07-06 15:18:46 -070030
31#include <boost/multi_index_container.hpp>
32#include <boost/multi_index/tag.hpp>
33#include <boost/multi_index/ordered_index.hpp>
34#include <boost/multi_index/composite_key.hpp>
35#include <boost/multi_index/hashed_index.hpp>
36#include <boost/multi_index/random_access_index.hpp>
37#include <boost/multi_index/member.hpp>
38#include <boost/multi_index/mem_fun.hpp>
39
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070040namespace ns3 {
41namespace ndn {
Alexander Afanasyev78057c32012-07-06 15:18:46 -070042
Alexander Afanasyevcfdc14f2013-03-15 14:38:44 -070043class Name;
Alexander Afanasyev73f06f62013-03-15 15:41:38 -070044typedef Name NameComponents;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070045
Alexander Afanasyevff0d9ca2013-04-14 23:13:46 -070046class Fib;
47
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070048namespace fib {
Alexander Afanasyev78057c32012-07-06 15:18:46 -070049
50/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070051 * \ingroup ndn
Alexander Afanasyev78057c32012-07-06 15:18:46 -070052 * \brief Structure holding various parameters associated with a (FibEntry, Face) tuple
53 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070054class FaceMetric
Alexander Afanasyev78057c32012-07-06 15:18:46 -070055{
56public:
57 /**
58 * @brief Color codes for FIB face status
59 */
60 enum Status { NDN_FIB_GREEN = 1,
61 NDN_FIB_YELLOW = 2,
62 NDN_FIB_RED = 3 };
63public:
64 /**
65 * \brief Metric constructor
66 *
67 * \param face Face for which metric
68 * \param cost Initial value for routing cost
69 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070070 FaceMetric (Ptr<Face> face, int32_t cost)
Alexander Afanasyev78057c32012-07-06 15:18:46 -070071 : m_face (face)
72 , m_status (NDN_FIB_YELLOW)
73 , m_routingCost (cost)
74 , m_sRtt (Seconds (0))
75 , m_rttVar (Seconds (0))
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -080076 , m_realDelay (Seconds (0))
Alexander Afanasyev78057c32012-07-06 15:18:46 -070077 { }
78
79 /**
80 * \brief Comparison operator used by boost::multi_index::identity<>
81 */
82 bool
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070083 operator< (const FaceMetric &fm) const { return *m_face < *fm.m_face; } // return identity of the face
Alexander Afanasyev78057c32012-07-06 15:18:46 -070084
85 /**
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070086 * @brief Comparison between FaceMetric and Face
Alexander Afanasyev78057c32012-07-06 15:18:46 -070087 */
88 bool
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -080089 operator< (const Ptr<Face> &face) const { return *m_face < *face; }
Alexander Afanasyev78057c32012-07-06 15:18:46 -070090
91 /**
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070092 * @brief Return Face associated with FaceMetric
Alexander Afanasyev78057c32012-07-06 15:18:46 -070093 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070094 Ptr<Face>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070095 GetFace () const { return m_face; }
96
97 /**
98 * \brief Recalculate smoothed RTT and RTT variation
99 * \param rttSample RTT sample
100 */
101 void
102 UpdateRtt (const Time &rttSample);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800103
104 /**
105 * @brief Get current status of FIB entry
106 */
107 Status
108 GetStatus () const
109 {
110 return m_status;
111 }
112
113 /**
114 * @brief Set current status of FIB entry
115 */
116 void
117 SetStatus (Status status)
118 {
Alexander Afanasyeve6dc0ac2013-02-21 14:00:48 -0800119 m_status.Set (status);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800120 }
121
122 /**
123 * @brief Get current routing cost
124 */
125 int32_t
126 GetRoutingCost () const
127 {
128 return m_routingCost;
129 }
130
131 /**
132 * @brief Set routing cost
133 */
134 void
135 SetRoutingCost (int32_t routingCost)
136 {
137 m_routingCost = routingCost;
138 }
139
140 /**
141 * @brief Get real propagation delay to the producer, calculated based on NS-3 p2p link delays
142 */
143 Time
144 GetRealDelay () const
145 {
146 return m_realDelay;
147 }
148
149 /**
150 * @brief Set real propagation delay to the producer, calculated based on NS-3 p2p link delays
151 */
152 void
153 SetRealDelay (Time realDelay)
154 {
155 m_realDelay = realDelay;
156 }
157
Alexander Afanasyeve6dc0ac2013-02-21 14:00:48 -0800158 /**
159 * @brief Get direct access to status trace
160 */
161 TracedValue<Status> &
162 GetStatusTrace ()
163 {
164 return m_status;
165 }
166
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700167private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700168 friend std::ostream& operator<< (std::ostream& os, const FaceMetric &metric);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800169
170private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700171 Ptr<Face> m_face; ///< Face
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800172
Alexander Afanasyeve6dc0ac2013-02-21 14:00:48 -0800173 TracedValue<Status> m_status; ///< \brief Status of the next hop:
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700174 ///< - NDN_FIB_GREEN
175 ///< - NDN_FIB_YELLOW
176 ///< - NDN_FIB_RED
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800177
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700178 int32_t m_routingCost; ///< \brief routing protocol cost (interpretation of the value depends on the underlying routing protocol)
179
180 Time m_sRtt; ///< \brief smoothed round-trip time
181 Time m_rttVar; ///< \brief round-trip time variation
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -0800182
183 Time m_realDelay; ///< \brief real propagation delay to the producer, calculated based on NS-3 p2p link delays
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700184};
185
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700186/// @cond include_hidden
187class i_face {};
188class i_metric {};
189class i_nth {};
190/// @endcond
191
192
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700193/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700194 * \ingroup ndn
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700195 * \brief Typedef for indexed face container of Entry
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700196 *
197 * Currently, there are 2 indexes:
198 * - by face (used to find record and update metric)
199 * - by metric (face ranking)
200 * - random access index (for fast lookup on nth face). Order is
201 * maintained manually to be equal to the 'by metric' order
202 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700203struct FaceMetricContainer
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700204{
205 /// @cond include_hidden
206 typedef boost::multi_index::multi_index_container<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700207 FaceMetric,
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700208 boost::multi_index::indexed_by<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700209 // For fast access to elements using Face
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700210 boost::multi_index::ordered_unique<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700211 boost::multi_index::tag<i_face>,
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800212 boost::multi_index::const_mem_fun<FaceMetric,Ptr<Face>,&FaceMetric::GetFace>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700213 >,
214
215 // List of available faces ordered by (status, m_routingCost)
216 boost::multi_index::ordered_non_unique<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700217 boost::multi_index::tag<i_metric>,
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700218 boost::multi_index::composite_key<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700219 FaceMetric,
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800220 boost::multi_index::const_mem_fun<FaceMetric,FaceMetric::Status,&FaceMetric::GetStatus>,
221 boost::multi_index::const_mem_fun<FaceMetric,int32_t,&FaceMetric::GetRoutingCost>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700222 >
223 >,
224
225 // To optimize nth candidate selection (sacrifice a little bit space to gain speed)
226 boost::multi_index::random_access<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700227 boost::multi_index::tag<i_nth>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700228 >
229 >
230 > type;
231 /// @endcond
232};
233
234/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700235 * \ingroup ndn
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700236 * \brief Structure for FIB table entry, holding indexed list of
237 * available faces and their respective metrics
238 */
Alexander Afanasyevf5c07742012-10-31 13:13:05 -0700239class Entry : public Object
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700240{
241public:
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800242 typedef Entry base_type;
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800243
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800244public:
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700245 class NoFaces {}; ///< @brief Exception class for the case when FIB entry is not found
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800246
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700247 /**
248 * \brief Constructor
249 * \param prefix smart pointer to the prefix for the FIB entry
250 */
Alexander Afanasyevff0d9ca2013-04-14 23:13:46 -0700251 Entry (Ptr<Fib> fib, const Ptr<const Name> &prefix)
252 : m_fib (fib)
253 , m_prefix (prefix)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700254 , m_needsProbing (false)
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700255 {
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700256 }
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800257
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700258 /**
259 * \brief Update status of FIB next hop
260 * \param status Status to set on the FIB entry
261 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700262 void UpdateStatus (Ptr<Face> face, FaceMetric::Status status);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700263
264 /**
265 * \brief Add or update routing metric of FIB next hop
266 *
267 * Initial status of the next hop is set to YELLOW
268 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700269 void AddOrUpdateRoutingMetric (Ptr<Face> face, int32_t metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700270
271 /**
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -0800272 * \brief Set real delay to the producer
273 */
274 void
275 SetRealDelayToProducer (Ptr<Face> face, Time delay);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800276
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -0800277 /**
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700278 * @brief Invalidate face
279 *
280 * Set routing metric on all faces to max and status to RED
281 */
282 void
283 Invalidate ();
284
285 /**
286 * @brief Update RTT averages for the face
287 */
288 void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700289 UpdateFaceRtt (Ptr<Face> face, const Time &sample);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800290
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700291 /**
292 * \brief Get prefix for the FIB entry
293 */
Alexander Afanasyevcfdc14f2013-03-15 14:38:44 -0700294 const Name&
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700295 GetPrefix () const { return *m_prefix; }
296
297 /**
298 * \brief Find "best route" candidate, skipping `skip' first candidates (modulo # of faces)
299 *
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700300 * throws Entry::NoFaces if m_faces.size()==0
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700301 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700302 const FaceMetric &
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700303 FindBestCandidate (uint32_t skip = 0) const;
304
305 /**
306 * @brief Remove record associated with `face`
307 */
308 void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700309 RemoveFace (const Ptr<Face> &face)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700310 {
311 m_faces.erase (face);
312 }
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700313
Alexander Afanasyevff0d9ca2013-04-14 23:13:46 -0700314 /**
315 * @brief Get pointer to access FIB, to which this entry is added
316 */
317 Ptr<Fib>
318 GetFib ();
319
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700320private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700321 friend std::ostream& operator<< (std::ostream& os, const Entry &entry);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700322
323public:
Alexander Afanasyevff0d9ca2013-04-14 23:13:46 -0700324 Ptr<Fib> m_fib; ///< \brief FIB to which entry is added
325
Alexander Afanasyevcfdc14f2013-03-15 14:38:44 -0700326 Ptr<const Name> m_prefix; ///< \brief Prefix of the FIB entry
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700327 FaceMetricContainer::type m_faces; ///< \brief Indexed list of faces
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700328
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700329 bool m_needsProbing; ///< \brief flag indicating that probing should be performed
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700330};
331
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700332std::ostream& operator<< (std::ostream& os, const Entry &entry);
333std::ostream& operator<< (std::ostream& os, const FaceMetric &metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700334
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700335} // namespace fib
336} // namespace ndn
337} // namespace ns3
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700338
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700339#endif // _NDN_FIB_ENTRY_H_