blob: 57e8916724dbfb303982be0508fded4d9ff116bf [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 Afanasyev2b4c9472012-08-09 15:00:38 -070027#include "ns3/ndn-name-components.h"
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070028#include "ns3/ndn-limits.h"
Alexander Afanasyev78057c32012-07-06 15:18:46 -070029
30#include <boost/multi_index_container.hpp>
31#include <boost/multi_index/tag.hpp>
32#include <boost/multi_index/ordered_index.hpp>
33#include <boost/multi_index/composite_key.hpp>
34#include <boost/multi_index/hashed_index.hpp>
35#include <boost/multi_index/random_access_index.hpp>
36#include <boost/multi_index/member.hpp>
37#include <boost/multi_index/mem_fun.hpp>
38
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070039namespace ns3 {
40namespace ndn {
Alexander Afanasyev78057c32012-07-06 15:18:46 -070041
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070042class NameComponents;
43
44namespace fib {
Alexander Afanasyev78057c32012-07-06 15:18:46 -070045
46/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070047 * \ingroup ndn
Alexander Afanasyev78057c32012-07-06 15:18:46 -070048 * \brief Structure holding various parameters associated with a (FibEntry, Face) tuple
49 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070050class FaceMetric
Alexander Afanasyev78057c32012-07-06 15:18:46 -070051{
52public:
53 /**
54 * @brief Color codes for FIB face status
55 */
56 enum Status { NDN_FIB_GREEN = 1,
57 NDN_FIB_YELLOW = 2,
58 NDN_FIB_RED = 3 };
59public:
60 /**
61 * \brief Metric constructor
62 *
63 * \param face Face for which metric
64 * \param cost Initial value for routing cost
65 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070066 FaceMetric (Ptr<Face> face, int32_t cost)
Alexander Afanasyev78057c32012-07-06 15:18:46 -070067 : m_face (face)
68 , m_status (NDN_FIB_YELLOW)
69 , m_routingCost (cost)
70 , m_sRtt (Seconds (0))
71 , m_rttVar (Seconds (0))
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -080072 , m_realDelay (Seconds (0))
Alexander Afanasyev78057c32012-07-06 15:18:46 -070073 { }
74
75 /**
76 * \brief Comparison operator used by boost::multi_index::identity<>
77 */
78 bool
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070079 operator< (const FaceMetric &fm) const { return *m_face < *fm.m_face; } // return identity of the face
Alexander Afanasyev78057c32012-07-06 15:18:46 -070080
81 /**
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070082 * @brief Comparison between FaceMetric and Face
Alexander Afanasyev78057c32012-07-06 15:18:46 -070083 */
84 bool
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -080085 operator< (const Ptr<Face> &face) const { return *m_face < *face; }
Alexander Afanasyev78057c32012-07-06 15:18:46 -070086
87 /**
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070088 * @brief Return Face associated with FaceMetric
Alexander Afanasyev78057c32012-07-06 15:18:46 -070089 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070090 Ptr<Face>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070091 GetFace () const { return m_face; }
92
93 /**
94 * \brief Recalculate smoothed RTT and RTT variation
95 * \param rttSample RTT sample
96 */
97 void
98 UpdateRtt (const Time &rttSample);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -080099
100 /**
101 * @brief Get current status of FIB entry
102 */
103 Status
104 GetStatus () const
105 {
106 return m_status;
107 }
108
109 /**
110 * @brief Set current status of FIB entry
111 */
112 void
113 SetStatus (Status status)
114 {
115 m_status = status;
116 }
117
118 /**
119 * @brief Get current routing cost
120 */
121 int32_t
122 GetRoutingCost () const
123 {
124 return m_routingCost;
125 }
126
127 /**
128 * @brief Set routing cost
129 */
130 void
131 SetRoutingCost (int32_t routingCost)
132 {
133 m_routingCost = routingCost;
134 }
135
136 /**
137 * @brief Get real propagation delay to the producer, calculated based on NS-3 p2p link delays
138 */
139 Time
140 GetRealDelay () const
141 {
142 return m_realDelay;
143 }
144
145 /**
146 * @brief Set real propagation delay to the producer, calculated based on NS-3 p2p link delays
147 */
148 void
149 SetRealDelay (Time realDelay)
150 {
151 m_realDelay = realDelay;
152 }
153
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700154private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700155 friend std::ostream& operator<< (std::ostream& os, const FaceMetric &metric);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800156
157private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700158 Ptr<Face> m_face; ///< Face
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800159
160 Status m_status; ///< \brief Status of the next hop:
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700161 ///< - NDN_FIB_GREEN
162 ///< - NDN_FIB_YELLOW
163 ///< - NDN_FIB_RED
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800164
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700165 int32_t m_routingCost; ///< \brief routing protocol cost (interpretation of the value depends on the underlying routing protocol)
166
167 Time m_sRtt; ///< \brief smoothed round-trip time
168 Time m_rttVar; ///< \brief round-trip time variation
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -0800169
170 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 -0700171};
172
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700173/// @cond include_hidden
174class i_face {};
175class i_metric {};
176class i_nth {};
177/// @endcond
178
179
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700180/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700181 * \ingroup ndn
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700182 * \brief Typedef for indexed face container of Entry
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700183 *
184 * Currently, there are 2 indexes:
185 * - by face (used to find record and update metric)
186 * - by metric (face ranking)
187 * - random access index (for fast lookup on nth face). Order is
188 * maintained manually to be equal to the 'by metric' order
189 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700190struct FaceMetricContainer
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700191{
192 /// @cond include_hidden
193 typedef boost::multi_index::multi_index_container<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700194 FaceMetric,
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700195 boost::multi_index::indexed_by<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700196 // For fast access to elements using Face
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700197 boost::multi_index::ordered_unique<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700198 boost::multi_index::tag<i_face>,
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800199 boost::multi_index::const_mem_fun<FaceMetric,Ptr<Face>,&FaceMetric::GetFace>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700200 >,
201
202 // List of available faces ordered by (status, m_routingCost)
203 boost::multi_index::ordered_non_unique<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700204 boost::multi_index::tag<i_metric>,
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700205 boost::multi_index::composite_key<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700206 FaceMetric,
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800207 boost::multi_index::const_mem_fun<FaceMetric,FaceMetric::Status,&FaceMetric::GetStatus>,
208 boost::multi_index::const_mem_fun<FaceMetric,int32_t,&FaceMetric::GetRoutingCost>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700209 >
210 >,
211
212 // To optimize nth candidate selection (sacrifice a little bit space to gain speed)
213 boost::multi_index::random_access<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700214 boost::multi_index::tag<i_nth>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700215 >
216 >
217 > type;
218 /// @endcond
219};
220
221/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700222 * \ingroup ndn
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700223 * \brief Structure for FIB table entry, holding indexed list of
224 * available faces and their respective metrics
225 */
Alexander Afanasyevf5c07742012-10-31 13:13:05 -0700226class Entry : public Object
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700227{
228public:
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800229 typedef Entry base_type;
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800230
Alexander Afanasyev8566f452012-12-10 15:21:51 -0800231public:
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700232 class NoFaces {}; ///< @brief Exception class for the case when FIB entry is not found
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800233
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700234 /**
235 * \brief Constructor
236 * \param prefix smart pointer to the prefix for the FIB entry
237 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700238 Entry (const Ptr<const NameComponents> &prefix)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700239 : m_prefix (prefix)
240 , m_needsProbing (false)
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700241 {
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700242 }
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800243
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700244 /**
245 * \brief Update status of FIB next hop
246 * \param status Status to set on the FIB entry
247 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700248 void UpdateStatus (Ptr<Face> face, FaceMetric::Status status);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700249
250 /**
251 * \brief Add or update routing metric of FIB next hop
252 *
253 * Initial status of the next hop is set to YELLOW
254 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700255 void AddOrUpdateRoutingMetric (Ptr<Face> face, int32_t metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700256
257 /**
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -0800258 * \brief Set real delay to the producer
259 */
260 void
261 SetRealDelayToProducer (Ptr<Face> face, Time delay);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800262
Alexander Afanasyev6b0c88f2012-12-01 12:24:27 -0800263 /**
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700264 * @brief Invalidate face
265 *
266 * Set routing metric on all faces to max and status to RED
267 */
268 void
269 Invalidate ();
270
271 /**
272 * @brief Update RTT averages for the face
273 */
274 void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700275 UpdateFaceRtt (Ptr<Face> face, const Time &sample);
Alexander Afanasyev06dba7c2013-02-21 11:36:26 -0800276
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700277 /**
278 * \brief Get prefix for the FIB entry
279 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700280 const NameComponents&
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700281 GetPrefix () const { return *m_prefix; }
282
283 /**
284 * \brief Find "best route" candidate, skipping `skip' first candidates (modulo # of faces)
285 *
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700286 * throws Entry::NoFaces if m_faces.size()==0
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700287 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700288 const FaceMetric &
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700289 FindBestCandidate (uint32_t skip = 0) const;
290
291 /**
292 * @brief Remove record associated with `face`
293 */
294 void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700295 RemoveFace (const Ptr<Face> &face)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700296 {
297 m_faces.erase (face);
298 }
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700299
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700300private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700301 friend std::ostream& operator<< (std::ostream& os, const Entry &entry);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700302
303public:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700304 Ptr<const NameComponents> m_prefix; ///< \brief Prefix of the FIB entry
305 FaceMetricContainer::type m_faces; ///< \brief Indexed list of faces
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700306
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700307 bool m_needsProbing; ///< \brief flag indicating that probing should be performed
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700308};
309
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700310std::ostream& operator<< (std::ostream& os, const Entry &entry);
311std::ostream& operator<< (std::ostream& os, const FaceMetric &metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700312
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700313} // namespace fib
314} // namespace ndn
315} // namespace ns3
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700316
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700317#endif // _NDN_FIB_ENTRY_H_