routing-table-calculator.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
23 #include "lsdb.hpp"
24 #include "map.hpp"
25 #include "nexthop.hpp"
26 #include "nlsr.hpp"
27 #include "logger.hpp"
28 #include "adjacent.hpp"
29 
30 #include <iostream>
31 #include <boost/math/constants/constants.hpp>
32 #include <ndn-cxx/util/logger.hpp>
33 #include <cmath>
34 
35 namespace nlsr {
36 
37 INIT_LOGGER(route.RoutingTableCalculator);
38 
39 const int LinkStateRoutingTableCalculator::EMPTY_PARENT = -12345;
40 const double LinkStateRoutingTableCalculator::INF_DISTANCE = 2147483647;
41 const int LinkStateRoutingTableCalculator::NO_MAPPING_NUM = -1;
43 
44 void
46 {
47  adjMatrix = new double*[m_nRouters];
48 
49  for (size_t i = 0; i < m_nRouters; ++i) {
50  adjMatrix[i] = new double[m_nRouters];
51  }
52 }
53 
54 void
56 {
57  for (size_t i = 0; i < m_nRouters; i++) {
58  for (size_t j = 0; j < m_nRouters; j++) {
60  }
61  }
62 }
63 
64 void
65 RoutingTableCalculator::makeAdjMatrix(const std::list<AdjLsa>& adjLsaList, Map& pMap)
66 {
67  // For each LSA represented in the map
68  for (const auto& adjLsa : adjLsaList) {
69  ndn::optional<int32_t> row = pMap.getMappingNoByRouterName(adjLsa.getOrigRouter());
70 
71  std::list<Adjacent> adl = adjLsa.getAdl().getAdjList();
72  // For each adjacency represented in the LSA
73  for (const auto& adjacent : adl) {
74  ndn::optional<int32_t> col = pMap.getMappingNoByRouterName(adjacent.getName());
75  double cost = adjacent.getLinkCost();
76 
77  if (row && col && *row < static_cast<int32_t>(m_nRouters)
78  && *col < static_cast<int32_t>(m_nRouters))
79  {
80  adjMatrix[*row][*col] = cost;
81  }
82  }
83  }
84 
85  // Links that do not have the same cost for both directions should
86  // have their costs corrected:
87  //
88  // If the cost of one side of the link is NON_ADJACENT_COST (i.e. broken) or negative,
89  // both direction of the link should have their cost corrected to NON_ADJACENT_COST.
90  //
91  // Otherwise, both sides of the link should use the larger of the two costs.
92  //
93  // Additionally, this means that we can halve the amount of space
94  // that the matrix uses by only maintaining a triangle.
95  // - But that is not yet implemented.
96  for (size_t row = 0; row < m_nRouters; ++row) {
97  for (size_t col = 0; col < m_nRouters; ++col) {
98  double toCost = adjMatrix[row][col];
99  double fromCost = adjMatrix[col][row];
100 
101  if (fromCost != toCost) {
102  double correctedCost = Adjacent::NON_ADJACENT_COST;
103 
104  if (toCost >= 0 && fromCost >= 0) {
105  // If both sides of the link are up, use the larger cost else break the link
106  correctedCost = std::max(toCost, fromCost);
107  }
108 
109  NLSR_LOG_WARN("Cost between [" << row << "][" << col << "] and [" << col << "][" << row <<
110  "] are not the same (" << toCost << " != " << fromCost << "). " <<
111  "Correcting to cost: " << correctedCost);
112 
113  adjMatrix[row][col] = correctedCost;
114  adjMatrix[col][row] = correctedCost;
115  }
116  }
117  }
118 }
119 
120 void
122 {
123  if (!ndn_cxx_getLogger().isLevelEnabled(ndn::util::LogLevel::DEBUG)) {
124  return;
125  }
126 
127  NLSR_LOG_DEBUG("-----------Legend (routerName -> index)------");
128  std::string routerIndex;
129  std::string indexToNameMapping;
130  std::string lengthOfDash = "--";
131 
132  for (size_t i = 0; i < m_nRouters; i++) {
133  routerIndex += boost::lexical_cast<std::string>(i);
134  routerIndex += " ";
135  lengthOfDash += "--";
136  NLSR_LOG_DEBUG("Router:" + map.getRouterNameByMappingNo(i)->toUri() +
137  " Index:" + boost::lexical_cast<std::string>(i));
138  }
139  NLSR_LOG_DEBUG(" |" + routerIndex);
140  NLSR_LOG_DEBUG(lengthOfDash);
141 
142  for (size_t i = 0; i < m_nRouters; i++) {
143  std::string line;
144  for (size_t j = 0; j < m_nRouters; j++) {
145  if (adjMatrix[i][j] == LinkStateRoutingTableCalculator::NO_NEXT_HOP) {
146  line += "0 ";
147  }
148  else {
149  line += boost::lexical_cast<std::string>(adjMatrix[i][j]);
150  line += " ";
151  }
152  }
153  line = boost::lexical_cast<std::string>(i) + "|" + line;
154  NLSR_LOG_DEBUG(line);
155  }
156 }
157 
158 void
159 RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
160 {
161  for (int i = 0; i < static_cast<int>(m_nRouters); i++) {
162  if (i == link) {
163  adjMatrix[source][i] = linkCost;
164  }
165  else {
166  // if "i" is not a link to the source, set it's cost to a non adjacent value.
168  }
169  }
170 }
171 
172 int
174 {
175  int noLink = 0;
176 
177  for (size_t i = 0; i < m_nRouters; i++) {
178  if (adjMatrix[sRouter][i] >= 0 && i != static_cast<size_t>(sRouter)) { // make sure "i" is not self
179  noLink++;
180  }
181  }
182  return noLink;
183 }
184 
185 void
187  double* linkCosts, int source)
188 {
189  int j = 0;
190 
191  for (size_t i = 0; i < m_nRouters; i++) {
192  if (adjMatrix[source][i] >= 0 && i != static_cast<size_t>(source)) {// make sure "i" is not self
193  links[j] = i;
194  linkCosts[j] = adjMatrix[source][i];
195  j++;
196  }
197  }
198 }
199 
200 void
202 {
203  for (size_t i = 0; i < m_nRouters; ++i) {
204  delete [] adjMatrix[i];
205  }
206  delete [] adjMatrix;
207 }
208 
209 void
211 {
212  links = new int[vNoLink];
213 }
214 
215 void
217 {
218  linkCosts = new double[vNoLink];
219 }
220 
221 
222 void
224 {
225  delete [] links;
226 }
227 void
229 {
230  delete [] linkCosts;
231 }
232 
233 void
235  ConfParameter& confParam,
236  const std::list<AdjLsa>& adjLsaList)
237 {
238  NLSR_LOG_DEBUG("LinkStateRoutingTableCalculator::calculatePath Called");
240  initMatrix();
241  makeAdjMatrix(adjLsaList, pMap);
242  writeAdjMatrixLog(pMap);
243  ndn::optional<int32_t> sourceRouter =
244  pMap.getMappingNoByRouterName(confParam.getRouterPrefix());
245  allocateParent(); // These two matrices are used in Dijkstra's algorithm.
246  allocateDistance(); //
247  // We only bother to do the calculation if we have a router by that name.
248  if (sourceRouter && confParam.getMaxFacesPerPrefix() == 1) {
249  // In the single path case we can simply run Dijkstra's algorithm.
250  doDijkstraPathCalculation(*sourceRouter);
251  // Inform the routing table of the new next hops.
252  addAllLsNextHopsToRoutingTable(confParam.getAdjacencyList(), rt, pMap, *sourceRouter);
253  }
254  else {
255  // Multi Path
256  setNoLink(getNumOfLinkfromAdjMatrix(*sourceRouter));
257  allocateLinks();
259  // Gets a sparse listing of adjacencies for path calculation
260  getLinksFromAdjMatrix(links, linkCosts, *sourceRouter);
261  for (int i = 0 ; i < vNoLink; i++) {
262  // Simulate that only the current neighbor is accessible
263  adjustAdMatrix(*sourceRouter, links[i], linkCosts[i]);
264  writeAdjMatrixLog(pMap);
265  // Do Dijkstra's algorithm using the current neighbor as your start.
266  doDijkstraPathCalculation(*sourceRouter);
267  // Update the routing table with the calculations.
268  addAllLsNextHopsToRoutingTable(confParam.getAdjacencyList(), rt, pMap, *sourceRouter);
269  }
270  freeLinks();
271  freeLinksCosts();
272  }
273  freeParent();
274  freeDistance();
275  freeAdjMatrix();
276 }
277 
278 void
279 LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
280 {
281  int i;
282  int v, u;
283  int* Q = new int[m_nRouters]; // Each cell represents the router with that mapping no.
284  int head = 0;
285  // Initiate the parent
286  for (i = 0 ; i < static_cast<int>(m_nRouters); i++) {
287  m_parent[i] = EMPTY_PARENT;
288  // Array where the ith element is the distance to the router with mapping no i.
289  m_distance[i] = INF_DISTANCE;
290  Q[i] = i;
291  }
292  if (sourceRouter != NO_MAPPING_NUM) {
293  // Distance to source from source is always 0.
294  m_distance[sourceRouter] = 0;
295  sortQueueByDistance(Q, m_distance, head, m_nRouters);
296  // While we haven't visited every node.
297  while (head < static_cast<int>(m_nRouters)) {
298  u = Q[head]; // Set u to be the current node pointed to by head.
299  if (m_distance[u] == INF_DISTANCE) {
300  break; // This can only happen when there are no accessible nodes.
301  }
302  // Iterate over the adjacent nodes to u.
303  for (v = 0 ; v < static_cast<int>(m_nRouters); v++) {
304  // If the current node is accessible.
305  if (adjMatrix[u][v] >= 0) {
306  // And we haven't visited it yet.
307  if (isNotExplored(Q, v, head + 1, m_nRouters)) {
308  // And if the distance to this node + from this node to v
309  // is less than the distance from our source node to v
310  // that we got when we built the adj LSAs
311  if (m_distance[u] + adjMatrix[u][v] < m_distance[v]) {
312  // Set the new distance
313  m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
314  // Set how we get there.
315  m_parent[v] = u;
316  }
317  }
318  }
319  }
320  // Increment the head position, resort the list by distance from where we are.
321  head++;
322  sortQueueByDistance(Q, m_distance, head, m_nRouters);
323  }
324  }
325  delete [] Q;
326 }
327 
328 void
329 LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(AdjacencyList& adjacencies,
330  RoutingTable& rt, Map& pMap,
331  uint32_t sourceRouter)
332 {
333  NLSR_LOG_DEBUG("LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called");
334 
335  int nextHopRouter = 0;
336 
337  // For each router we have
338  for (size_t i = 0; i < m_nRouters ; i++) {
339  if (i != sourceRouter) {
340 
341  // Obtain the next hop that was determined by the algorithm
342  nextHopRouter = getLsNextHop(i, sourceRouter);
343  // If this router is accessible at all
344  if (nextHopRouter != NO_NEXT_HOP) {
345 
346  // Fetch its distance
347  double routeCost = m_distance[i];
348  // Fetch its actual name
349  ndn::optional<ndn::Name> nextHopRouterName= pMap.getRouterNameByMappingNo(nextHopRouter);
350  if (nextHopRouterName) {
351  std::string nextHopFace =
352  adjacencies.getAdjacent(*nextHopRouterName).getFaceUri().toString();
353  // Add next hop to routing table
354  NextHop nh(nextHopFace, routeCost);
355  rt.addNextHop(*(pMap.getRouterNameByMappingNo(i)), nh);
356 
357  }
358  }
359  }
360  }
361 }
362 
363 int
364 LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
365 {
366  int nextHop = NO_NEXT_HOP;
367  while (m_parent[dest] != EMPTY_PARENT) {
368  nextHop = dest;
369  dest = m_parent[dest];
370  }
371  if (dest != source) {
372  nextHop = NO_NEXT_HOP;
373  }
374  return nextHop;
375 }
376 
377 void
378 LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
379  double* dist,
380  int start, int element)
381 {
382  for (int i = start ; i < element ; i++) {
383  for (int j = i + 1; j < element; j++) {
384  if (dist[Q[j]] < dist[Q[i]]) {
385  int tempU = Q[j];
386  Q[j] = Q[i];
387  Q[i] = tempU;
388  }
389  }
390  }
391 }
392 
393 int
394 LinkStateRoutingTableCalculator::isNotExplored(int* Q,
395  int u, int start, int element)
396 {
397  int ret = 0;
398  for (int i = start; i < element; i++) {
399  if (Q[i] == u) {
400  ret = 1;
401  break;
402  }
403  }
404  return ret;
405 }
406 
407 void
408 LinkStateRoutingTableCalculator::allocateParent()
409 {
410  m_parent = new int[m_nRouters];
411 }
412 
413 void
414 LinkStateRoutingTableCalculator::allocateDistance()
415 {
416  m_distance = new double[m_nRouters];
417 }
418 
419 void
420 LinkStateRoutingTableCalculator::freeParent()
421 {
422  delete [] m_parent;
423 }
424 
425 void LinkStateRoutingTableCalculator::freeDistance()
426 {
427  delete [] m_distance;
428 }
429 
430 const double HyperbolicRoutingCalculator::MATH_PI = boost::math::constants::pi<double>();
431 
432 const double HyperbolicRoutingCalculator::UNKNOWN_DISTANCE = -1.0;
433 const double HyperbolicRoutingCalculator::UNKNOWN_RADIUS = -1.0;
434 
435 void
437  Lsdb& lsdb, AdjacencyList& adjacencies)
438 {
439  NLSR_LOG_TRACE("Calculating hyperbolic paths");
440 
441  ndn::optional<int32_t> thisRouter = map.getMappingNoByRouterName(m_thisRouterName);
442 
443  // Iterate over directly connected neighbors
444  std::list<Adjacent> neighbors = adjacencies.getAdjList();
445  for (std::list<Adjacent>::iterator adj = neighbors.begin(); adj != neighbors.end(); ++adj) {
446 
447  // Don't calculate nexthops using an inactive router
448  if (adj->getStatus() == Adjacent::STATUS_INACTIVE) {
449  NLSR_LOG_TRACE(adj->getName() << " is inactive; not using it as a nexthop");
450  continue;
451  }
452 
453  ndn::Name srcRouterName = adj->getName();
454 
455  // Don't calculate nexthops for this router to other routers
456  if (srcRouterName == m_thisRouterName) {
457  continue;
458  }
459 
460  std::string srcFaceUri = adj->getFaceUri().toString();
461 
462  // Install nexthops for this router to the neighbor; direct neighbors have a 0 cost link
463  addNextHop(srcRouterName, srcFaceUri, 0, rt);
464 
465  ndn::optional<int32_t> src = map.getMappingNoByRouterName(srcRouterName);
466 
467  if (!src) {
468  NLSR_LOG_WARN(adj->getName() << " does not exist in the router map!");
469  continue;
470  }
471 
472  // Get hyperbolic distance from direct neighbor to every other router
473  for (int dest = 0; dest < static_cast<int>(m_nRouters); ++dest) {
474  // Don't calculate nexthops to this router or from a router to itself
475  if (thisRouter && dest != *thisRouter && dest != *src) {
476 
477  ndn::optional<ndn::Name> destRouterName = map.getRouterNameByMappingNo(dest);
478  if (destRouterName) {
479  double distance = getHyperbolicDistance(lsdb, srcRouterName, *destRouterName);
480 
481  // Could not compute distance
482  if (distance == UNKNOWN_DISTANCE) {
483  NLSR_LOG_WARN("Could not calculate hyperbolic distance from " << srcRouterName
484  << " to " << *destRouterName);
485  continue;
486  }
487  addNextHop(*destRouterName, srcFaceUri, distance, rt);
488  }
489  }
490  }
491  }
492 }
493 
494 double
495 HyperbolicRoutingCalculator::getHyperbolicDistance(Lsdb& lsdb, ndn::Name src, ndn::Name dest)
496 {
497  NLSR_LOG_TRACE("Calculating hyperbolic distance from " << src << " to " << dest);
498 
499  double distance = UNKNOWN_DISTANCE;
500 
501  ndn::Name srcLsaKey = src;
502  srcLsaKey.append(std::to_string(Lsa::Type::COORDINATE));
503 
504  CoordinateLsa* srcLsa = lsdb.findCoordinateLsa(srcLsaKey);
505 
506  ndn::Name destLsaKey = dest;
507  destLsaKey.append(std::to_string(Lsa::Type::COORDINATE));
508 
509  CoordinateLsa* destLsa = lsdb.findCoordinateLsa(destLsaKey);
510 
511  // Coordinate LSAs do not exist for these routers
512  if (srcLsa == nullptr || destLsa == nullptr) {
513  return UNKNOWN_DISTANCE;
514  }
515 
516  std::vector<double> srcTheta = srcLsa->getCorTheta();
517  std::vector<double> destTheta = destLsa->getCorTheta();
518 
519  double srcRadius = srcLsa->getCorRadius();
520  double destRadius = destLsa->getCorRadius();
521 
522  double diffTheta = calculateAngularDistance(srcTheta, destTheta);
523 
524  if (srcRadius == UNKNOWN_RADIUS || destRadius == UNKNOWN_RADIUS ||
525  diffTheta == UNKNOWN_DISTANCE) {
526  return UNKNOWN_DISTANCE;
527  }
528 
529  // double r_i, double r_j, double delta_theta, double zeta = 1 (default)
530  distance = calculateHyperbolicDistance(srcRadius, destRadius, diffTheta);
531 
532  NLSR_LOG_TRACE("Distance from " << src << " to " << dest << " is " << distance);
533 
534  return distance;
535 }
536 
537 double
538 HyperbolicRoutingCalculator::calculateAngularDistance(std::vector<double> angleVectorI,
539  std::vector<double> angleVectorJ)
540 {
541  // It is not possible for angle vector size to be zero as ensured by conf-file-processor
542 
543  // https://en.wikipedia.org/wiki/N-sphere#Spherical_coordinates
544 
545  // Check if two vector lengths are the same
546  if (angleVectorI.size() != angleVectorJ.size()) {
547  NLSR_LOG_ERROR("Angle vector sizes do not match");
548  return UNKNOWN_DISTANCE;
549  }
550 
551  // Check if all angles are within the [0, PI] and [0, 2PI] ranges
552  if (angleVectorI.size() > 1) {
553  for (unsigned int k = 0; k < angleVectorI.size() - 1; k++) {
554  if ((angleVectorI[k] > M_PI && angleVectorI[k] < 0.0) ||
555  (angleVectorJ[k] > M_PI && angleVectorJ[k] < 0.0)) {
556  NLSR_LOG_ERROR("Angle outside [0, PI]");
557  return UNKNOWN_DISTANCE;
558  }
559  }
560  }
561  if (angleVectorI[angleVectorI.size()-1] > 2.*M_PI ||
562  angleVectorI[angleVectorI.size()-1] < 0.0) {
563  NLSR_LOG_ERROR("Angle not within [0, 2PI]");
564  return UNKNOWN_DISTANCE;
565  }
566 
567  if (angleVectorI[angleVectorI.size()-1] > 2.*M_PI ||
568  angleVectorI[angleVectorI.size()-1] < 0.0) {
569  NLSR_LOG_ERROR("Angle not within [0, 2PI]");
570  return UNKNOWN_DISTANCE;
571  }
572 
573  // deltaTheta = arccos(vectorI . vectorJ) -> do the inner product
574  double innerProduct = 0.0;
575 
576  // Calculate x0 of the vectors
577  double x0i = std::cos(angleVectorI[0]);
578  double x0j = std::cos(angleVectorJ[0]);
579 
580  // Calculate xn of the vectors
581  double xni = std::sin(angleVectorI[angleVectorI.size() - 1]);
582  double xnj = std::sin(angleVectorJ[angleVectorJ.size() - 1]);
583 
584  // Do the aggregation of the (n-1) coordinates (if there is more than one angle)
585  // i.e contraction of all (n-1)-dimensional angular coordinates to one variable
586  for (unsigned int k = 0; k < angleVectorI.size() - 1; k++) {
587  xni *= std::sin(angleVectorI[k]);
588  xnj *= std::sin(angleVectorJ[k]);
589  }
590  innerProduct += (x0i * x0j) + (xni * xnj);
591 
592  // If d > 1
593  if (angleVectorI.size() > 1) {
594  for (unsigned int m = 1; m < angleVectorI.size(); m++) {
595  // calculate euclidean coordinates given the angles and assuming R_sphere = 1
596  double xmi = std::cos(angleVectorI[m]);
597  double xmj = std::cos(angleVectorJ[m]);
598  for (unsigned int l = 0; l < m; l++) {
599  xmi *= std::sin(angleVectorI[l]);
600  xmj *= std::sin(angleVectorJ[l]);
601  }
602  innerProduct += xmi * xmj;
603  }
604  }
605 
606  // ArcCos of the inner product gives the angular distance
607  // between two points on a d-dimensional sphere
608  return std::acos(innerProduct);
609 }
610 
611 double
612 HyperbolicRoutingCalculator::calculateHyperbolicDistance(double rI, double rJ,
613  double deltaTheta)
614 {
615  if (deltaTheta == UNKNOWN_DISTANCE) {
616  return UNKNOWN_DISTANCE;
617  }
618 
619  // Usually, we set zeta = 1 in all experiments
620  double zeta = 1;
621 
622  if (deltaTheta <= 0.0 || rI <= 0.0 || rJ <= 0.0) {
623  NLSR_LOG_ERROR("Delta theta or rI or rJ is <= 0");
624  NLSR_LOG_ERROR("Please make sure that no two nodes have the exact same HR coordinates");
625  return UNKNOWN_DISTANCE;
626  }
627 
628  double xij = (1. / zeta) * std::acosh(std::cosh(zeta*rI) * std::cosh(zeta*rJ) -
629  std::sinh(zeta*rI)*std::sinh(zeta*rJ)*std::cos(deltaTheta));
630  return xij;
631 }
632 
633 void
634 HyperbolicRoutingCalculator::addNextHop(ndn::Name dest, std::string faceUri,
635  double cost, RoutingTable& rt)
636 {
637  NextHop hop(faceUri, cost);
638  hop.setHyperbolic(true);
639 
640  NLSR_LOG_TRACE("Calculated " << hop << " for destination: " << dest);
641 
642  if (m_isDryRun) {
643  rt.addNextHopToDryTable(dest, hop);
644  }
645  else {
646  rt.addNextHop(dest, hop);
647  }
648 }
649 
650 } // namespace nlsr
void writeAdjMatrixLog(const Map &map) const
Writes a formated adjacent matrix to DEBUG log.
#define NLSR_LOG_WARN(x)
Definition: logger.hpp:40
A class to house all the configuration parameters for NLSR.
void getLinksFromAdjMatrix(int *links, double *linkCosts, int source)
Populates temp. variables with the link costs for some router.
ndn::optional< ndn::Name > getRouterNameByMappingNo(int32_t mn) const
Definition: map.cpp:48
void calculatePath(Map &map, RoutingTable &rt, Lsdb &lsdb, AdjacencyList &adjacencies)
const ndn::FaceUri & getFaceUri() const
Definition: adjacent.hpp:69
void allocateAdjMatrix()
Allocate the space needed for the adj. matrix.
void adjustAdMatrix(int source, int link, double linkCost)
Adjust a link cost in the adj. matrix.
static const double NON_ADJACENT_COST
Definition: adjacent.hpp:158
AdjacencyList & getAdjacencyList()
ndn::optional< int32_t > getMappingNoByRouterName(const ndn::Name &rName)
Definition: map.cpp:61
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:38
const ndn::Name & getRouterPrefix() const
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
Adjacent getAdjacent(const ndn::Name &adjName)
#define INIT_LOGGER(name)
Definition: logger.hpp:35
void makeAdjMatrix(const std::list< AdjLsa > &adjLsaList, Map &pMap)
Constructs an adj. matrix to calculate with.
uint32_t getMaxFacesPerPrefix() const
void initMatrix()
set NON_ADJACENT_COST i.e. -12345 to every cell of the matrix to ensure that the memory is safe...
CoordinateLsa * findCoordinateLsa(const ndn::Name &key)
Finds a cor. LSA in the LSDB.
Definition: lsdb.cpp:383
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
Copyright (c) 2014-2019, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
void calculatePath(Map &pMap, RoutingTable &rt, ConfParameter &confParam, const std::list< AdjLsa > &adjLsaList)
const std::vector< double > getCorTheta() const
Definition: lsa.hpp:346
void addNextHopToDryTable(const ndn::Name &destRouter, NextHop &nh)
Adds a next hop to a routing table entry in a dry run scenario.
int getNumOfLinkfromAdjMatrix(int sRouter)
Returns how many links a router in the matrix has.
void setHyperbolic(bool b)
void addNextHop(const ndn::Name &destRouter, NextHop &nh)
Adds a next hop to a routing table entry.
std::list< Adjacent > & getAdjList()
#define NLSR_LOG_TRACE(x)
Definition: logger.hpp:37
double getCorRadius() const
Definition: lsa.hpp:334