blob: 1c39d5143bc472e56d8458717e1e97bc6ff84189 [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 std::cout << std::endl;
246 int nextHopRouter = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500247 for (int i = 0; i < numOfRouter ; i++) {
248 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500249 nextHopRouter = getLsNextHop(i, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500250 if (nextHopRouter != NO_NEXT_HOP) {
akmhoque53353462014-04-22 08:43:45 -0500251 double routeCost = m_distance[i];
akmhoque31d1d4b2014-05-05 22:08:14 -0500252 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500253 std::string nextHopFace =
254 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500255 // Add next hop to routing table
akmhoque157b0a42014-05-13 00:26:37 -0500256 NextHop nh(nextHopFace, routeCost);
akmhoque53353462014-04-22 08:43:45 -0500257 rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
258 }
259 }
260 }
261}
262
263int
264LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
265{
266 int nextHop = NO_NEXT_HOP;
akmhoque157b0a42014-05-13 00:26:37 -0500267 while (m_parent[dest] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500268 nextHop = dest;
269 dest = m_parent[dest];
270 }
akmhoque157b0a42014-05-13 00:26:37 -0500271 if (dest != source) {
akmhoque53353462014-04-22 08:43:45 -0500272 nextHop = NO_NEXT_HOP;
273 }
274 return nextHop;
275}
276
277void
akmhoque53353462014-04-22 08:43:45 -0500278LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
akmhoque2f423352014-06-03 11:49:35 -0500279 double* dist,
280 int start, int element)
akmhoque53353462014-04-22 08:43:45 -0500281{
akmhoque157b0a42014-05-13 00:26:37 -0500282 for (int i = start ; i < element ; i++) {
283 for (int j = i + 1; j < element; j++) {
284 if (dist[Q[j]] < dist[Q[i]]) {
akmhoque53353462014-04-22 08:43:45 -0500285 int tempU = Q[j];
286 Q[j] = Q[i];
287 Q[i] = tempU;
288 }
289 }
290 }
291}
292
293int
294LinkStateRoutingTableCalculator::isNotExplored(int* Q,
295 int u, int start, int element)
296{
297 int ret = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500298 for (int i = start; i < element; i++) {
299 if (Q[i] == u) {
akmhoque53353462014-04-22 08:43:45 -0500300 ret = 1;
301 break;
302 }
303 }
304 return ret;
305}
306
307void
308LinkStateRoutingTableCalculator::allocateParent()
309{
310 m_parent = new int[numOfRouter];
311}
312
313void
314LinkStateRoutingTableCalculator::allocateDistance()
315{
316 m_distance = new double[numOfRouter];
317}
318
319void
320LinkStateRoutingTableCalculator::freeParent()
321{
322 delete [] m_parent;
323}
324
325void LinkStateRoutingTableCalculator::freeDistance()
326{
327 delete [] m_distance;
328}
329
330
331
332void
333HypRoutingTableCalculator::calculatePath(Map& pMap,
334 RoutingTable& rt, Nlsr& pnlsr)
335{
336 makeAdjMatrix(pnlsr, pMap);
akmhoque2f423352014-06-03 11:49:35 -0500337 //std::cout << pMap;
akmhoque31d1d4b2014-05-05 22:08:14 -0500338 ndn::Name routerName = pnlsr.getConfParameter().getRouterPrefix();
akmhoque53353462014-04-22 08:43:45 -0500339 int sourceRouter = pMap.getMappingNoByRouterName(routerName);
340 int noLink = getNumOfLinkfromAdjMatrix(sourceRouter);
341 setNoLink(noLink);
342 allocateLinks();
343 allocateLinkCosts();
344 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500345 for (int i = 0 ; i < numOfRouter ; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500346 int k = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500347 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500348 allocateLinkFaces();
349 allocateDistanceToNeighbor();
350 allocateDistFromNbrToDest();
akmhoque157b0a42014-05-13 00:26:37 -0500351 for (int j = 0; j < vNoLink; j++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500352 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(links[j]);
akmhoque157b0a42014-05-13 00:26:37 -0500353 std::string nextHopFaceUri =
354 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500355 double distToNbr = getHyperbolicDistance(pnlsr, pMap,
356 sourceRouter, links[j]);
357 double distToDestFromNbr = getHyperbolicDistance(pnlsr,
358 pMap, links[j], i);
akmhoque157b0a42014-05-13 00:26:37 -0500359 if (distToDestFromNbr >= 0) {
360 m_linkFaceUris[k] = nextHopFaceUri;
akmhoque53353462014-04-22 08:43:45 -0500361 m_distanceToNeighbor[k] = distToNbr;
362 m_distFromNbrToDest[k] = distToDestFromNbr;
363 k++;
364 }
365 }
366 addHypNextHopsToRoutingTable(pnlsr, pMap, rt, k, i);
367 freeLinkFaces();
368 freeDistanceToNeighbor();
369 freeDistFromNbrToDest();
370 }
371 }
372 freeLinks();
373 freeLinksCosts();
374 freeAdjMatrix();
375}
376
377void
378HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
379 RoutingTable& rt, int noFaces, int dest)
380{
akmhoque157b0a42014-05-13 00:26:37 -0500381 for (int i = 0 ; i < noFaces ; ++i) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500382 ndn::Name destRouter = pMap.getRouterNameByMappingNo(dest);
akmhoque157b0a42014-05-13 00:26:37 -0500383 NextHop nh(m_linkFaceUris[i], m_distFromNbrToDest[i]);
akmhoque53353462014-04-22 08:43:45 -0500384 rt.addNextHop(destRouter, nh);
akmhoque157b0a42014-05-13 00:26:37 -0500385 if (m_isDryRun) {
akmhoque53353462014-04-22 08:43:45 -0500386 rt.addNextHopToDryTable(destRouter, nh);
387 }
388 }
389}
390
391double
392HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
393 Map& pMap, int src, int dest)
394{
395 double distance = 0.0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500396 ndn::Name srcRouterKey = pMap.getRouterNameByMappingNo(src);
397 srcRouterKey.append("coordinate");
398 ndn::Name destRouterKey = pMap.getRouterNameByMappingNo(dest);
399 destRouterKey.append("coordinate");
akmhoqueb6450b12014-04-24 00:01:03 -0500400 double srcRadius = (pnlsr.getLsdb().findCoordinateLsa(
401 srcRouterKey))->getCorRadius();
402 double srcTheta = (pnlsr.getLsdb().findCoordinateLsa(
403 srcRouterKey))->getCorTheta();
404 double destRadius = (pnlsr.getLsdb().findCoordinateLsa(
405 destRouterKey))->getCorRadius();
406 double destTheta = (pnlsr.getLsdb().findCoordinateLsa(
407 destRouterKey))->getCorTheta();
akmhoque53353462014-04-22 08:43:45 -0500408 double diffTheta = fabs(srcTheta - destTheta);
akmhoque157b0a42014-05-13 00:26:37 -0500409 if (diffTheta > MATH_PI) {
akmhoque53353462014-04-22 08:43:45 -0500410 diffTheta = 2 * MATH_PI - diffTheta;
411 }
akmhoque157b0a42014-05-13 00:26:37 -0500412 if (srcRadius != -1 && destRadius != -1) {
413 if (diffTheta == 0) {
akmhoque53353462014-04-22 08:43:45 -0500414 distance = fabs(srcRadius - destRadius);
akmhoque157b0a42014-05-13 00:26:37 -0500415 }
416 else {
akmhoque53353462014-04-22 08:43:45 -0500417 distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
418 (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
akmhoque157b0a42014-05-13 00:26:37 -0500419 }
akmhoque53353462014-04-22 08:43:45 -0500420 }
akmhoque157b0a42014-05-13 00:26:37 -0500421 else {
akmhoque53353462014-04-22 08:43:45 -0500422 distance = -1;
423 }
424 return distance;
425}
426
427void
428HypRoutingTableCalculator::allocateLinkFaces()
429{
akmhoque157b0a42014-05-13 00:26:37 -0500430 m_linkFaceUris.reserve(vNoLink);
akmhoque53353462014-04-22 08:43:45 -0500431}
432
433void
434HypRoutingTableCalculator::allocateDistanceToNeighbor()
435{
436 m_distanceToNeighbor = new double[vNoLink];
437}
438
439void
440HypRoutingTableCalculator::allocateDistFromNbrToDest()
441{
442 m_distFromNbrToDest = new double[vNoLink];
443}
444
445void
446HypRoutingTableCalculator::freeLinkFaces()
447{
akmhoque157b0a42014-05-13 00:26:37 -0500448 m_linkFaceUris.clear();
akmhoque53353462014-04-22 08:43:45 -0500449}
450
451void
452HypRoutingTableCalculator::freeDistanceToNeighbor()
453{
454 delete [] m_distanceToNeighbor;
455}
456
457void
458HypRoutingTableCalculator::freeDistFromNbrToDest()
459{
460 delete [] m_distFromNbrToDest;
461}
462
463}//namespace nlsr