blob: e464c49c32bff375be01fbc6a6b12706574f32a7 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonfeae5572017-01-13 12:06:26 -06003 * Copyright (c) 2014-2017, The University of Memphis,
Vince Lehman41b173e2015-05-07 14:13:26 -05004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
akmhoque3d06e792014-05-27 16:23:20 -050020 **/
Vince Lehman41b173e2015-05-07 14:13:26 -050021
akmhoque53353462014-04-22 08:43:45 -050022#include <iostream>
23#include <cmath>
24#include "lsdb.hpp"
25#include "routing-table-calculator.hpp"
26#include "map.hpp"
27#include "lsa.hpp"
28#include "nexthop.hpp"
29#include "nlsr.hpp"
akmhoque2f423352014-06-03 11:49:35 -050030#include "logger.hpp"
akmhoque53353462014-04-22 08:43:45 -050031
Vince Lehman9a709032014-09-13 16:28:07 -050032#include <boost/math/constants/constants.hpp>
33
akmhoque53353462014-04-22 08:43:45 -050034namespace nlsr {
35
akmhoque2f423352014-06-03 11:49:35 -050036INIT_LOGGER("RoutingTableCalculator");
akmhoque53353462014-04-22 08:43:45 -050037using namespace std;
38
39void
40RoutingTableCalculator::allocateAdjMatrix()
41{
Vince Lehman9a709032014-09-13 16:28:07 -050042 adjMatrix = new double*[m_nRouters];
43
44 for (size_t i = 0; i < m_nRouters; ++i) {
45 adjMatrix[i] = new double[m_nRouters];
akmhoque53353462014-04-22 08:43:45 -050046 }
47}
48
49void
50RoutingTableCalculator::initMatrix()
51{
Vince Lehman9a709032014-09-13 16:28:07 -050052 for (size_t i = 0; i < m_nRouters; i++) {
53 for (size_t j = 0; j < m_nRouters; j++) {
akmhoque53353462014-04-22 08:43:45 -050054 adjMatrix[i][j] = 0;
akmhoque157b0a42014-05-13 00:26:37 -050055 }
akmhoque53353462014-04-22 08:43:45 -050056 }
57}
58
59void
60RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
61{
62 std::list<AdjLsa> adjLsdb = pnlsr.getLsdb().getAdjLsdb();
Nick G97e34942016-07-11 14:46:27 -050063 // For each LSA represented in the map
Vince Lehman9a709032014-09-13 16:28:07 -050064 for (std::list<AdjLsa>::iterator it = adjLsdb.begin(); it != adjLsdb.end() ; it++) {
65
Nick G97e34942016-07-11 14:46:27 -050066
Vince Lehman9a709032014-09-13 16:28:07 -050067 int32_t row = pMap.getMappingNoByRouterName((*it).getOrigRouter());
68
akmhoque53353462014-04-22 08:43:45 -050069 std::list<Adjacent> adl = (*it).getAdl().getAdjList();
Nick G97e34942016-07-11 14:46:27 -050070 // For each adjacency represented in the LSA
Vince Lehman9a709032014-09-13 16:28:07 -050071 for (std::list<Adjacent>::iterator itAdl = adl.begin(); itAdl != adl.end() ; itAdl++) {
72
73 int32_t col = pMap.getMappingNoByRouterName((*itAdl).getName());
akmhoque53353462014-04-22 08:43:45 -050074 double cost = (*itAdl).getLinkCost();
Vince Lehman9a709032014-09-13 16:28:07 -050075
76 if ((row >= 0 && row < static_cast<int32_t>(m_nRouters)) &&
77 (col >= 0 && col < static_cast<int32_t>(m_nRouters)))
78 {
akmhoque53353462014-04-22 08:43:45 -050079 adjMatrix[row][col] = cost;
80 }
81 }
82 }
Vince Lehman41b173e2015-05-07 14:13:26 -050083
Nick G97e34942016-07-11 14:46:27 -050084 // Links that do not have the same cost for both directions should
85 // have their costs corrected:
Vince Lehman41b173e2015-05-07 14:13:26 -050086 //
Nick G97e34942016-07-11 14:46:27 -050087 // If the cost of one side of the link is 0, both sides of the
88 // link should have their cost corrected to 0.
Vince Lehman41b173e2015-05-07 14:13:26 -050089 //
90 // Otherwise, both sides of the link should use the larger of the two costs.
91 //
Nick G97e34942016-07-11 14:46:27 -050092 // Additionally, this means that we can halve the amount of space
93 // that the matrix uses by only maintaining a triangle.
94 // - But that is not yet implemented.
Vince Lehman41b173e2015-05-07 14:13:26 -050095 for (size_t row = 0; row < m_nRouters; ++row) {
96 for (size_t col = 0; col < m_nRouters; ++col) {
97 double toCost = adjMatrix[row][col];
98 double fromCost = adjMatrix[col][row];
99
100 if (fromCost != toCost) {
101 double correctedCost = 0.0;
102
103 if (toCost != 0 && fromCost != 0) {
104 // If both sides of the link are up, use the larger cost
105 correctedCost = std::max(toCost, fromCost);
106 }
107
108 _LOG_WARN("Cost between [" << row << "][" << col << "] and [" << col << "][" << row <<
109 "] are not the same (" << toCost << " != " << fromCost << "). " <<
110 "Correcting to cost: " << correctedCost);
111
112 adjMatrix[row][col] = correctedCost;
113 adjMatrix[col][row] = correctedCost;
114 }
115 }
116 }
akmhoque53353462014-04-22 08:43:45 -0500117}
118
119void
akmhoque2f423352014-06-03 11:49:35 -0500120RoutingTableCalculator::writeAdjMatrixLog()
akmhoque53353462014-04-22 08:43:45 -0500121{
Vince Lehman9a709032014-09-13 16:28:07 -0500122 for (size_t i = 0; i < m_nRouters; i++) {
akmhoque2f423352014-06-03 11:49:35 -0500123 string line="";
Vince Lehman9a709032014-09-13 16:28:07 -0500124 for (size_t j = 0; j < m_nRouters; j++) {
akmhoque2f423352014-06-03 11:49:35 -0500125 line += boost::lexical_cast<std::string>(adjMatrix[i][j]);
126 line += " ";
akmhoque157b0a42014-05-13 00:26:37 -0500127 }
akmhoque2f423352014-06-03 11:49:35 -0500128 _LOG_DEBUG(line);
akmhoque53353462014-04-22 08:43:45 -0500129 }
130}
131
132void
133RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
134{
Vince Lehman9a709032014-09-13 16:28:07 -0500135 for (int i = 0; i < static_cast<int>(m_nRouters); i++) {
akmhoque157b0a42014-05-13 00:26:37 -0500136 if (i == link) {
akmhoque53353462014-04-22 08:43:45 -0500137 adjMatrix[source][i] = linkCost;
138 }
akmhoque157b0a42014-05-13 00:26:37 -0500139 else {
akmhoque53353462014-04-22 08:43:45 -0500140 adjMatrix[source][i] = 0;
141 }
142 }
143}
144
145int
146RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
147{
148 int noLink = 0;
Vince Lehman9a709032014-09-13 16:28:07 -0500149
150 for (size_t i = 0; i < m_nRouters; i++) {
akmhoque157b0a42014-05-13 00:26:37 -0500151 if (adjMatrix[sRouter][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -0500152 noLink++;
153 }
154 }
155 return noLink;
156}
157
158void
159RoutingTableCalculator::getLinksFromAdjMatrix(int* links,
160 double* linkCosts, int source)
161{
162 int j = 0;
Vince Lehman9a709032014-09-13 16:28:07 -0500163
164 for (size_t i = 0; i < m_nRouters; i++) {
akmhoque157b0a42014-05-13 00:26:37 -0500165 if (adjMatrix[source][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -0500166 links[j] = i;
167 linkCosts[j] = adjMatrix[source][i];
168 j++;
169 }
170 }
171}
172
173void
174RoutingTableCalculator::freeAdjMatrix()
175{
Vince Lehman9a709032014-09-13 16:28:07 -0500176 for (size_t i = 0; i < m_nRouters; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500177 delete [] adjMatrix[i];
178 }
179 delete [] adjMatrix;
180}
181
akmhoque53353462014-04-22 08:43:45 -0500182void
183RoutingTableCalculator::allocateLinks()
184{
185 links = new int[vNoLink];
186}
187
188void
189RoutingTableCalculator::allocateLinkCosts()
190{
191 linkCosts = new double[vNoLink];
192}
193
194
195void
196RoutingTableCalculator::freeLinks()
197{
198 delete [] links;
199}
200void
201RoutingTableCalculator::freeLinksCosts()
202{
203 delete [] linkCosts;
204}
205
206void
207LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
208 RoutingTable& rt, Nlsr& pnlsr)
209{
akmhoque2f423352014-06-03 11:49:35 -0500210 _LOG_DEBUG("LinkStateRoutingTableCalculator::calculatePath Called");
akmhoque53353462014-04-22 08:43:45 -0500211 allocateAdjMatrix();
212 initMatrix();
213 makeAdjMatrix(pnlsr, pMap);
akmhoque2f423352014-06-03 11:49:35 -0500214 writeAdjMatrixLog();
akmhoque31d1d4b2014-05-05 22:08:14 -0500215 int sourceRouter = pMap.getMappingNoByRouterName(pnlsr.getConfParameter().getRouterPrefix());
Nick G97e34942016-07-11 14:46:27 -0500216 allocateParent(); // These two matrices are used in Dijkstra's algorithm.
217 allocateDistance(); //
akmhoque157b0a42014-05-13 00:26:37 -0500218 if (pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1) {
Nick G97e34942016-07-11 14:46:27 -0500219 // In the single path case we can simply run Dijkstra's algorithm.
akmhoque53353462014-04-22 08:43:45 -0500220 doDijkstraPathCalculation(sourceRouter);
Nick G97e34942016-07-11 14:46:27 -0500221 // Inform the routing table of the new next hops.
akmhoque53353462014-04-22 08:43:45 -0500222 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
223 }
akmhoque157b0a42014-05-13 00:26:37 -0500224 else {
akmhoque53353462014-04-22 08:43:45 -0500225 // Multi Path
226 setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
227 allocateLinks();
228 allocateLinkCosts();
Nick G97e34942016-07-11 14:46:27 -0500229 // Gets a sparse listing of adjacencies for path calculation
akmhoque53353462014-04-22 08:43:45 -0500230 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500231 for (int i = 0 ; i < vNoLink; i++) {
Nick G97e34942016-07-11 14:46:27 -0500232 // Simulate that only the current neighbor is accessible
akmhoque53353462014-04-22 08:43:45 -0500233 adjustAdMatrix(sourceRouter, links[i], linkCosts[i]);
akmhoque2f423352014-06-03 11:49:35 -0500234 writeAdjMatrixLog();
Nick G97e34942016-07-11 14:46:27 -0500235 // Do Dijkstra's algorithm using the current neighbor as your start.
akmhoque53353462014-04-22 08:43:45 -0500236 doDijkstraPathCalculation(sourceRouter);
Nick G97e34942016-07-11 14:46:27 -0500237 // Update the routing table with the calculations.
akmhoque53353462014-04-22 08:43:45 -0500238 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
239 }
240 freeLinks();
241 freeLinksCosts();
242 }
243 freeParent();
244 freeDistance();
245 freeAdjMatrix();
246}
247
248void
249LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
250{
251 int i;
252 int v, u;
Nick G97e34942016-07-11 14:46:27 -0500253 int* Q = new int[m_nRouters]; // Each cell represents the router with that mapping no.
akmhoque53353462014-04-22 08:43:45 -0500254 int head = 0;
255 /* Initiate the Parent */
Vince Lehman9a709032014-09-13 16:28:07 -0500256 for (i = 0 ; i < static_cast<int>(m_nRouters); i++) {
akmhoque53353462014-04-22 08:43:45 -0500257 m_parent[i] = EMPTY_PARENT;
Nick G97e34942016-07-11 14:46:27 -0500258 // Array where the ith element is the distance to the router with mapping no i.
akmhoque53353462014-04-22 08:43:45 -0500259 m_distance[i] = INF_DISTANCE;
260 Q[i] = i;
261 }
akmhoque157b0a42014-05-13 00:26:37 -0500262 if (sourceRouter != NO_MAPPING_NUM) {
Nick G97e34942016-07-11 14:46:27 -0500263 // Distance to source from source is always 0.
akmhoque53353462014-04-22 08:43:45 -0500264 m_distance[sourceRouter] = 0;
Vince Lehman9a709032014-09-13 16:28:07 -0500265 sortQueueByDistance(Q, m_distance, head, m_nRouters);
Nick G97e34942016-07-11 14:46:27 -0500266 // While we haven't visited every node.
Vince Lehman9a709032014-09-13 16:28:07 -0500267 while (head < static_cast<int>(m_nRouters)) {
Nick G97e34942016-07-11 14:46:27 -0500268 u = Q[head]; // Set u to be the current node pointed to by head.
akmhoque157b0a42014-05-13 00:26:37 -0500269 if (m_distance[u] == INF_DISTANCE) {
Nick G97e34942016-07-11 14:46:27 -0500270 break; // This can only happen when there are no accessible nodes.
akmhoque53353462014-04-22 08:43:45 -0500271 }
Nick G97e34942016-07-11 14:46:27 -0500272 // Iterate over the adjacent nodes to u.
Vince Lehman9a709032014-09-13 16:28:07 -0500273 for (v = 0 ; v < static_cast<int>(m_nRouters); v++) {
Nick G97e34942016-07-11 14:46:27 -0500274 // If the current node is accessible.
akmhoque157b0a42014-05-13 00:26:37 -0500275 if (adjMatrix[u][v] > 0) {
Nick G97e34942016-07-11 14:46:27 -0500276 // And we haven't visited it yet.
Vince Lehman9a709032014-09-13 16:28:07 -0500277 if (isNotExplored(Q, v, head + 1, m_nRouters)) {
Nick G97e34942016-07-11 14:46:27 -0500278 // And if the distance to this node + from this node to v
279 // is less than the distance from our source node to v
280 // that we got when we built the adj LSAs
akmhoque157b0a42014-05-13 00:26:37 -0500281 if (m_distance[u] + adjMatrix[u][v] < m_distance[v]) {
Nick G97e34942016-07-11 14:46:27 -0500282 // Set the new distance
akmhoque53353462014-04-22 08:43:45 -0500283 m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
Nick G97e34942016-07-11 14:46:27 -0500284 // Set how we get there.
akmhoque53353462014-04-22 08:43:45 -0500285 m_parent[v] = u;
286 }
287 }
288 }
289 }
Nick G97e34942016-07-11 14:46:27 -0500290 // Increment the head position, resort the list by distance from where we are.
akmhoque53353462014-04-22 08:43:45 -0500291 head++;
Vince Lehman9a709032014-09-13 16:28:07 -0500292 sortQueueByDistance(Q, m_distance, head, m_nRouters);
akmhoque53353462014-04-22 08:43:45 -0500293 }
294 }
295 delete [] Q;
296}
297
298void
Vince Lehman9a709032014-09-13 16:28:07 -0500299LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr, RoutingTable& rt,
300 Map& pMap, uint32_t sourceRouter)
akmhoque53353462014-04-22 08:43:45 -0500301{
akmhoque2f423352014-06-03 11:49:35 -0500302 _LOG_DEBUG("LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called");
Vince Lehman9a709032014-09-13 16:28:07 -0500303
akmhoque53353462014-04-22 08:43:45 -0500304 int nextHopRouter = 0;
Vince Lehman9a709032014-09-13 16:28:07 -0500305
Nick G97e34942016-07-11 14:46:27 -0500306 // For each router we have
Vince Lehman9a709032014-09-13 16:28:07 -0500307 for (size_t i = 0; i < m_nRouters ; i++) {
akmhoque157b0a42014-05-13 00:26:37 -0500308 if (i != sourceRouter) {
Vince Lehman9a709032014-09-13 16:28:07 -0500309
Nick G97e34942016-07-11 14:46:27 -0500310 // Obtain the next hop that was determined by the algorithm
akmhoque53353462014-04-22 08:43:45 -0500311 nextHopRouter = getLsNextHop(i, sourceRouter);
Vince Lehman9a709032014-09-13 16:28:07 -0500312
Nick G97e34942016-07-11 14:46:27 -0500313 // If this router is accessible at all
akmhoque157b0a42014-05-13 00:26:37 -0500314 if (nextHopRouter != NO_NEXT_HOP) {
Vince Lehman9a709032014-09-13 16:28:07 -0500315
Nick G97e34942016-07-11 14:46:27 -0500316 // Fetch its distance
akmhoque53353462014-04-22 08:43:45 -0500317 double routeCost = m_distance[i];
Nick G97e34942016-07-11 14:46:27 -0500318 // Fetch its actual name
akmhoque31d1d4b2014-05-05 22:08:14 -0500319 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500320 std::string nextHopFace =
321 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500322 // Add next hop to routing table
akmhoque157b0a42014-05-13 00:26:37 -0500323 NextHop nh(nextHopFace, routeCost);
akmhoque53353462014-04-22 08:43:45 -0500324 rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
325 }
326 }
327 }
328}
329
330int
331LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
332{
333 int nextHop = NO_NEXT_HOP;
akmhoque157b0a42014-05-13 00:26:37 -0500334 while (m_parent[dest] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500335 nextHop = dest;
336 dest = m_parent[dest];
337 }
akmhoque157b0a42014-05-13 00:26:37 -0500338 if (dest != source) {
akmhoque53353462014-04-22 08:43:45 -0500339 nextHop = NO_NEXT_HOP;
340 }
341 return nextHop;
342}
343
344void
akmhoque53353462014-04-22 08:43:45 -0500345LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
akmhoque2f423352014-06-03 11:49:35 -0500346 double* dist,
347 int start, int element)
akmhoque53353462014-04-22 08:43:45 -0500348{
akmhoque157b0a42014-05-13 00:26:37 -0500349 for (int i = start ; i < element ; i++) {
350 for (int j = i + 1; j < element; j++) {
351 if (dist[Q[j]] < dist[Q[i]]) {
akmhoque53353462014-04-22 08:43:45 -0500352 int tempU = Q[j];
353 Q[j] = Q[i];
354 Q[i] = tempU;
355 }
356 }
357 }
358}
359
360int
361LinkStateRoutingTableCalculator::isNotExplored(int* Q,
362 int u, int start, int element)
363{
364 int ret = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500365 for (int i = start; i < element; i++) {
366 if (Q[i] == u) {
akmhoque53353462014-04-22 08:43:45 -0500367 ret = 1;
368 break;
369 }
370 }
371 return ret;
372}
373
374void
375LinkStateRoutingTableCalculator::allocateParent()
376{
Vince Lehman9a709032014-09-13 16:28:07 -0500377 m_parent = new int[m_nRouters];
akmhoque53353462014-04-22 08:43:45 -0500378}
379
380void
381LinkStateRoutingTableCalculator::allocateDistance()
382{
Vince Lehman9a709032014-09-13 16:28:07 -0500383 m_distance = new double[m_nRouters];
akmhoque53353462014-04-22 08:43:45 -0500384}
385
386void
387LinkStateRoutingTableCalculator::freeParent()
388{
389 delete [] m_parent;
390}
391
392void LinkStateRoutingTableCalculator::freeDistance()
393{
394 delete [] m_distance;
395}
396
Vince Lehman9a709032014-09-13 16:28:07 -0500397const double HyperbolicRoutingCalculator::MATH_PI = boost::math::constants::pi<double>();
akmhoque53353462014-04-22 08:43:45 -0500398
Vince Lehman9a709032014-09-13 16:28:07 -0500399const double HyperbolicRoutingCalculator::UNKNOWN_DISTANCE = -1.0;
400const double HyperbolicRoutingCalculator::UNKNOWN_RADIUS = -1.0;
401
402const int32_t HyperbolicRoutingCalculator::ROUTER_NOT_FOUND = -1.0;
akmhoque53353462014-04-22 08:43:45 -0500403
404void
Vince Lehman9a709032014-09-13 16:28:07 -0500405HyperbolicRoutingCalculator::calculatePaths(Map& map, RoutingTable& rt,
406 Lsdb& lsdb, AdjacencyList& adjacencies)
akmhoque53353462014-04-22 08:43:45 -0500407{
Vince Lehman9a709032014-09-13 16:28:07 -0500408 _LOG_TRACE("Calculating hyperbolic paths");
409
410 int thisRouter = map.getMappingNoByRouterName(m_thisRouterName);
411
412 // Iterate over directly connected neighbors
413 std::list<Adjacent> neighbors = adjacencies.getAdjList();
414 for (std::list<Adjacent>::iterator adj = neighbors.begin(); adj != neighbors.end(); ++adj) {
415
416 // Don't calculate nexthops using an inactive router
417 if (adj->getStatus() == Adjacent::STATUS_INACTIVE) {
418 _LOG_TRACE(adj->getName() << " is inactive; not using it as a nexthop");
419 continue;
420 }
421
422 ndn::Name srcRouterName = adj->getName();
423
424 // Don't calculate nexthops for this router to other routers
425 if (srcRouterName == m_thisRouterName) {
426 continue;
427 }
428
429 std::string srcFaceUri = adj->getConnectingFaceUri();
430
431 // Install nexthops for this router to the neighbor; direct neighbors have a 0 cost link
432 addNextHop(srcRouterName, srcFaceUri, 0, rt);
433
434 int src = map.getMappingNoByRouterName(srcRouterName);
435
436 if (src == ROUTER_NOT_FOUND) {
437 _LOG_WARN(adj->getName() << " does not exist in the router map!");
438 continue;
439 }
440
441 // Get hyperbolic distance from direct neighbor to every other router
442 for (int dest = 0; dest < static_cast<int>(m_nRouters); ++dest) {
443 // Don't calculate nexthops to this router or from a router to itself
444 if (dest != thisRouter && dest != src) {
445
446 ndn::Name destRouterName = map.getRouterNameByMappingNo(dest);
447
448 double distance = getHyperbolicDistance(map, lsdb, srcRouterName, destRouterName);
449
450 // Could not compute distance
451 if (distance == UNKNOWN_DISTANCE) {
452 _LOG_WARN("Could not calculate hyperbolic distance from " << srcRouterName << " to " <<
453 destRouterName);
454 continue;
akmhoque53353462014-04-22 08:43:45 -0500455 }
akmhoque53353462014-04-22 08:43:45 -0500456
Vince Lehman9a709032014-09-13 16:28:07 -0500457 addNextHop(destRouterName, srcFaceUri, distance, rt);
458 }
akmhoquedcee9362014-08-05 22:58:01 -0500459 }
akmhoque53353462014-04-22 08:43:45 -0500460 }
461}
462
463double
Vince Lehman9a709032014-09-13 16:28:07 -0500464HyperbolicRoutingCalculator::getHyperbolicDistance(Map& map, Lsdb& lsdb,
465 ndn::Name src, ndn::Name dest)
akmhoque53353462014-04-22 08:43:45 -0500466{
Vince Lehman9a709032014-09-13 16:28:07 -0500467 _LOG_TRACE("Calculating hyperbolic distance from " << src << " to " << dest);
akmhoquedcee9362014-08-05 22:58:01 -0500468
Vince Lehman9a709032014-09-13 16:28:07 -0500469 double distance = UNKNOWN_DISTANCE;
470
471 ndn::Name srcLsaKey = src;
472 srcLsaKey.append("coordinate");
473
474 CoordinateLsa* srcLsa = lsdb.findCoordinateLsa(srcLsaKey);
475
476 ndn::Name destLsaKey = dest;
477 destLsaKey.append("coordinate");
478
479 CoordinateLsa* destLsa = lsdb.findCoordinateLsa(destLsaKey);
480
481 // Coordinate LSAs do not exist for these routers
482 if (srcLsa == NULL || destLsa == NULL) {
483 return UNKNOWN_DISTANCE;
akmhoquedcee9362014-08-05 22:58:01 -0500484 }
485
akmhoquedcee9362014-08-05 22:58:01 -0500486 double srcTheta = srcLsa->getCorTheta();
akmhoquedcee9362014-08-05 22:58:01 -0500487 double destTheta = destLsa->getCorTheta();
488
akmhoque53353462014-04-22 08:43:45 -0500489 double diffTheta = fabs(srcTheta - destTheta);
Vince Lehman9a709032014-09-13 16:28:07 -0500490
akmhoque157b0a42014-05-13 00:26:37 -0500491 if (diffTheta > MATH_PI) {
akmhoque53353462014-04-22 08:43:45 -0500492 diffTheta = 2 * MATH_PI - diffTheta;
493 }
Vince Lehman9a709032014-09-13 16:28:07 -0500494
495 double srcRadius = srcLsa->getCorRadius();
496 double destRadius = destLsa->getCorRadius();
497
498 if (srcRadius == UNKNOWN_RADIUS && destRadius == UNKNOWN_RADIUS) {
499 return UNKNOWN_DISTANCE;
500 }
501
502 if (diffTheta == 0) {
503 distance = fabs(srcRadius - destRadius);
akmhoque53353462014-04-22 08:43:45 -0500504 }
akmhoque157b0a42014-05-13 00:26:37 -0500505 else {
Vince Lehman9a709032014-09-13 16:28:07 -0500506 distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
507 (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
akmhoque53353462014-04-22 08:43:45 -0500508 }
Vince Lehman9a709032014-09-13 16:28:07 -0500509
510 _LOG_TRACE("Distance from " << src << " to " << dest << " is " << distance);
511
akmhoque53353462014-04-22 08:43:45 -0500512 return distance;
513}
514
Vince Lehman9a709032014-09-13 16:28:07 -0500515void HyperbolicRoutingCalculator::addNextHop(ndn::Name dest, std::string faceUri,
516 double cost, RoutingTable& rt)
akmhoque53353462014-04-22 08:43:45 -0500517{
Vince Lehman9a709032014-09-13 16:28:07 -0500518 NextHop hop(faceUri, cost);
Vince Lehman20fe4a92014-09-09 15:57:59 -0500519 hop.setHyperbolic(true);
akmhoque53353462014-04-22 08:43:45 -0500520
Vince Lehman9a709032014-09-13 16:28:07 -0500521 _LOG_TRACE("Calculated " << hop << " for destination: " << dest);
akmhoque53353462014-04-22 08:43:45 -0500522
Vince Lehman9a709032014-09-13 16:28:07 -0500523 if (m_isDryRun) {
524 rt.addNextHopToDryTable(dest, hop);
525 }
526 else {
527 rt.addNextHop(dest, hop);
528 }
akmhoque53353462014-04-22 08:43:45 -0500529}
530
Nick Gordonfad8e252016-08-11 14:21:38 -0500531} // namespace nlsr