blob: d59338dbb0a77e1329edd84feb9cc2e113c56bb8 [file] [log] [blame]
Vince12e49462014-06-09 13:29:32 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoa3148082018-04-12 18:21:54 -04002/*
3 * Copyright (c) 2014-2018, Regents of the University of California,
Alexander Afanasyev7c10b3b2015-01-20 12:24:27 -08004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Vince12e49462014-06-09 13:29:32 -050010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "rib-entry.hpp"
Vince Lehman281ded72014-08-21 12:17:08 -050027#include "core/logger.hpp"
28
Junxiao Shi25c6ce42016-09-09 13:49:59 +000029#include <ndn-cxx/mgmt/nfd/control-command.hpp>
Vince12e49462014-06-09 13:29:32 -050030
31namespace nfd {
32namespace rib {
33
Davide Pesaventoa3148082018-04-12 18:21:54 -040034NFD_LOG_INIT(RibEntry);
35
Vince Lehman218be0a2015-01-15 17:25:20 -060036RibEntry::RouteList::iterator
37RibEntry::findRoute(const Route& route)
Vince12e49462014-06-09 13:29:32 -050038{
Vince Lehman218be0a2015-01-15 17:25:20 -060039 return std::find_if(begin(), end(), bind(&compareFaceIdAndOrigin, _1, route));
Vince12e49462014-06-09 13:29:32 -050040}
41
Vince Lehman76c751c2014-11-18 17:36:38 -060042RibEntry::RouteList::const_iterator
43RibEntry::findRoute(const Route& route) const
44{
45 return std::find_if(begin(), end(), bind(&compareFaceIdAndOrigin, _1, route));
46}
47
Nick Gordon89c4cca2016-11-02 15:42:32 +000048std::pair<RibEntry::iterator, bool>
Vince Lehman218be0a2015-01-15 17:25:20 -060049RibEntry::insertRoute(const Route& route)
Vince12e49462014-06-09 13:29:32 -050050{
Vince Lehman218be0a2015-01-15 17:25:20 -060051 iterator it = findRoute(route);
Vince12e49462014-06-09 13:29:32 -050052
Vince Lehman76c751c2014-11-18 17:36:38 -060053 if (it == end()) {
54 if (route.flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
55 m_nRoutesWithCaptureSet++;
56 }
Vince Lehman4387e782014-06-19 16:57:45 -050057
Vince Lehman76c751c2014-11-18 17:36:38 -060058 m_routes.push_back(route);
Davide Pesaventoe4b22382018-06-10 14:37:24 -040059 return {std::prev(m_routes.end()), true};
60 }
Vince Lehman76c751c2014-11-18 17:36:38 -060061
Davide Pesaventoe4b22382018-06-10 14:37:24 -040062 return {it, false};
Vince12e49462014-06-09 13:29:32 -050063}
64
Vince Lehman281ded72014-08-21 12:17:08 -050065void
Vince Lehman218be0a2015-01-15 17:25:20 -060066RibEntry::eraseRoute(const Route& route)
Vince12e49462014-06-09 13:29:32 -050067{
Vince Lehman218be0a2015-01-15 17:25:20 -060068 RibEntry::iterator it = findRoute(route);
69 eraseRoute(it);
Vince12e49462014-06-09 13:29:32 -050070}
71
72bool
Vince Lehman218be0a2015-01-15 17:25:20 -060073RibEntry::hasRoute(const Route& route)
Vince Lehman4387e782014-06-19 16:57:45 -050074{
Vince Lehman218be0a2015-01-15 17:25:20 -060075 RibEntry::const_iterator it = findRoute(route);
Vince Lehman4387e782014-06-19 16:57:45 -050076
Vince Lehman218be0a2015-01-15 17:25:20 -060077 return it != end();
Vince Lehman4387e782014-06-19 16:57:45 -050078}
79
80bool
Vince12e49462014-06-09 13:29:32 -050081RibEntry::hasFaceId(const uint64_t faceId) const
82{
Vince Lehman218be0a2015-01-15 17:25:20 -060083 RibEntry::const_iterator it = std::find_if(begin(), end(), bind(&compareFaceId, _1, faceId));
Vince12e49462014-06-09 13:29:32 -050084
Vince Lehman218be0a2015-01-15 17:25:20 -060085 return it != end();
Vince12e49462014-06-09 13:29:32 -050086}
87
Vince Lehman76c751c2014-11-18 17:36:38 -060088size_t
89RibEntry::getNRoutes() const
90{
91 return m_routes.size();
92}
93
Vince12e49462014-06-09 13:29:32 -050094void
95RibEntry::addChild(shared_ptr<RibEntry> child)
96{
Davide Pesaventoe4b22382018-06-10 14:37:24 -040097 BOOST_ASSERT(!child->getParent());
Vince12e49462014-06-09 13:29:32 -050098 child->setParent(this->shared_from_this());
Davide Pesaventoe4b22382018-06-10 14:37:24 -040099 m_children.push_back(std::move(child));
Vince12e49462014-06-09 13:29:32 -0500100}
101
102void
103RibEntry::removeChild(shared_ptr<RibEntry> child)
104{
105 BOOST_ASSERT(child->getParent().get() == this);
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400106 child->setParent(nullptr);
Vince12e49462014-06-09 13:29:32 -0500107 m_children.remove(child);
108}
109
Vince Lehman218be0a2015-01-15 17:25:20 -0600110RibEntry::RouteList::iterator
111RibEntry::eraseRoute(RouteList::iterator route)
Vince12e49462014-06-09 13:29:32 -0500112{
Vince Lehman76c751c2014-11-18 17:36:38 -0600113 if (route != m_routes.end()) {
114 if (route->flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
115 m_nRoutesWithCaptureSet--;
Vince Lehman4387e782014-06-19 16:57:45 -0500116 }
117
Vince Lehman76c751c2014-11-18 17:36:38 -0600118 // Cancel any scheduled event
119 NFD_LOG_TRACE("Cancelling expiration eventId: " << route->getExpirationEvent());
120 scheduler::cancel(route->getExpirationEvent());
121
122 return m_routes.erase(route);
123 }
124
Vince Lehman218be0a2015-01-15 17:25:20 -0600125 return m_routes.end();
Vince Lehman4387e782014-06-19 16:57:45 -0500126}
127
128void
Vince Lehman218be0a2015-01-15 17:25:20 -0600129RibEntry::addInheritedRoute(const Route& route)
Vince Lehman4387e782014-06-19 16:57:45 -0500130{
Vince Lehman218be0a2015-01-15 17:25:20 -0600131 m_inheritedRoutes.push_back(route);
Vince Lehman4387e782014-06-19 16:57:45 -0500132}
133
134void
Vince Lehman218be0a2015-01-15 17:25:20 -0600135RibEntry::removeInheritedRoute(const Route& route)
Vince Lehman4387e782014-06-19 16:57:45 -0500136{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400137 m_inheritedRoutes.remove_if(bind(&compareFaceId, _1, route.faceId));
Vince Lehman4387e782014-06-19 16:57:45 -0500138}
139
Vince Lehman76c751c2014-11-18 17:36:38 -0600140RibEntry::RouteList::const_iterator
141RibEntry::findInheritedRoute(const Route& route) const
Vince Lehman4387e782014-06-19 16:57:45 -0500142{
Vince Lehman218be0a2015-01-15 17:25:20 -0600143 return std::find_if(m_inheritedRoutes.begin(), m_inheritedRoutes.end(),
144 bind(&compareFaceId, _1, route.faceId));
Vince Lehman4387e782014-06-19 16:57:45 -0500145}
146
147bool
Vince Lehman76c751c2014-11-18 17:36:38 -0600148RibEntry::hasInheritedRoute(const Route& route) const
Vince Lehman4387e782014-06-19 16:57:45 -0500149{
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400150 return findInheritedRoute(route) != m_inheritedRoutes.end();
Vince Lehman4387e782014-06-19 16:57:45 -0500151}
152
153bool
154RibEntry::hasCapture() const
155{
Vince Lehman218be0a2015-01-15 17:25:20 -0600156 return m_nRoutesWithCaptureSet > 0;
Vince Lehman4387e782014-06-19 16:57:45 -0500157}
158
159bool
160RibEntry::hasChildInheritOnFaceId(uint64_t faceId) const
161{
Vince Lehman76c751c2014-11-18 17:36:38 -0600162 for (const Route& route : m_routes) {
163 if (route.faceId == faceId && (route.flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)) {
164 return true;
Vince Lehman4387e782014-06-19 16:57:45 -0500165 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600166 }
Vince Lehman4387e782014-06-19 16:57:45 -0500167
168 return false;
169}
170
Vince Lehman9dcfc402015-03-26 03:18:54 -0500171const Route*
Vince Lehman76c751c2014-11-18 17:36:38 -0600172RibEntry::getRouteWithLowestCostByFaceId(uint64_t faceId) const
Vince Lehman4387e782014-06-19 16:57:45 -0500173{
Vince Lehman9dcfc402015-03-26 03:18:54 -0500174 const Route* candidate = nullptr;
Vince Lehman4387e782014-06-19 16:57:45 -0500175
Vince Lehman76c751c2014-11-18 17:36:38 -0600176 for (const Route& route : m_routes) {
177 // Matching face ID
178 if (route.faceId == faceId) {
179 // If this is the first route with this Face ID found
180 if (candidate == nullptr) {
Vince Lehman9dcfc402015-03-26 03:18:54 -0500181 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600182 }
183 else if (route.cost < candidate->cost) {
184 // Found a route with a lower cost
Vince Lehman9dcfc402015-03-26 03:18:54 -0500185 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600186 }
Vince Lehman4387e782014-06-19 16:57:45 -0500187 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600188 }
Vince Lehman4387e782014-06-19 16:57:45 -0500189
Vince Lehman218be0a2015-01-15 17:25:20 -0600190 return candidate;
Vince Lehman4387e782014-06-19 16:57:45 -0500191}
192
Vince Lehman76c751c2014-11-18 17:36:38 -0600193const Route*
194RibEntry::getRouteWithSecondLowestCostByFaceId(uint64_t faceId) const
195{
Vince Lehman4310d502016-03-04 11:58:59 -0600196 std::vector<const Route*> matches;
Vince Lehman76c751c2014-11-18 17:36:38 -0600197
198 // Copy routes which have faceId
Vince Lehman4310d502016-03-04 11:58:59 -0600199 for (const Route& route : m_routes) {
200 if (route.faceId == faceId) {
201 matches.push_back(&route);
202 }
203 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600204
Vince Lehman4310d502016-03-04 11:58:59 -0600205 // If there are less than 2 routes, there is no second lowest
Vince Lehman76c751c2014-11-18 17:36:38 -0600206 if (matches.size() < 2) {
207 return nullptr;
208 }
209
210 // Get second lowest cost
211 std::nth_element(matches.begin(), matches.begin() + 1, matches.end(),
Vince Lehman4310d502016-03-04 11:58:59 -0600212 [] (const Route* lhs, const Route* rhs) { return lhs->cost < rhs->cost; });
Vince Lehman76c751c2014-11-18 17:36:38 -0600213
Vince Lehman4310d502016-03-04 11:58:59 -0600214 return matches.at(1);
Vince Lehman76c751c2014-11-18 17:36:38 -0600215}
216
Vince Lehman9dcfc402015-03-26 03:18:54 -0500217const Route*
Vince Lehman76c751c2014-11-18 17:36:38 -0600218RibEntry::getRouteWithLowestCostAndChildInheritByFaceId(uint64_t faceId) const
Vince Lehman4387e782014-06-19 16:57:45 -0500219{
Vince Lehman9dcfc402015-03-26 03:18:54 -0500220 const Route* candidate = nullptr;
Vince Lehman4387e782014-06-19 16:57:45 -0500221
Vince Lehman76c751c2014-11-18 17:36:38 -0600222 for (const Route& route : m_routes) {
223 // Correct face ID and Child Inherit flag set
224 if (route.faceId == faceId &&
225 (route.flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT) == ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
Vince Lehman4387e782014-06-19 16:57:45 -0500226 {
Vince Lehman76c751c2014-11-18 17:36:38 -0600227 // If this is the first route with this Face ID found
228 if (candidate == nullptr) {
Vince Lehman9dcfc402015-03-26 03:18:54 -0500229 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600230 }
231 else if (route.cost < candidate->cost) {
232 // Found a route with a lower cost
Vince Lehman9dcfc402015-03-26 03:18:54 -0500233 candidate = &route;
Vince Lehman76c751c2014-11-18 17:36:38 -0600234 }
Vince Lehman4387e782014-06-19 16:57:45 -0500235 }
Vince Lehman76c751c2014-11-18 17:36:38 -0600236 }
Vince Lehman4387e782014-06-19 16:57:45 -0500237
Vince Lehman218be0a2015-01-15 17:25:20 -0600238 return candidate;
Vince12e49462014-06-09 13:29:32 -0500239}
240
Junxiao Shid47cd632018-09-11 03:10:00 +0000241ndn::PrefixAnnouncement
242RibEntry::getPrefixAnnouncement(time::milliseconds minExpiration,
243 time::milliseconds maxExpiration) const
244{
245 const Route* bestAnnRoute = nullptr;
246 auto entryExpiry = time::steady_clock::TimePoint::min();
247
248 for (const Route& route : *this) {
249 if (route.expires) {
250 entryExpiry = std::max(entryExpiry, *route.expires);
251 if (route.announcement) {
252 if (bestAnnRoute == nullptr || *route.expires > *bestAnnRoute->expires) {
253 bestAnnRoute = &route;
254 }
255 }
256 }
257 else {
258 entryExpiry = time::steady_clock::TimePoint::max();
259 }
260 }
261
262 if (bestAnnRoute != nullptr) {
263 return *bestAnnRoute->announcement;
264 }
265
266 ndn::PrefixAnnouncement ann;
267 ann.setAnnouncedName(m_name);
268 ann.setExpiration(ndn::clamp(
269 time::duration_cast<time::milliseconds>(entryExpiry - time::steady_clock::now()),
270 minExpiration, maxExpiration));
271 return ann;
272}
273
Vince12e49462014-06-09 13:29:32 -0500274std::ostream&
Vince12e49462014-06-09 13:29:32 -0500275operator<<(std::ostream& os, const RibEntry& entry)
276{
Syed Obaid3313a372014-07-01 01:31:33 -0500277 os << "RibEntry {\n";
Junxiao Shi3f21e582017-05-29 15:26:32 +0000278 os << " Name: " << entry.getName() << "\n";
Vince12e49462014-06-09 13:29:32 -0500279
Vince Lehman76c751c2014-11-18 17:36:38 -0600280 for (const Route& route : entry) {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000281 os << " " << route << "\n";
Vince Lehman76c751c2014-11-18 17:36:38 -0600282 }
Vince12e49462014-06-09 13:29:32 -0500283
284 os << "}";
285
286 return os;
287}
288
289} // namespace rib
290} // namespace nfd