blob: 57bf6b29486205dabb809414de132f8055cf753c [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 //printAdjMatrix();
171 writeAdjMatrixLog();
akmhoque31d1d4b2014-05-05 22:08:14 -0500172 int sourceRouter = pMap.getMappingNoByRouterName(pnlsr.getConfParameter().getRouterPrefix());
akmhoque53353462014-04-22 08:43:45 -0500173 allocateParent();
174 allocateDistance();
akmhoque157b0a42014-05-13 00:26:37 -0500175 if (pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1) {
akmhoque53353462014-04-22 08:43:45 -0500176 // Single Path
177 doDijkstraPathCalculation(sourceRouter);
akmhoque53353462014-04-22 08:43:45 -0500178 // update routing table
179 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
180 }
akmhoque157b0a42014-05-13 00:26:37 -0500181 else {
akmhoque53353462014-04-22 08:43:45 -0500182 // Multi Path
183 setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
184 allocateLinks();
185 allocateLinkCosts();
186 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500187 for (int i = 0 ; i < vNoLink; i++) {
akmhoque53353462014-04-22 08:43:45 -0500188 adjustAdMatrix(sourceRouter, links[i], linkCosts[i]);
akmhoque2f423352014-06-03 11:49:35 -0500189 writeAdjMatrixLog();
akmhoque53353462014-04-22 08:43:45 -0500190 doDijkstraPathCalculation(sourceRouter);
akmhoque53353462014-04-22 08:43:45 -0500191 //update routing table
192 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
193 }
194 freeLinks();
195 freeLinksCosts();
196 }
197 freeParent();
198 freeDistance();
199 freeAdjMatrix();
200}
201
202void
203LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
204{
205 int i;
206 int v, u;
207 int* Q = new int[numOfRouter];
208 int head = 0;
209 /* Initiate the Parent */
akmhoque157b0a42014-05-13 00:26:37 -0500210 for (i = 0 ; i < numOfRouter; i++) {
akmhoque53353462014-04-22 08:43:45 -0500211 m_parent[i] = EMPTY_PARENT;
212 m_distance[i] = INF_DISTANCE;
213 Q[i] = i;
214 }
akmhoque157b0a42014-05-13 00:26:37 -0500215 if (sourceRouter != NO_MAPPING_NUM) {
akmhoque53353462014-04-22 08:43:45 -0500216 m_distance[sourceRouter] = 0;
217 sortQueueByDistance(Q, m_distance, head, numOfRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500218 while (head < numOfRouter) {
akmhoque53353462014-04-22 08:43:45 -0500219 u = Q[head];
akmhoque157b0a42014-05-13 00:26:37 -0500220 if (m_distance[u] == INF_DISTANCE) {
akmhoque53353462014-04-22 08:43:45 -0500221 break;
222 }
akmhoque157b0a42014-05-13 00:26:37 -0500223 for (v = 0 ; v < numOfRouter; v++) {
224 if (adjMatrix[u][v] > 0) {
225 if (isNotExplored(Q, v, head + 1, numOfRouter)) {
226 if (m_distance[u] + adjMatrix[u][v] < m_distance[v]) {
akmhoque53353462014-04-22 08:43:45 -0500227 m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
228 m_parent[v] = u;
229 }
230 }
231 }
232 }
233 head++;
234 sortQueueByDistance(Q, m_distance, head, numOfRouter);
235 }
236 }
237 delete [] Q;
238}
239
240void
241LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
242 RoutingTable& rt, Map& pMap, int sourceRouter)
243{
akmhoque2f423352014-06-03 11:49:35 -0500244 _LOG_DEBUG("LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called");
akmhoque53353462014-04-22 08:43:45 -0500245 int nextHopRouter = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500246 for (int i = 0; i < numOfRouter ; i++) {
247 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500248 nextHopRouter = getLsNextHop(i, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500249 if (nextHopRouter != NO_NEXT_HOP) {
akmhoque53353462014-04-22 08:43:45 -0500250 double routeCost = m_distance[i];
akmhoque31d1d4b2014-05-05 22:08:14 -0500251 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500252 std::string nextHopFace =
253 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500254 // Add next hop to routing table
akmhoque157b0a42014-05-13 00:26:37 -0500255 NextHop nh(nextHopFace, routeCost);
akmhoque53353462014-04-22 08:43:45 -0500256 rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
257 }
258 }
259 }
260}
261
262int
263LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
264{
265 int nextHop = NO_NEXT_HOP;
akmhoque157b0a42014-05-13 00:26:37 -0500266 while (m_parent[dest] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500267 nextHop = dest;
268 dest = m_parent[dest];
269 }
akmhoque157b0a42014-05-13 00:26:37 -0500270 if (dest != source) {
akmhoque53353462014-04-22 08:43:45 -0500271 nextHop = NO_NEXT_HOP;
272 }
273 return nextHop;
274}
275
276void
akmhoque53353462014-04-22 08:43:45 -0500277LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
akmhoque2f423352014-06-03 11:49:35 -0500278 double* dist,
279 int start, int element)
akmhoque53353462014-04-22 08:43:45 -0500280{
akmhoque157b0a42014-05-13 00:26:37 -0500281 for (int i = start ; i < element ; i++) {
282 for (int j = i + 1; j < element; j++) {
283 if (dist[Q[j]] < dist[Q[i]]) {
akmhoque53353462014-04-22 08:43:45 -0500284 int tempU = Q[j];
285 Q[j] = Q[i];
286 Q[i] = tempU;
287 }
288 }
289 }
290}
291
292int
293LinkStateRoutingTableCalculator::isNotExplored(int* Q,
294 int u, int start, int element)
295{
296 int ret = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500297 for (int i = start; i < element; i++) {
298 if (Q[i] == u) {
akmhoque53353462014-04-22 08:43:45 -0500299 ret = 1;
300 break;
301 }
302 }
303 return ret;
304}
305
306void
307LinkStateRoutingTableCalculator::allocateParent()
308{
309 m_parent = new int[numOfRouter];
310}
311
312void
313LinkStateRoutingTableCalculator::allocateDistance()
314{
315 m_distance = new double[numOfRouter];
316}
317
318void
319LinkStateRoutingTableCalculator::freeParent()
320{
321 delete [] m_parent;
322}
323
324void LinkStateRoutingTableCalculator::freeDistance()
325{
326 delete [] m_distance;
327}
328
329
330
331void
332HypRoutingTableCalculator::calculatePath(Map& pMap,
333 RoutingTable& rt, Nlsr& pnlsr)
334{
335 makeAdjMatrix(pnlsr, pMap);
akmhoque2f423352014-06-03 11:49:35 -0500336 //std::cout << 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) {
akmhoque53353462014-04-22 08:43:45 -0500347 allocateLinkFaces();
348 allocateDistanceToNeighbor();
349 allocateDistFromNbrToDest();
akmhoque157b0a42014-05-13 00:26:37 -0500350 for (int j = 0; j < vNoLink; j++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500351 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(links[j]);
akmhoque157b0a42014-05-13 00:26:37 -0500352 std::string nextHopFaceUri =
353 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500354 double distToNbr = getHyperbolicDistance(pnlsr, pMap,
355 sourceRouter, links[j]);
356 double distToDestFromNbr = getHyperbolicDistance(pnlsr,
357 pMap, links[j], i);
akmhoque157b0a42014-05-13 00:26:37 -0500358 if (distToDestFromNbr >= 0) {
359 m_linkFaceUris[k] = nextHopFaceUri;
akmhoque53353462014-04-22 08:43:45 -0500360 m_distanceToNeighbor[k] = distToNbr;
361 m_distFromNbrToDest[k] = distToDestFromNbr;
362 k++;
363 }
364 }
365 addHypNextHopsToRoutingTable(pnlsr, pMap, rt, k, i);
366 freeLinkFaces();
367 freeDistanceToNeighbor();
368 freeDistFromNbrToDest();
369 }
370 }
371 freeLinks();
372 freeLinksCosts();
373 freeAdjMatrix();
374}
375
376void
377HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
378 RoutingTable& rt, int noFaces, int dest)
379{
akmhoque157b0a42014-05-13 00:26:37 -0500380 for (int i = 0 ; i < noFaces ; ++i) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500381 ndn::Name destRouter = pMap.getRouterNameByMappingNo(dest);
akmhoque157b0a42014-05-13 00:26:37 -0500382 NextHop nh(m_linkFaceUris[i], m_distFromNbrToDest[i]);
akmhoque53353462014-04-22 08:43:45 -0500383 rt.addNextHop(destRouter, nh);
akmhoque157b0a42014-05-13 00:26:37 -0500384 if (m_isDryRun) {
akmhoque53353462014-04-22 08:43:45 -0500385 rt.addNextHopToDryTable(destRouter, nh);
386 }
387 }
388}
389
390double
391HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
392 Map& pMap, int src, int dest)
393{
394 double distance = 0.0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500395 ndn::Name srcRouterKey = pMap.getRouterNameByMappingNo(src);
396 srcRouterKey.append("coordinate");
397 ndn::Name destRouterKey = pMap.getRouterNameByMappingNo(dest);
398 destRouterKey.append("coordinate");
akmhoqueb6450b12014-04-24 00:01:03 -0500399 double srcRadius = (pnlsr.getLsdb().findCoordinateLsa(
400 srcRouterKey))->getCorRadius();
401 double srcTheta = (pnlsr.getLsdb().findCoordinateLsa(
402 srcRouterKey))->getCorTheta();
403 double destRadius = (pnlsr.getLsdb().findCoordinateLsa(
404 destRouterKey))->getCorRadius();
405 double destTheta = (pnlsr.getLsdb().findCoordinateLsa(
406 destRouterKey))->getCorTheta();
akmhoque53353462014-04-22 08:43:45 -0500407 double diffTheta = fabs(srcTheta - destTheta);
akmhoque157b0a42014-05-13 00:26:37 -0500408 if (diffTheta > MATH_PI) {
akmhoque53353462014-04-22 08:43:45 -0500409 diffTheta = 2 * MATH_PI - diffTheta;
410 }
akmhoque157b0a42014-05-13 00:26:37 -0500411 if (srcRadius != -1 && destRadius != -1) {
412 if (diffTheta == 0) {
akmhoque53353462014-04-22 08:43:45 -0500413 distance = fabs(srcRadius - destRadius);
akmhoque157b0a42014-05-13 00:26:37 -0500414 }
415 else {
akmhoque53353462014-04-22 08:43:45 -0500416 distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
417 (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
akmhoque157b0a42014-05-13 00:26:37 -0500418 }
akmhoque53353462014-04-22 08:43:45 -0500419 }
akmhoque157b0a42014-05-13 00:26:37 -0500420 else {
akmhoque53353462014-04-22 08:43:45 -0500421 distance = -1;
422 }
423 return distance;
424}
425
426void
427HypRoutingTableCalculator::allocateLinkFaces()
428{
akmhoque157b0a42014-05-13 00:26:37 -0500429 m_linkFaceUris.reserve(vNoLink);
akmhoque53353462014-04-22 08:43:45 -0500430}
431
432void
433HypRoutingTableCalculator::allocateDistanceToNeighbor()
434{
435 m_distanceToNeighbor = new double[vNoLink];
436}
437
438void
439HypRoutingTableCalculator::allocateDistFromNbrToDest()
440{
441 m_distFromNbrToDest = new double[vNoLink];
442}
443
444void
445HypRoutingTableCalculator::freeLinkFaces()
446{
akmhoque157b0a42014-05-13 00:26:37 -0500447 m_linkFaceUris.clear();
akmhoque53353462014-04-22 08:43:45 -0500448}
449
450void
451HypRoutingTableCalculator::freeDistanceToNeighbor()
452{
453 delete [] m_distanceToNeighbor;
454}
455
456void
457HypRoutingTableCalculator::freeDistFromNbrToDest()
458{
459 delete [] m_distFromNbrToDest;
460}
461
462}//namespace nlsr