A Discrete-Event Network Simulator
API
dsr-rcache.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Yufei Cheng
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
18  * Song Luan <lsuper@mail.ustc.edu.cn> (Implemented Link Cache using Dijsktra
19  * algorithm)
20  *
21  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
22  * ResiliNets Research Group https://resilinets.org/
23  * Information and Telecommunication Technology Center (ITTC)
24  * and Department of Electrical Engineering and Computer Science
25  * The University of Kansas Lawrence, KS USA.
26  *
27  * Work supported in part by NSF FIND (Future Internet Design) Program
28  * under grant CNS-0626918 (Postmodern Internet Architecture),
29  * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
30  * US Department of Defense (DoD), and ITTC at The University of Kansas.
31  */
32 
33 #include "dsr-rcache.h"
34 
35 #include "ns3/address-utils.h"
36 #include "ns3/ipv4-route.h"
37 #include "ns3/log.h"
38 #include "ns3/packet.h"
39 #include "ns3/simulator.h"
40 #include "ns3/socket.h"
41 #include "ns3/wifi-mac-header.h"
42 
43 #include <algorithm>
44 #include <cmath>
45 #include <functional>
46 #include <iomanip>
47 #include <iostream>
48 #include <list>
49 #include <map>
50 #include <vector>
51 
52 namespace ns3
53 {
54 
55 NS_LOG_COMPONENT_DEFINE("DsrRouteCache");
56 
57 namespace dsr
58 {
59 
60 bool
62 {
63  // compare based on both with hop count considered priority
64  return (a.GetVector().size() < b.GetVector().size()) ||
65  ((a.GetVector().size() == b.GetVector().size()) &&
66  (a.GetExpireTime() > b.GetExpireTime()));
67 }
68 
69 bool
71 {
72  // compare based on hops
73  return a.GetVector().size() < b.GetVector().size();
74 }
75 
76 bool
78 {
79  // compare based on expire time
80  return a.GetExpireTime() > b.GetExpireTime();
81 }
82 
83 void
84 Link::Print() const
85 {
86  NS_LOG_DEBUG(m_low << "----" << m_high);
87 }
88 
90  : m_nodeStability(nodeStab + Simulator::Now())
91 {
92 }
93 
95 {
96 }
97 
99  : m_linkStability(linkStab + Simulator::Now())
100 {
101 }
102 
104 {
105 }
106 
107 void
109 {
110  NS_LOG_LOGIC("LifeTime: " << GetLinkStability().As(Time::S));
111 }
112 
113 typedef std::list<DsrRouteCacheEntry>::value_type route_pair;
114 
116  : m_ackTimer(Timer::CANCEL_ON_DESTROY),
117  m_dst(dst),
118  m_path(ip),
119  m_expire(exp + Simulator::Now()),
120  m_reqCount(0),
121  m_blackListState(false),
122  m_blackListTimeout(Simulator::Now())
123 {
124 }
125 
127 {
128 }
129 
130 void
132 {
133  m_reqCount = 0;
134  m_expire = badLinkLifetime + Simulator::Now();
135 }
136 
137 void
138 DsrRouteCacheEntry::Print(std::ostream& os) const
139 {
140  os << m_dst << "\t" << (m_expire - Simulator::Now()).As(Time::S) << "\t";
141 }
142 
144 
145 TypeId
147 {
148  static TypeId tid = TypeId("ns3::dsr::DsrRouteCache")
149  .SetParent<Object>()
150  .SetGroupName("Dsr")
151  .AddConstructor<DsrRouteCache>();
152  return tid;
153 }
154 
156  : m_vector(0),
157  m_maxEntriesEachDst(3),
158  m_isLinkCache(false),
159  m_ntimer(Timer::CANCEL_ON_DESTROY),
160  m_delay(MilliSeconds(100))
161 {
162  /*
163  * The timer to set layer 2 notification, not fully supported by ns3 yet
164  */
167 }
168 
170 {
172  // clear the route cache when done
173  m_sortedRoutes.clear();
174 }
175 
176 void
177 DsrRouteCache::RemoveLastEntry(std::list<DsrRouteCacheEntry>& rtVector)
178 {
179  NS_LOG_FUNCTION(this);
180  // Release the last entry of route list
181  rtVector.pop_back();
182 }
183 
184 bool
186 {
187  NS_LOG_FUNCTION(this << dst);
188  auto i = m_sortedRoutes.find(dst);
189  if (i == m_sortedRoutes.end())
190  {
191  NS_LOG_LOGIC("Failed to find the route entry for the destination " << dst);
192  return false;
193  }
194  else
195  {
196  std::list<DsrRouteCacheEntry> rtVector = i->second;
197  DsrRouteCacheEntry successEntry = rtVector.front();
198  successEntry.SetExpireTime(RouteCacheTimeout);
199  rtVector.pop_front();
200  rtVector.push_back(successEntry);
201  rtVector.sort(CompareRoutesExpire); // sort the route vector first
202  m_sortedRoutes.erase(dst); // erase the entry first
203  /*
204  * Save the new route cache along with the destination address in map
205  */
206  auto result = m_sortedRoutes.insert(std::make_pair(dst, rtVector));
207  return result.second;
208  }
209  return false;
210 }
211 
212 bool
214 {
215  NS_LOG_FUNCTION(this << id);
216  if (IsLinkCache())
217  {
218  return LookupRoute_Link(id, rt);
219  }
220 
221  Purge(); // Purge first to remove expired entries
222  if (m_sortedRoutes.empty())
223  {
224  NS_LOG_LOGIC("Route to " << id << " not found; m_sortedRoutes is empty");
225  return false;
226  }
227  auto i = m_sortedRoutes.find(id);
228  if (i == m_sortedRoutes.end())
229  {
230  NS_LOG_LOGIC("No Direct Route to " << id << " found");
231  for (auto j = m_sortedRoutes.begin(); j != m_sortedRoutes.end(); ++j)
232  {
233  std::list<DsrRouteCacheEntry> rtVector =
234  j->second; // The route cache vector linked with destination address
235  /*
236  * Loop through the possibly multiple routes within the route vector
237  */
238  for (auto k = rtVector.begin(); k != rtVector.end(); ++k)
239  {
240  // return the first route in the route vector
242  DsrRouteCacheEntry::IP_VECTOR changeVector;
243 
244  for (auto l = routeVector.begin(); l != routeVector.end(); ++l)
245  {
246  changeVector.push_back(*l);
247 
248  if (*l == id)
249  {
250  break;
251  }
252  }
253  /*
254  * When the changed vector is smaller in size and larger than 1, which means we
255  * have found a route with the destination address we are looking for
256  */
257  if ((changeVector.size() < routeVector.size()) && (changeVector.size() > 1))
258  {
259  DsrRouteCacheEntry changeEntry; // Create the route entry
260  changeEntry.SetVector(changeVector);
261  changeEntry.SetDestination(id);
262  // Use the expire time from original route entry
263  changeEntry.SetExpireTime(k->GetExpireTime());
264  // We need to add new route entry here
265  std::list<DsrRouteCacheEntry> newVector;
266  newVector.push_back(changeEntry);
267  newVector.sort(CompareRoutesExpire); // sort the route vector first
268  m_sortedRoutes[id] =
269  newVector; // Only get the first sub route and add it in route cache
270  NS_LOG_INFO("We have a sub-route to " << id << " add it in route cache");
271  }
272  }
273  }
274  }
275  NS_LOG_INFO("Here we check the route cache again after updated the sub routes");
276  auto m = m_sortedRoutes.find(id);
277  if (m == m_sortedRoutes.end())
278  {
279  NS_LOG_LOGIC("No updated route till last time");
280  return false;
281  }
282  /*
283  * We have a direct route to the destination address
284  */
285  std::list<DsrRouteCacheEntry> rtVector = m->second;
286  rt = rtVector.front(); // use the first entry in the route vector
287  NS_LOG_LOGIC("Route to " << id << " with route size " << rtVector.size());
288  return true;
289 }
290 
291 void
293 {
294  NS_LOG_FUNCTION(this << type);
295  if (type == "LinkCache")
296  {
297  m_isLinkCache = true;
298  }
299  else if (type == "PathCache")
300  {
301  m_isLinkCache = false;
302  }
303  else
304  {
305  m_isLinkCache = true; // use link cache as default
306  NS_LOG_INFO("Error Cache Type");
307  }
308 }
309 
310 bool
312 {
313  NS_LOG_FUNCTION(this);
314  return m_isLinkCache;
315 }
316 
317 void
319 {
320  NS_LOG_FUNCTION(this << source);
324  // @d shortest-path estimate
325  std::map<Ipv4Address, uint32_t> d;
326  // @pre preceding node
327  std::map<Ipv4Address, Ipv4Address> pre;
328  for (auto i = m_netGraph.begin(); i != m_netGraph.end(); ++i)
329  {
330  if (i->second.find(source) != i->second.end())
331  {
332  d[i->first] = i->second[source];
333  pre[i->first] = source;
334  }
335  else
336  {
337  d[i->first] = MAXWEIGHT;
338  pre[i->first] = Ipv4Address("255.255.255.255");
339  }
340  }
341  d[source] = 0;
345  // the node set which shortest distance has been calculated, if true calculated
346  std::map<Ipv4Address, bool> s;
347  double temp = MAXWEIGHT;
348  Ipv4Address tempip("255.255.255.255");
349  for (uint32_t i = 0; i < m_netGraph.size(); i++)
350  {
351  temp = MAXWEIGHT;
352  for (auto j = d.begin(); j != d.end(); ++j)
353  {
354  Ipv4Address ip = j->first;
355  if (s.find(ip) == s.end())
356  {
357  /*
358  * \brief The following are for comparison
359  */
360  if (j->second <= temp)
361  {
362  temp = j->second;
363  tempip = ip;
364  }
365  }
366  }
367  if (!tempip.IsBroadcast())
368  {
369  s[tempip] = true;
370  for (auto k = m_netGraph[tempip].begin(); k != m_netGraph[tempip].end(); ++k)
371  {
372  if (s.find(k->first) == s.end() && d[k->first] > d[tempip] + k->second)
373  {
374  d[k->first] = d[tempip] + k->second;
375  pre[k->first] = tempip;
376  }
377  /*
378  * Selects the shortest-length route that has the longest expected lifetime
379  * (highest minimum timeout of any link in the route)
380  * For the computation overhead and complexity
381  * Here I just implement kind of greedy strategy to select link with the longest
382  * expected lifetime when there is two options
383  */
384  else if (d[k->first] == d[tempip] + k->second)
385  {
386  auto oldlink = m_linkCache.find(Link(k->first, pre[k->first]));
387  auto newlink = m_linkCache.find(Link(k->first, tempip));
388  if (oldlink != m_linkCache.end() && newlink != m_linkCache.end())
389  {
390  if (oldlink->second.GetLinkStability() < newlink->second.GetLinkStability())
391  {
392  NS_LOG_INFO("Select the link with longest expected lifetime");
393  d[k->first] = d[tempip] + k->second;
394  pre[k->first] = tempip;
395  }
396  }
397  else
398  {
399  NS_LOG_INFO("Link Stability Info Corrupt");
400  }
401  }
402  }
403  }
404  }
405  // clean the best route table
406  m_bestRoutesTable_link.clear();
407  for (auto i = pre.begin(); i != pre.end(); ++i)
408  {
409  // loop for all vertices
411  Ipv4Address iptemp = i->first;
412 
413  if (!i->second.IsBroadcast() && iptemp != source)
414  {
415  while (iptemp != source)
416  {
417  route.push_back(iptemp);
418  iptemp = pre[iptemp];
419  }
420  route.push_back(source);
421  // Reverse the route
422  DsrRouteCacheEntry::IP_VECTOR reverseroute(route.rbegin(), route.rend());
423  NS_LOG_LOGIC("Add newly calculated best routes");
424  PrintVector(reverseroute);
425  m_bestRoutesTable_link[i->first] = reverseroute;
426  }
427  }
428 }
429 
430 bool
432 {
433  NS_LOG_FUNCTION(this << id);
435  PurgeLinkNode();
436  auto i = m_bestRoutesTable_link.find(id);
437  if (i == m_bestRoutesTable_link.end())
438  {
439  NS_LOG_INFO("No route find to " << id);
440  return false;
441  }
442 
443  if (i->second.size() < 2)
444  {
445  NS_LOG_LOGIC("Route to " << id << " error");
446  return false;
447  }
448 
449  DsrRouteCacheEntry newEntry; // Create the route entry
450  newEntry.SetVector(i->second);
451  newEntry.SetDestination(id);
453  NS_LOG_INFO("Route to " << id << " found with the length " << i->second.size());
454  rt = newEntry;
455  std::vector<Ipv4Address> path = rt.GetVector();
456  PrintVector(path);
457  return true;
458 }
459 
460 void
462 {
463  NS_LOG_FUNCTION(this);
464  for (auto i = m_linkCache.begin(); i != m_linkCache.end();)
465  {
466  NS_LOG_DEBUG("The link stability " << i->second.GetLinkStability().As(Time::S));
467  auto itmp = i;
468  if (i->second.GetLinkStability() <= Seconds(0))
469  {
470  ++i;
471  m_linkCache.erase(itmp);
472  }
473  else
474  {
475  ++i;
476  }
477  }
479  for (auto i = m_nodeCache.begin(); i != m_nodeCache.end();)
480  {
481  NS_LOG_DEBUG("The node stability " << i->second.GetNodeStability().As(Time::S));
482  auto itmp = i;
483  if (i->second.GetNodeStability() <= Seconds(0))
484  {
485  ++i;
486  m_nodeCache.erase(itmp);
487  }
488  else
489  {
490  ++i;
491  }
492  }
493 }
494 
495 void
497 {
498  NS_LOG_FUNCTION(this);
499  m_netGraph.clear();
500  for (auto i = m_linkCache.begin(); i != m_linkCache.end(); ++i)
501  {
502  // Here the weight is set as 1
504  uint32_t weight = 1;
505  m_netGraph[i->first.m_low][i->first.m_high] = weight;
506  m_netGraph[i->first.m_high][i->first.m_low] = weight;
507  }
508 }
509 
510 bool
512 {
513  NS_LOG_FUNCTION(this << node);
514  auto i = m_nodeCache.find(node);
515  if (i == m_nodeCache.end())
516  {
517  NS_LOG_INFO("The initial stability " << m_initStability.As(Time::S));
519  m_nodeCache[node] = ns;
520  return false;
521  }
522  else
523  {
525  NS_LOG_INFO("The node stability " << i->second.GetNodeStability().As(Time::S));
526  NS_LOG_INFO("The stability here "
527  << Time(i->second.GetNodeStability() * m_stabilityIncrFactor).As(Time::S));
528  DsrNodeStab ns(Time(i->second.GetNodeStability() * m_stabilityIncrFactor));
529  m_nodeCache[node] = ns;
530  return true;
531  }
532  return false;
533 }
534 
535 bool
537 {
538  NS_LOG_FUNCTION(this << node);
539  auto i = m_nodeCache.find(node);
540  if (i == m_nodeCache.end())
541  {
543  m_nodeCache[node] = ns;
544  return false;
545  }
546  else
547  {
549  NS_LOG_INFO("The stability here " << i->second.GetNodeStability().As(Time::S));
550  NS_LOG_INFO("The stability here "
551  << Time(i->second.GetNodeStability() / m_stabilityDecrFactor).As(Time::S));
552  DsrNodeStab ns(Time(i->second.GetNodeStability() / m_stabilityDecrFactor));
553  m_nodeCache[node] = ns;
554  return true;
555  }
556  return false;
557 }
558 
559 bool
561 {
562  NS_LOG_FUNCTION(this << source);
563  NS_LOG_LOGIC("Use Link Cache");
565  PurgeLinkNode();
566  for (uint32_t i = 0; i < nodelist.size() - 1; i++)
567  {
568  DsrNodeStab ns;
570 
571  if (m_nodeCache.find(nodelist[i]) == m_nodeCache.end())
572  {
573  m_nodeCache[nodelist[i]] = ns;
574  }
575  if (m_nodeCache.find(nodelist[i + 1]) == m_nodeCache.end())
576  {
577  m_nodeCache[nodelist[i + 1]] = ns;
578  }
579  Link link(nodelist[i], nodelist[i + 1]);
580  DsrLinkStab stab;
583  if (m_nodeCache[nodelist[i]].GetNodeStability() <
584  m_nodeCache[nodelist[i + 1]].GetNodeStability())
585  {
586  stab.SetLinkStability(m_nodeCache[nodelist[i]].GetNodeStability());
587  }
588  else
589  {
590  stab.SetLinkStability(m_nodeCache[nodelist[i + 1]].GetNodeStability());
591  }
592  if (stab.GetLinkStability() < m_minLifeTime)
593  {
594  NS_LOG_LOGIC("Stability: " << stab.GetLinkStability().As(Time::S));
597  }
598  m_linkCache[link] = stab;
599  NS_LOG_DEBUG("Add a new link");
600  link.Print();
601  NS_LOG_DEBUG("Link Info");
602  stab.Print();
603  }
604  UpdateNetGraph();
605  RebuildBestRouteTable(source);
606  return true;
607 }
608 
609 void
611 {
612  NS_LOG_FUNCTION(this);
614  PurgeLinkNode();
615  if (rt.size() < 2)
616  {
617  NS_LOG_INFO("The route is too short");
618  return;
619  }
620  for (auto i = rt.begin(); i != rt.end() - 1; ++i)
621  {
622  Link link(*i, *(i + 1));
623  if (m_linkCache.find(link) != m_linkCache.end())
624  {
625  if (m_linkCache[link].GetLinkStability() < m_useExtends)
626  {
627  m_linkCache[link].SetLinkStability(m_useExtends);
629  NS_LOG_INFO("The time of the link "
630  << m_linkCache[link].GetLinkStability().As(Time::S));
631  }
632  }
633  else
634  {
635  NS_LOG_INFO("We cannot find a link in cache");
636  }
637  }
639  for (auto i = rt.begin(); i != rt.end(); ++i)
640  {
641  if (m_nodeCache.find(*i) != m_nodeCache.end())
642  {
643  NS_LOG_LOGIC("Increase the stability");
644  if (m_nodeCache[*i].GetNodeStability() <= m_initStability)
645  {
646  IncStability(*i);
647  }
648  else
649  {
650  NS_LOG_INFO("The node stability has already been increased");
651  }
652  }
653  }
654 }
655 
656 bool
658 {
659  NS_LOG_FUNCTION(this);
660  Purge();
661  std::list<DsrRouteCacheEntry> rtVector; // Declare the route cache entry vector
662  Ipv4Address dst = rt.GetDestination();
663  std::vector<Ipv4Address> route = rt.GetVector();
664 
665  NS_LOG_DEBUG("The route destination we have " << dst);
666  auto i = m_sortedRoutes.find(dst);
667 
668  if (i == m_sortedRoutes.end())
669  {
670  rtVector.push_back(rt);
671  m_sortedRoutes.erase(dst); // Erase the route entries for dst first
675  auto result = m_sortedRoutes.insert(std::make_pair(dst, rtVector));
676  return result.second;
677  }
678 
679  rtVector = i->second;
680  NS_LOG_DEBUG("The existing route size " << rtVector.size() << " for destination address "
681  << dst);
685  if (rtVector.size() >= m_maxEntriesEachDst)
686  {
687  RemoveLastEntry(rtVector); // Drop the last entry for the sorted route cache, the route
688  // has already been sorted
689  }
690 
691  if (FindSameRoute(rt, rtVector))
692  {
693  NS_LOG_DEBUG(
694  "Find same vector, the FindSameRoute function will update the route expire time");
695  return true;
696  }
697  else
698  {
699  // Check if the expire time for the new route has expired or not
700  if (rt.GetExpireTime() > Time(0))
701  {
702  rtVector.push_back(rt);
703  // This sort function will sort the route cache entries based on the size of route
704  // in each of the route entries
705  rtVector.sort(CompareRoutesExpire);
706  NS_LOG_DEBUG("The first time" << rtVector.front().GetExpireTime().As(Time::S)
707  << " The second time "
708  << rtVector.back().GetExpireTime().As(Time::S));
709  NS_LOG_DEBUG("The first hop" << rtVector.front().GetVector().size()
710  << " The second hop "
711  << rtVector.back().GetVector().size());
712  m_sortedRoutes.erase(dst); // erase the route entries for dst first
716  auto result = m_sortedRoutes.insert(std::make_pair(dst, rtVector));
717  return result.second;
718  }
719  else
720  {
721  NS_LOG_INFO("The newly found route is already expired");
722  }
723  }
724 
725  return false;
726 }
727 
728 bool
729 DsrRouteCache::FindSameRoute(DsrRouteCacheEntry& rt, std::list<DsrRouteCacheEntry>& rtVector)
730 {
731  NS_LOG_FUNCTION(this);
732  for (auto i = rtVector.begin(); i != rtVector.end(); ++i)
733  {
734  // return the first route in the route vector
736  DsrRouteCacheEntry::IP_VECTOR newVector = rt.GetVector();
737 
738  if (routeVector == newVector)
739  {
740  NS_LOG_DEBUG("Found same routes in the route cache with the vector size "
741  << rt.GetDestination() << " " << rtVector.size());
742  NS_LOG_DEBUG("The new route expire time " << rt.GetExpireTime().As(Time::S)
743  << " the original expire time "
744  << i->GetExpireTime().As(Time::S));
745  if (rt.GetExpireTime() > i->GetExpireTime())
746  {
747  i->SetExpireTime(rt.GetExpireTime());
748  }
749  m_sortedRoutes.erase(rt.GetDestination()); // erase the entry first
750  rtVector.sort(CompareRoutesExpire); // sort the route vector first
751  /*
752  * Save the new route cache along with the destination address in map
753  */
754  auto result = m_sortedRoutes.insert(std::make_pair(rt.GetDestination(), rtVector));
755  return result.second;
756  }
757  }
758  return false;
759 }
760 
761 bool
763 {
764  NS_LOG_FUNCTION(this << dst);
765  Purge(); // purge the route cache first to remove timeout entries
766  if (m_sortedRoutes.erase(dst) != 0)
767  {
768  NS_LOG_LOGIC("Route deletion to " << dst << " successful");
769  return true;
770  }
771  NS_LOG_LOGIC("Route deletion to " << dst << " not successful");
772  return false;
773 }
774 
775 void
777  Ipv4Address unreachNode,
778  Ipv4Address node)
779 {
780  NS_LOG_FUNCTION(this << errorSrc << unreachNode << node);
781  if (IsLinkCache())
782  {
783  // Purge the link node cache first
784  PurgeLinkNode();
785  /*
786  * The following are for cleaning the broken link in link cache
787  * We basically remove the link between errorSrc and unreachNode
788  */
789  Link link1(errorSrc, unreachNode);
790  Link link2(unreachNode, errorSrc);
791  // erase the two kind of links to make sure the link is removed from the link cache
792  NS_LOG_DEBUG("Erase the route");
793  m_linkCache.erase(link1);
795  NS_LOG_DEBUG("The link cache size " << m_linkCache.size());
796  m_linkCache.erase(link2);
797  NS_LOG_DEBUG("The link cache size " << m_linkCache.size());
798 
799  auto i = m_nodeCache.find(errorSrc);
800  if (i == m_nodeCache.end())
801  {
802  NS_LOG_LOGIC("Update the node stability unsuccessfuly");
803  }
804  else
805  {
806  DecStability(i->first);
807  }
808  i = m_nodeCache.find(unreachNode);
809  if (i == m_nodeCache.end())
810  {
811  NS_LOG_LOGIC("Update the node stability unsuccessfuly");
812  }
813  else
814  {
815  DecStability(i->first);
816  }
817  UpdateNetGraph();
818  RebuildBestRouteTable(node);
819  }
820  else
821  {
822  /*
823  * the following are for cleaning the broken link in pathcache
824  *
825  */
826  Purge();
827  if (m_sortedRoutes.empty())
828  {
829  return;
830  }
831  /*
832  * Loop all the routes saved in the route cache
833  */
834  for (auto j = m_sortedRoutes.begin(); j != m_sortedRoutes.end();)
835  {
836  auto jtmp = j;
837  Ipv4Address address = j->first;
838  std::list<DsrRouteCacheEntry> rtVector = j->second;
839  /*
840  * Loop all the routes for a single destination
841  */
842  for (auto k = rtVector.begin(); k != rtVector.end();)
843  {
844  // return the first route in the route vector
846  DsrRouteCacheEntry::IP_VECTOR changeVector;
847  /*
848  * Loop the ip addresses within a single route entry
849  */
850  for (auto i = routeVector.begin(); i != routeVector.end(); ++i)
851  {
852  if (*i != errorSrc)
853  {
854  changeVector.push_back(*i);
855  }
856  else
857  {
858  changeVector.push_back(*i);
859 
860  if (*(i + 1) == unreachNode)
861  {
862  break;
863  }
864  }
865  }
866  /*
867  * Verify if need to remove some affected links
868  */
869  if (changeVector.size() == routeVector.size())
870  {
871  NS_LOG_DEBUG("The route does not contain the broken link");
872  ++k;
873  }
874  else if ((changeVector.size() < routeVector.size()) && (changeVector.size() > 1))
875  {
876  NS_LOG_DEBUG("sub route " << m_subRoute);
877  if (m_subRoute)
878  {
879  Time expire = k->GetExpireTime();
880  /*
881  * Remove the route first
882  */
883  k = rtVector.erase(k);
884  DsrRouteCacheEntry changeEntry;
885  changeEntry.SetVector(changeVector);
886  Ipv4Address destination = changeVector.back();
887  NS_LOG_DEBUG("The destination of the newly formed route "
888  << destination << " and the size of the route "
889  << changeVector.size());
890  changeEntry.SetDestination(destination);
891  changeEntry.SetExpireTime(
892  expire); // Initialize the timeout value to the one it has
893  rtVector.push_back(changeEntry); // Add the route entry to the route list
894  NS_LOG_DEBUG("We have a sub-route to " << destination);
895  }
896  else
897  {
898  /*
899  * Remove the route
900  */
901  k = rtVector.erase(k);
902  }
903  }
904  else
905  {
906  NS_LOG_LOGIC("Cut route unsuccessful and erase the route");
907  /*
908  * Remove the route
909  */
910  k = rtVector.erase(k);
911  }
912  }
913  ++j;
914  if (!IsLinkCache())
915  {
916  m_sortedRoutes.erase(jtmp);
917  }
918  if (!rtVector.empty())
919  {
920  /*
921  * Save the new route cache along with the destination address in map
922  */
923  rtVector.sort(CompareRoutesExpire);
924  m_sortedRoutes[address] = rtVector;
925  }
926  else
927  {
928  NS_LOG_DEBUG("There is no route left for that destination " << address);
929  }
930  }
931  }
932 }
933 
934 void
935 DsrRouteCache::PrintVector(std::vector<Ipv4Address>& vec)
936 {
937  NS_LOG_FUNCTION(this);
938  /*
939  * Check elements in a route vector, used when one wants to check the IP addresses saved in
940  */
941  if (vec.empty())
942  {
943  NS_LOG_DEBUG("The vector is empty");
944  }
945  else
946  {
947  NS_LOG_DEBUG("Print all the elements in a vector");
948  for (auto i = vec.begin(); i != vec.end(); ++i)
949  {
950  NS_LOG_DEBUG("The ip address " << *i);
951  }
952  }
953 }
954 
955 void
956 DsrRouteCache::PrintRouteVector(std::list<DsrRouteCacheEntry> route)
957 {
958  NS_LOG_FUNCTION(this);
959  for (auto i = route.begin(); i != route.end(); i++)
960  {
961  std::vector<Ipv4Address> path = i->GetVector();
962  NS_LOG_INFO("Route NO. ");
963  PrintVector(path);
964  }
965 }
966 
967 void
969 {
970  NS_LOG_FUNCTION(this);
971  // Trying to purge the route cache
972  if (m_sortedRoutes.empty())
973  {
974  NS_LOG_DEBUG("The route cache is empty");
975  return;
976  }
977  for (auto i = m_sortedRoutes.begin(); i != m_sortedRoutes.end();)
978  {
979  // Loop of route cache entry with the route size
980  auto itmp = i;
981  /*
982  * The route cache entry vector
983  */
984  Ipv4Address dst = i->first;
985  std::list<DsrRouteCacheEntry> rtVector = i->second;
986  NS_LOG_DEBUG("The route vector size of 1 " << dst << " " << rtVector.size());
987  if (!rtVector.empty())
988  {
989  for (auto j = rtVector.begin(); j != rtVector.end();)
990  {
991  NS_LOG_DEBUG("The expire time of every entry with expire time "
992  << j->GetExpireTime());
993  /*
994  * First verify if the route has expired or not
995  */
996  if (j->GetExpireTime() <= Seconds(0))
997  {
998  /*
999  * When the expire time has passed, erase the certain route
1000  */
1001  NS_LOG_DEBUG("Erase the expired route for " << dst << " with expire time "
1002  << j->GetExpireTime());
1003  j = rtVector.erase(j);
1004  }
1005  else
1006  {
1007  ++j;
1008  }
1009  }
1010  NS_LOG_DEBUG("The route vector size of 2 " << dst << " " << rtVector.size());
1011  if (!rtVector.empty())
1012  {
1013  ++i;
1014  m_sortedRoutes.erase(itmp); // erase the entry first
1015  /*
1016  * Save the new route cache along with the destination address in map
1017  */
1018  m_sortedRoutes.insert(std::make_pair(dst, rtVector));
1019  }
1020  else
1021  {
1022  ++i;
1023  m_sortedRoutes.erase(itmp);
1024  }
1025  }
1026  else
1027  {
1028  ++i;
1029  m_sortedRoutes.erase(itmp);
1030  }
1031  }
1032 }
1033 
1034 void
1035 DsrRouteCache::Print(std::ostream& os)
1036 {
1037  NS_LOG_FUNCTION(this);
1038  Purge();
1039  os << "\nDSR Route Cache\n"
1040  << "Destination\tGateway\t\tInterface\tFlag\tExpire\tHops\n";
1041  for (auto i = m_routeEntryVector.begin(); i != m_routeEntryVector.end(); ++i)
1042  {
1043  i->Print(os);
1044  }
1045  os << "\n";
1046 }
1047 
1048 // ----------------------------------------------------------------------------------------------------------
1052 uint16_t
1054 {
1055  NS_LOG_FUNCTION(this);
1056  auto i = m_ackIdCache.find(nextHop);
1057  if (i == m_ackIdCache.end())
1058  {
1059  NS_LOG_LOGIC("No Ack id for " << nextHop
1060  << " found and use id 1 for the first network ack id");
1061  m_ackIdCache[nextHop] = 1;
1062  return 1;
1063  }
1064 
1065  uint16_t ackId = m_ackIdCache[nextHop];
1066  NS_LOG_LOGIC("Ack id for " << nextHop << " found in the cache has value " << ackId);
1067  ackId++;
1068  m_ackIdCache[nextHop] = ackId;
1069  return ackId;
1070 }
1071 
1072 uint16_t
1074 {
1075  return m_ackIdCache.size();
1076 }
1077 
1078 // ----------------------------------------------------------------------------------------------------------
1082 bool
1084 {
1085  NS_LOG_FUNCTION(this);
1086  PurgeMac(); // purge the mac cache
1087  for (auto i = m_nb.begin(); i != m_nb.end(); ++i)
1088  {
1089  if (i->m_neighborAddress == addr)
1090  {
1091  return true;
1092  }
1093  }
1094  return false;
1095 }
1096 
1097 Time
1099 {
1100  NS_LOG_FUNCTION(this);
1101  PurgeMac();
1102  for (auto i = m_nb.begin(); i != m_nb.end(); ++i)
1103  {
1104  if (i->m_neighborAddress == addr)
1105  {
1106  return (i->m_expireTime - Simulator::Now());
1107  }
1108  }
1109  return Seconds(0);
1110 }
1111 
1112 void
1113 DsrRouteCache::UpdateNeighbor(std::vector<Ipv4Address> nodeList, Time expire)
1114 {
1115  NS_LOG_FUNCTION(this);
1116  for (auto i = m_nb.begin(); i != m_nb.end(); ++i)
1117  {
1118  for (auto j = nodeList.begin(); j != nodeList.end(); ++j)
1119  {
1120  if (i->m_neighborAddress == (*j))
1121  {
1122  i->m_expireTime = std::max(expire + Simulator::Now(), i->m_expireTime);
1123  if (i->m_hardwareAddress == Mac48Address())
1124  {
1125  i->m_hardwareAddress = LookupMacAddress(i->m_neighborAddress);
1126  }
1127  return;
1128  }
1129  }
1130  }
1131 
1132  Ipv4Address addr;
1133  NS_LOG_LOGIC("Open link to " << addr);
1134  Neighbor neighbor(addr, LookupMacAddress(addr), expire + Simulator::Now());
1135  m_nb.push_back(neighbor);
1136  PurgeMac();
1137 }
1138 
1139 void
1140 DsrRouteCache::AddNeighbor(std::vector<Ipv4Address> nodeList, Ipv4Address ownAddress, Time expire)
1141 {
1142  NS_LOG_LOGIC("Add neighbor number " << nodeList.size());
1143  for (auto j = nodeList.begin(); j != nodeList.end();)
1144  {
1145  Ipv4Address addr = *j;
1146  if (addr == ownAddress)
1147  {
1148  j = nodeList.erase(j);
1149  NS_LOG_DEBUG("The node list size " << nodeList.size());
1150  }
1151  else
1152  {
1153  ++j;
1154  }
1155  Neighbor neighbor(addr, LookupMacAddress(addr), expire + Simulator::Now());
1156  m_nb.push_back(neighbor);
1157  PurgeMac();
1158  }
1159 }
1160 
1163 {
1170  bool operator()(const DsrRouteCache::Neighbor& nb) const
1171  {
1172  return ((nb.m_expireTime < Simulator::Now()) || nb.close);
1173  }
1174 };
1175 
1176 void
1178 {
1179  if (m_nb.empty())
1180  {
1181  return;
1182  }
1183 
1184  CloseNeighbor pred;
1185  if (!m_handleLinkFailure.IsNull())
1186  {
1187  for (auto j = m_nb.begin(); j != m_nb.end(); ++j)
1188  {
1189  if (pred(*j))
1190  {
1191  NS_LOG_LOGIC("Close link to " << j->m_neighborAddress);
1193  // m_handleLinkFailure (j->m_neighborAddress);
1194  }
1195  }
1196  }
1197  m_nb.erase(std::remove_if(m_nb.begin(), m_nb.end(), pred), m_nb.end());
1198  m_ntimer.Cancel();
1199  m_ntimer.Schedule();
1200 }
1201 
1202 void
1204 {
1205  m_ntimer.Cancel();
1206  m_ntimer.Schedule();
1207 }
1208 
1209 void
1211 {
1212  m_arp.push_back(a);
1213 }
1214 
1215 void
1217 {
1218  m_arp.erase(std::remove(m_arp.begin(), m_arp.end(), a), m_arp.end());
1219 }
1220 
1223 {
1224  Mac48Address hwaddr;
1225  for (auto i = m_arp.begin(); i != m_arp.end(); ++i)
1226  {
1227  ArpCache::Entry* entry = (*i)->Lookup(addr);
1228  if (entry != nullptr && (entry->IsAlive() || entry->IsPermanent()) && !entry->IsExpired())
1229  {
1230  hwaddr = Mac48Address::ConvertFrom(entry->GetMacAddress());
1231  break;
1232  }
1233  }
1234  return hwaddr;
1235 }
1236 
1237 void
1239 {
1240  Mac48Address addr = hdr.GetAddr1();
1241 
1242  for (auto i = m_nb.begin(); i != m_nb.end(); ++i)
1243  {
1244  if (i->m_hardwareAddress == addr)
1245  {
1246  i->close = true;
1247  }
1248  }
1249  PurgeMac();
1250 }
1251 } // namespace dsr
1252 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:42
A record that that holds information about an ArpCache entry.
Definition: arp-cache.h:184
bool IsAlive()
Definition: arp-cache.cc:397
Address GetMacAddress() const
Definition: arp-cache.cc:499
bool IsExpired() const
Definition: arp-cache.cc:547
bool IsPermanent()
Definition: arp-cache.cc:411
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
bool IsBroadcast() const
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address ConvertFrom(const Address &address)
A base class which provides memory management and object aggregation.
Definition: object.h:89
Control the scheduling of simulation events.
Definition: simulator.h:68
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
A simple virtual Timer class.
Definition: timer.h:74
void SetDelay(const Time &delay)
Definition: timer.cc:76
void SetFunction(FN fn)
Definition: timer.h:275
void Cancel()
Cancel the currently-running event if there is one.
Definition: timer.cc:108
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:162
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
DsrNodeStab class (DSR node stability)
Definition: dsr-rcache.h:192
void SetNodeStability(Time nodeStab)
Set node stability.
Definition: dsr-rcache.h:206
virtual ~DsrNodeStab()
Definition: dsr-rcache.cc:94
DsrNodeStab(Time nodeStab=Simulator::Now())
Constructor.
Definition: dsr-rcache.cc:89
DsrRouteCacheEntry class for entries in the route cache.
Definition: dsr-rcache.h:229
IP_VECTOR GetVector() const
Get the IP vector.
Definition: dsr-rcache.h:309
void SetDestination(Ipv4Address d)
Set destination address.
Definition: dsr-rcache.h:300
Time m_expire
Expire time for queue entry.
Definition: dsr-rcache.h:361
DsrRouteCacheEntry(IP_VECTOR const &ip=IP_VECTOR(), Ipv4Address dst=Ipv4Address(), Time exp=Simulator::Now())
Constructor.
Definition: dsr-rcache.cc:115
Ipv4Address m_dst
The destination Ip address.
Definition: dsr-rcache.h:359
uint8_t m_reqCount
Number of route requests.
Definition: dsr-rcache.h:363
Ipv4Address GetDestination() const
Get destination address.
Definition: dsr-rcache.h:291
virtual ~DsrRouteCacheEntry()
Definition: dsr-rcache.cc:126
void Invalidate(Time badLinkLifetime)
Mark entry as "down" (i.e.
Definition: dsr-rcache.cc:131
void Print(std::ostream &os) const
Print necessary fields.
Definition: dsr-rcache.cc:138
std::vector< Ipv4Address > IP_VECTOR
Define the vector to hold Ip address.
Definition: dsr-rcache.h:231
Time GetExpireTime() const
Get expire time.
Definition: dsr-rcache.h:336
void SetExpireTime(Time exp)
Set expire time.
Definition: dsr-rcache.h:327
void SetVector(IP_VECTOR v)
Sets the IP vector.
Definition: dsr-rcache.h:318
DSR route request queue Since DSR is an on demand routing we queue requests while looking for route.
Definition: dsr-rcache.h:376
std::map< Ipv4Address, std::map< Ipv4Address, uint32_t > > m_netGraph
Current network graph state for this node, double is weight, which is calculated by the node informat...
Definition: dsr-rcache.h:804
uint32_t m_stabilityDecrFactor
stability decrease factor
Definition: dsr-rcache.h:772
std::list< DsrRouteCacheEntry::IP_VECTOR > routeVector
Define the vector of route entries.
Definition: dsr-rcache.h:398
static TypeId GetTypeId()
Get the type ID.
Definition: dsr-rcache.cc:146
void PurgeLinkNode()
Purge from the cache if the stability time expired.
Definition: dsr-rcache.cc:461
Callback< void, Ipv4Address, uint8_t > m_handleLinkFailure
The following code handles link-layer acks.
Definition: dsr-rcache.h:877
std::map< Link, DsrLinkStab > m_linkCache
The data structure to store link info.
Definition: dsr-rcache.h:808
void ScheduleTimer()
Schedule m_ntimer.
Definition: dsr-rcache.cc:1203
void RebuildBestRouteTable(Ipv4Address source)
Rebuild the best route table.
Definition: dsr-rcache.cc:318
void SetCacheType(std::string type)
Dijsktra algorithm to get the best route from m_netGraph and update the m_bestRoutesTable_link when c...
Definition: dsr-rcache.cc:292
routeEntryVector m_routeEntryVector
Define the route vector.
Definition: dsr-rcache.h:785
void AddArpCache(Ptr< ArpCache > a)
Add ARP cache to be used to allow layer 2 notifications processing.
Definition: dsr-rcache.cc:1210
std::map< Ipv4Address, DsrNodeStab > m_nodeCache
The data structure to store node info.
Definition: dsr-rcache.h:809
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: dsr-rcache.cc:968
Time m_initStability
initial stability
Definition: dsr-rcache.h:774
uint16_t CheckUniqueAckId(Ipv4Address nextHop)
Check for duplicate ids and save new entries if the id is not present in the table.
Definition: dsr-rcache.cc:1053
bool IsLinkCache()
is link cached
Definition: dsr-rcache.cc:311
uint32_t m_stabilityIncrFactor
stability increase factor
Definition: dsr-rcache.h:773
bool LookupRoute(Ipv4Address id, DsrRouteCacheEntry &rt)
Lookup route cache entry with destination address dst.
Definition: dsr-rcache.cc:213
uint16_t GetAckSize()
Get the ack table size.
Definition: dsr-rcache.cc:1073
std::map< Ipv4Address, uint16_t > m_ackIdCache
The id cache to ensure all the ids are unique.
Definition: dsr-rcache.h:789
void ProcessTxError(const WifiMacHeader &hdr)
Process layer 2 TX error notification.
Definition: dsr-rcache.cc:1238
Time RouteCacheTimeout
The maximum period of time that dsr is allowed to for an unused route.
Definition: dsr-rcache.h:766
bool AddRoute_Link(DsrRouteCacheEntry::IP_VECTOR nodelist, Ipv4Address node)
dd route link to cache
Definition: dsr-rcache.cc:560
std::vector< Ptr< ArpCache > > m_arp
list of ARP cached to be used for layer 2 notifications processing
Definition: dsr-rcache.h:884
Mac48Address LookupMacAddress(Ipv4Address addr)
Find MAC address by IP using list of ARP caches.
Definition: dsr-rcache.cc:1222
void UseExtends(DsrRouteCacheEntry::IP_VECTOR rt)
When a link from the Route Cache is used in routing a packet originated or salvaged by that node,...
Definition: dsr-rcache.cc:610
void PurgeMac()
Remove all expired mac entries.
Definition: dsr-rcache.cc:1177
bool FindSameRoute(DsrRouteCacheEntry &rt, std::list< DsrRouteCacheEntry > &rtVector)
Find the same route in the route cache.
Definition: dsr-rcache.cc:729
std::map< Ipv4Address, routeEntryVector > m_sortedRoutes
Map the ipv4Address to route entry vector.
Definition: dsr-rcache.h:783
void PrintVector(std::vector< Ipv4Address > &vec)
Print the route vector elements.
Definition: dsr-rcache.cc:935
bool m_isLinkCache
Check if the route is using path cache or link cache.
Definition: dsr-rcache.h:791
Time m_delay
This timeout deals with the passive ack.
Definition: dsr-rcache.h:886
bool DeleteRoute(Ipv4Address dst)
Delete the route with certain destination address.
Definition: dsr-rcache.cc:762
bool IncStability(Ipv4Address node)
increase the stability of the node
Definition: dsr-rcache.cc:511
void PrintRouteVector(std::list< DsrRouteCacheEntry > route)
Print all the route vector elements from the route list.
Definition: dsr-rcache.cc:956
uint32_t m_maxEntriesEachDst
number of entries for each destination
Definition: dsr-rcache.h:787
Time GetExpireTime(Ipv4Address addr)
Return expire time for neighbor node with address addr, if exists, else return 0.
Definition: dsr-rcache.cc:1098
Time m_useExtends
use extend
Definition: dsr-rcache.h:776
std::vector< Neighbor > m_nb
vector of entries
Definition: dsr-rcache.h:881
Time m_minLifeTime
minimum lifetime
Definition: dsr-rcache.h:775
void DelArpCache(Ptr< ArpCache >)
Don't use the provided ARP cache any more (interface is down)
Definition: dsr-rcache.cc:1216
void Print(std::ostream &os)
Print route cache.
Definition: dsr-rcache.cc:1035
bool LookupRoute_Link(Ipv4Address id, DsrRouteCacheEntry &rt)
used by LookupRoute when LinkCache
Definition: dsr-rcache.cc:431
bool UpdateRouteEntry(Ipv4Address dst)
Update route cache entry if it has been recently used and successfully delivered the data packet.
Definition: dsr-rcache.cc:185
void UpdateNeighbor(std::vector< Ipv4Address > nodeList, Time expire)
Update expire time for entry with address addr, if it exists, else add new entry.
Definition: dsr-rcache.cc:1113
void RemoveLastEntry(std::list< DsrRouteCacheEntry > &rtVector)
Remove the aged route cache entries when the route cache is full.
Definition: dsr-rcache.cc:177
Timer m_ntimer
Timer for neighbor's list. Schedule Purge().
Definition: dsr-rcache.h:879
bool m_subRoute
Check if save the sub route entries or not.
Definition: dsr-rcache.h:793
void DeleteAllRoutesIncludeLink(Ipv4Address errorSrc, Ipv4Address unreachNode, Ipv4Address node)
Delete all the routes which includes the link from next hop address that has just been notified as un...
Definition: dsr-rcache.cc:776
bool IsNeighbor(Ipv4Address addr)
Check that node with address addr is neighbor.
Definition: dsr-rcache.cc:1083
std::map< Ipv4Address, DsrRouteCacheEntry::IP_VECTOR > m_bestRoutesTable_link
for link route cache
Definition: dsr-rcache.h:807
bool DecStability(Ipv4Address node)
decrease the stability of the node
Definition: dsr-rcache.cc:536
void UpdateNetGraph()
Update the Net Graph for the link and node cache has changed.
Definition: dsr-rcache.cc:496
bool AddRoute(DsrRouteCacheEntry &rt)
Add route cache entry if it doesn't yet exist in route cache.
Definition: dsr-rcache.cc:657
void AddNeighbor(std::vector< Ipv4Address > nodeList, Ipv4Address ownAddress, Time expire)
Add to the neighbor list.
Definition: dsr-rcache.cc:1140
#define MAXWEIGHT
The link cache to update all the link status, bi-link is two link for link is a struct when the weigh...
Definition: dsr-rcache.h:798
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
address
Definition: first.py:47
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:839
bool CompareRoutesBoth(const DsrRouteCacheEntry &a, const DsrRouteCacheEntry &b)
Definition: dsr-rcache.cc:61
bool CompareRoutesExpire(const DsrRouteCacheEntry &a, const DsrRouteCacheEntry &b)
Definition: dsr-rcache.cc:77
bool CompareRoutesHops(const DsrRouteCacheEntry &a, const DsrRouteCacheEntry &b)
Definition: dsr-rcache.cc:70
std::list< DsrRouteCacheEntry >::value_type route_pair
Definition: dsr-rcache.cc:113
Every class exported by the ns3 library is enclosed in the ns3 namespace.
CloseNeighbor structure.
Definition: dsr-rcache.cc:1163
bool operator()(const DsrRouteCache::Neighbor &nb) const
Check if the entry is expired.
Definition: dsr-rcache.cc:1170
Structure to manage neighbor state.
Definition: dsr-rcache.h:664
Time m_expireTime
route expire time
Definition: dsr-rcache.h:667