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