blob: 00db7b7ebf727b30215b09943f5f716135f3ca2f [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014 University of Memphis,
4 * Regents of the University of California
5 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
21 *
22 **/
akmhoque53353462014-04-22 08:43:45 -050023#include <iostream>
24#include <cmath>
25#include "lsdb.hpp"
26#include "routing-table-calculator.hpp"
27#include "map.hpp"
28#include "lsa.hpp"
29#include "nexthop.hpp"
30#include "nlsr.hpp"
akmhoque2f423352014-06-03 11:49:35 -050031#include "logger.hpp"
akmhoque53353462014-04-22 08:43:45 -050032
33namespace nlsr {
34
akmhoque2f423352014-06-03 11:49:35 -050035INIT_LOGGER("RoutingTableCalculator");
akmhoque53353462014-04-22 08:43:45 -050036using namespace std;
37
38void
39RoutingTableCalculator::allocateAdjMatrix()
40{
41 adjMatrix = new double*[numOfRouter];
akmhoque157b0a42014-05-13 00:26:37 -050042 for (int i = 0; i < numOfRouter; ++i) {
akmhoque53353462014-04-22 08:43:45 -050043 adjMatrix[i] = new double[numOfRouter];
44 }
45}
46
47void
48RoutingTableCalculator::initMatrix()
49{
akmhoque157b0a42014-05-13 00:26:37 -050050 for (int i = 0; i < numOfRouter; i++) {
51 for (int j = 0; j < numOfRouter; j++) {
akmhoque53353462014-04-22 08:43:45 -050052 adjMatrix[i][j] = 0;
akmhoque157b0a42014-05-13 00:26:37 -050053 }
akmhoque53353462014-04-22 08:43:45 -050054 }
55}
56
57void
58RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
59{
60 std::list<AdjLsa> adjLsdb = pnlsr.getLsdb().getAdjLsdb();
61 for (std::list<AdjLsa>::iterator it = adjLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -050062 it != adjLsdb.end() ; it++) {
akmhoque31d1d4b2014-05-05 22:08:14 -050063 int row = pMap.getMappingNoByRouterName((*it).getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -050064 std::list<Adjacent> adl = (*it).getAdl().getAdjList();
65 for (std::list<Adjacent>::iterator itAdl = adl.begin();
akmhoque157b0a42014-05-13 00:26:37 -050066 itAdl != adl.end() ; itAdl++) {
akmhoque31d1d4b2014-05-05 22:08:14 -050067 int col = pMap.getMappingNoByRouterName((*itAdl).getName());
akmhoque53353462014-04-22 08:43:45 -050068 double cost = (*itAdl).getLinkCost();
akmhoque157b0a42014-05-13 00:26:37 -050069 if ((row >= 0 && row < numOfRouter) && (col >= 0 && col < numOfRouter)) {
akmhoque53353462014-04-22 08:43:45 -050070 adjMatrix[row][col] = cost;
71 }
72 }
73 }
74}
75
76void
akmhoque2f423352014-06-03 11:49:35 -050077RoutingTableCalculator::writeAdjMatrixLog()
akmhoque53353462014-04-22 08:43:45 -050078{
akmhoque157b0a42014-05-13 00:26:37 -050079 for (int i = 0; i < numOfRouter; i++) {
akmhoque2f423352014-06-03 11:49:35 -050080 string line="";
akmhoque157b0a42014-05-13 00:26:37 -050081 for (int j = 0; j < numOfRouter; j++) {
akmhoque2f423352014-06-03 11:49:35 -050082 line += boost::lexical_cast<std::string>(adjMatrix[i][j]);
83 line += " ";
akmhoque157b0a42014-05-13 00:26:37 -050084 }
akmhoque2f423352014-06-03 11:49:35 -050085 _LOG_DEBUG(line);
akmhoque53353462014-04-22 08:43:45 -050086 }
87}
88
89void
90RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
91{
akmhoque157b0a42014-05-13 00:26:37 -050092 for (int i = 0; i < numOfRouter; i++) {
93 if (i == link) {
akmhoque53353462014-04-22 08:43:45 -050094 adjMatrix[source][i] = linkCost;
95 }
akmhoque157b0a42014-05-13 00:26:37 -050096 else {
akmhoque53353462014-04-22 08:43:45 -050097 adjMatrix[source][i] = 0;
98 }
99 }
100}
101
102int
103RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
104{
105 int noLink = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500106 for (int i = 0; i < numOfRouter; i++) {
107 if (adjMatrix[sRouter][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -0500108 noLink++;
109 }
110 }
111 return noLink;
112}
113
114void
115RoutingTableCalculator::getLinksFromAdjMatrix(int* links,
116 double* linkCosts, int source)
117{
118 int j = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500119 for (int i = 0; i < numOfRouter; i++) {
120 if (adjMatrix[source][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -0500121 links[j] = i;
122 linkCosts[j] = adjMatrix[source][i];
123 j++;
124 }
125 }
126}
127
128void
129RoutingTableCalculator::freeAdjMatrix()
130{
akmhoque157b0a42014-05-13 00:26:37 -0500131 for (int i = 0; i < numOfRouter; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500132 delete [] adjMatrix[i];
133 }
134 delete [] adjMatrix;
135}
136
137
138void
139RoutingTableCalculator::allocateLinks()
140{
141 links = new int[vNoLink];
142}
143
144void
145RoutingTableCalculator::allocateLinkCosts()
146{
147 linkCosts = new double[vNoLink];
148}
149
150
151void
152RoutingTableCalculator::freeLinks()
153{
154 delete [] links;
155}
156void
157RoutingTableCalculator::freeLinksCosts()
158{
159 delete [] linkCosts;
160}
161
162void
163LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
164 RoutingTable& rt, Nlsr& pnlsr)
165{
akmhoque2f423352014-06-03 11:49:35 -0500166 _LOG_DEBUG("LinkStateRoutingTableCalculator::calculatePath Called");
akmhoque53353462014-04-22 08:43:45 -0500167 allocateAdjMatrix();
168 initMatrix();
169 makeAdjMatrix(pnlsr, pMap);
akmhoque2f423352014-06-03 11:49:35 -0500170 writeAdjMatrixLog();
akmhoque31d1d4b2014-05-05 22:08:14 -0500171 int sourceRouter = pMap.getMappingNoByRouterName(pnlsr.getConfParameter().getRouterPrefix());
akmhoque53353462014-04-22 08:43:45 -0500172 allocateParent();
173 allocateDistance();
akmhoque157b0a42014-05-13 00:26:37 -0500174 if (pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1) {
akmhoque53353462014-04-22 08:43:45 -0500175 // Single Path
176 doDijkstraPathCalculation(sourceRouter);
akmhoque53353462014-04-22 08:43:45 -0500177 // update routing table
178 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
179 }
akmhoque157b0a42014-05-13 00:26:37 -0500180 else {
akmhoque53353462014-04-22 08:43:45 -0500181 // Multi Path
182 setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
183 allocateLinks();
184 allocateLinkCosts();
185 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500186 for (int i = 0 ; i < vNoLink; i++) {
akmhoque53353462014-04-22 08:43:45 -0500187 adjustAdMatrix(sourceRouter, links[i], linkCosts[i]);
akmhoque2f423352014-06-03 11:49:35 -0500188 writeAdjMatrixLog();
akmhoque53353462014-04-22 08:43:45 -0500189 doDijkstraPathCalculation(sourceRouter);
akmhoque53353462014-04-22 08:43:45 -0500190 //update routing table
191 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
192 }
193 freeLinks();
194 freeLinksCosts();
195 }
196 freeParent();
197 freeDistance();
198 freeAdjMatrix();
199}
200
201void
202LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
203{
204 int i;
205 int v, u;
206 int* Q = new int[numOfRouter];
207 int head = 0;
208 /* Initiate the Parent */
akmhoque157b0a42014-05-13 00:26:37 -0500209 for (i = 0 ; i < numOfRouter; i++) {
akmhoque53353462014-04-22 08:43:45 -0500210 m_parent[i] = EMPTY_PARENT;
211 m_distance[i] = INF_DISTANCE;
212 Q[i] = i;
213 }
akmhoque157b0a42014-05-13 00:26:37 -0500214 if (sourceRouter != NO_MAPPING_NUM) {
akmhoque53353462014-04-22 08:43:45 -0500215 m_distance[sourceRouter] = 0;
216 sortQueueByDistance(Q, m_distance, head, numOfRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500217 while (head < numOfRouter) {
akmhoque53353462014-04-22 08:43:45 -0500218 u = Q[head];
akmhoque157b0a42014-05-13 00:26:37 -0500219 if (m_distance[u] == INF_DISTANCE) {
akmhoque53353462014-04-22 08:43:45 -0500220 break;
221 }
akmhoque157b0a42014-05-13 00:26:37 -0500222 for (v = 0 ; v < numOfRouter; v++) {
223 if (adjMatrix[u][v] > 0) {
224 if (isNotExplored(Q, v, head + 1, numOfRouter)) {
225 if (m_distance[u] + adjMatrix[u][v] < m_distance[v]) {
akmhoque53353462014-04-22 08:43:45 -0500226 m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
227 m_parent[v] = u;
228 }
229 }
230 }
231 }
232 head++;
233 sortQueueByDistance(Q, m_distance, head, numOfRouter);
234 }
235 }
236 delete [] Q;
237}
238
239void
240LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
241 RoutingTable& rt, Map& pMap, int sourceRouter)
242{
akmhoque2f423352014-06-03 11:49:35 -0500243 _LOG_DEBUG("LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called");
akmhoque53353462014-04-22 08:43:45 -0500244 int nextHopRouter = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500245 for (int i = 0; i < numOfRouter ; i++) {
246 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500247 nextHopRouter = getLsNextHop(i, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500248 if (nextHopRouter != NO_NEXT_HOP) {
akmhoque53353462014-04-22 08:43:45 -0500249 double routeCost = m_distance[i];
akmhoque31d1d4b2014-05-05 22:08:14 -0500250 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500251 std::string nextHopFace =
252 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500253 // Add next hop to routing table
akmhoque157b0a42014-05-13 00:26:37 -0500254 NextHop nh(nextHopFace, routeCost);
akmhoque53353462014-04-22 08:43:45 -0500255 rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
256 }
257 }
258 }
259}
260
261int
262LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
263{
264 int nextHop = NO_NEXT_HOP;
akmhoque157b0a42014-05-13 00:26:37 -0500265 while (m_parent[dest] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500266 nextHop = dest;
267 dest = m_parent[dest];
268 }
akmhoque157b0a42014-05-13 00:26:37 -0500269 if (dest != source) {
akmhoque53353462014-04-22 08:43:45 -0500270 nextHop = NO_NEXT_HOP;
271 }
272 return nextHop;
273}
274
275void
akmhoque53353462014-04-22 08:43:45 -0500276LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
akmhoque2f423352014-06-03 11:49:35 -0500277 double* dist,
278 int start, int element)
akmhoque53353462014-04-22 08:43:45 -0500279{
akmhoque157b0a42014-05-13 00:26:37 -0500280 for (int i = start ; i < element ; i++) {
281 for (int j = i + 1; j < element; j++) {
282 if (dist[Q[j]] < dist[Q[i]]) {
akmhoque53353462014-04-22 08:43:45 -0500283 int tempU = Q[j];
284 Q[j] = Q[i];
285 Q[i] = tempU;
286 }
287 }
288 }
289}
290
291int
292LinkStateRoutingTableCalculator::isNotExplored(int* Q,
293 int u, int start, int element)
294{
295 int ret = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500296 for (int i = start; i < element; i++) {
297 if (Q[i] == u) {
akmhoque53353462014-04-22 08:43:45 -0500298 ret = 1;
299 break;
300 }
301 }
302 return ret;
303}
304
305void
306LinkStateRoutingTableCalculator::allocateParent()
307{
308 m_parent = new int[numOfRouter];
309}
310
311void
312LinkStateRoutingTableCalculator::allocateDistance()
313{
314 m_distance = new double[numOfRouter];
315}
316
317void
318LinkStateRoutingTableCalculator::freeParent()
319{
320 delete [] m_parent;
321}
322
323void LinkStateRoutingTableCalculator::freeDistance()
324{
325 delete [] m_distance;
326}
327
328
329
330void
331HypRoutingTableCalculator::calculatePath(Map& pMap,
332 RoutingTable& rt, Nlsr& pnlsr)
333{
akmhoquedcee9362014-08-05 22:58:01 -0500334 allocateAdjMatrix();
335 initMatrix();
akmhoque53353462014-04-22 08:43:45 -0500336 makeAdjMatrix(pnlsr, pMap);
akmhoque31d1d4b2014-05-05 22:08:14 -0500337 ndn::Name routerName = pnlsr.getConfParameter().getRouterPrefix();
akmhoque53353462014-04-22 08:43:45 -0500338 int sourceRouter = pMap.getMappingNoByRouterName(routerName);
339 int noLink = getNumOfLinkfromAdjMatrix(sourceRouter);
340 setNoLink(noLink);
341 allocateLinks();
342 allocateLinkCosts();
343 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500344 for (int i = 0 ; i < numOfRouter ; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500345 int k = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500346 if (i != sourceRouter) {
akmhoquedcee9362014-08-05 22:58:01 -0500347 allocateNexthopRouters();
akmhoque53353462014-04-22 08:43:45 -0500348 allocateDistanceToNeighbor();
349 allocateDistFromNbrToDest();
akmhoque157b0a42014-05-13 00:26:37 -0500350 for (int j = 0; j < vNoLink; j++) {
akmhoque53353462014-04-22 08:43:45 -0500351 double distToNbr = getHyperbolicDistance(pnlsr, pMap,
352 sourceRouter, links[j]);
353 double distToDestFromNbr = getHyperbolicDistance(pnlsr,
354 pMap, links[j], i);
akmhoque157b0a42014-05-13 00:26:37 -0500355 if (distToDestFromNbr >= 0) {
akmhoquedcee9362014-08-05 22:58:01 -0500356 m_nexthopRouters[k] = links[j];
akmhoque53353462014-04-22 08:43:45 -0500357 m_distanceToNeighbor[k] = distToNbr;
358 m_distFromNbrToDest[k] = distToDestFromNbr;
359 k++;
360 }
361 }
362 addHypNextHopsToRoutingTable(pnlsr, pMap, rt, k, i);
akmhoquedcee9362014-08-05 22:58:01 -0500363 freeNexthopRouters();
akmhoque53353462014-04-22 08:43:45 -0500364 freeDistanceToNeighbor();
365 freeDistFromNbrToDest();
366 }
367 }
368 freeLinks();
369 freeLinksCosts();
370 freeAdjMatrix();
371}
372
373void
374HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
375 RoutingTable& rt, int noFaces, int dest)
376{
akmhoquedcee9362014-08-05 22:58:01 -0500377 ndn::Name destRouter = pMap.getRouterNameByMappingNo(dest);
akmhoque157b0a42014-05-13 00:26:37 -0500378 for (int i = 0 ; i < noFaces ; ++i) {
akmhoquedcee9362014-08-05 22:58:01 -0500379 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(m_nexthopRouters[i]);
380 std::string nextHopFaceUri =
381 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
382 NextHop nh(nextHopFaceUri, m_distFromNbrToDest[i]);
akmhoque157b0a42014-05-13 00:26:37 -0500383 if (m_isDryRun) {
akmhoque53353462014-04-22 08:43:45 -0500384 rt.addNextHopToDryTable(destRouter, nh);
385 }
akmhoquedcee9362014-08-05 22:58:01 -0500386 else {
387 rt.addNextHop(destRouter, nh);
388 }
akmhoque53353462014-04-22 08:43:45 -0500389 }
390}
391
392double
393HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
394 Map& pMap, int src, int dest)
395{
396 double distance = 0.0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500397 ndn::Name srcRouterKey = pMap.getRouterNameByMappingNo(src);
398 srcRouterKey.append("coordinate");
399 ndn::Name destRouterKey = pMap.getRouterNameByMappingNo(dest);
400 destRouterKey.append("coordinate");
akmhoquedcee9362014-08-05 22:58:01 -0500401 CoordinateLsa* srcLsa = pnlsr.getLsdb().findCoordinateLsa(srcRouterKey);
402 CoordinateLsa* destLsa = pnlsr.getLsdb().findCoordinateLsa(destRouterKey);
403
404 if ((srcLsa == 0) || (destLsa == 0)) {
405 return -1;
406 }
407
408 double srcRadius = srcLsa->getCorRadius();
409 double srcTheta = srcLsa->getCorTheta();
410 double destRadius = destLsa->getCorRadius();
411 double destTheta = destLsa->getCorTheta();
412
akmhoque53353462014-04-22 08:43:45 -0500413 double diffTheta = fabs(srcTheta - destTheta);
akmhoque157b0a42014-05-13 00:26:37 -0500414 if (diffTheta > MATH_PI) {
akmhoque53353462014-04-22 08:43:45 -0500415 diffTheta = 2 * MATH_PI - diffTheta;
416 }
akmhoque157b0a42014-05-13 00:26:37 -0500417 if (srcRadius != -1 && destRadius != -1) {
418 if (diffTheta == 0) {
akmhoque53353462014-04-22 08:43:45 -0500419 distance = fabs(srcRadius - destRadius);
akmhoque157b0a42014-05-13 00:26:37 -0500420 }
421 else {
akmhoque53353462014-04-22 08:43:45 -0500422 distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
423 (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
akmhoque157b0a42014-05-13 00:26:37 -0500424 }
akmhoque53353462014-04-22 08:43:45 -0500425 }
akmhoque157b0a42014-05-13 00:26:37 -0500426 else {
akmhoque53353462014-04-22 08:43:45 -0500427 distance = -1;
428 }
429 return distance;
430}
431
432void
akmhoquedcee9362014-08-05 22:58:01 -0500433HypRoutingTableCalculator::allocateNexthopRouters()
akmhoque53353462014-04-22 08:43:45 -0500434{
akmhoquedcee9362014-08-05 22:58:01 -0500435 m_nexthopRouters = new uint32_t[vNoLink];
akmhoque53353462014-04-22 08:43:45 -0500436}
437
438void
439HypRoutingTableCalculator::allocateDistanceToNeighbor()
440{
441 m_distanceToNeighbor = new double[vNoLink];
442}
443
444void
445HypRoutingTableCalculator::allocateDistFromNbrToDest()
446{
447 m_distFromNbrToDest = new double[vNoLink];
448}
449
450void
akmhoquedcee9362014-08-05 22:58:01 -0500451HypRoutingTableCalculator::freeNexthopRouters()
akmhoque53353462014-04-22 08:43:45 -0500452{
akmhoquedcee9362014-08-05 22:58:01 -0500453 delete [] m_nexthopRouters;
akmhoque53353462014-04-22 08:43:45 -0500454}
455
456void
457HypRoutingTableCalculator::freeDistanceToNeighbor()
458{
459 delete [] m_distanceToNeighbor;
460}
461
462void
463HypRoutingTableCalculator::freeDistFromNbrToDest()
464{
465 delete [] m_distFromNbrToDest;
466}
467
468}//namespace nlsr