A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
dsr-rcache.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Yufei Cheng
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
19  * Song Luan <lsuper@mail.ustc.edu.cn> (Implemented Link Cache using Dijsktra algorithm)
20  *
21  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
22  * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
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 #include <map>
35 #include <cmath>
36 #include <algorithm>
37 #include <iostream>
38 #include <list>
39 #include <vector>
40 #include <functional>
41 #include <iomanip>
42 
43 #include "ns3/simulator.h"
44 #include "ns3/ipv4-route.h"
45 #include "ns3/socket.h"
46 #include "ns3/log.h"
47 #include "ns3/address-utils.h"
48 #include "ns3/packet.h"
49 
50 NS_LOG_COMPONENT_DEFINE ("RouteCache");
51 
52 namespace ns3 {
53 namespace dsr {
54 
56 {
57  // compare based on both with hop count considered priority
58  return (a.GetVector ().size () < b.GetVector ().size ())
59  || ((a.GetVector ().size () == b.GetVector ().size ()) && (a.GetExpireTime () > b.GetExpireTime ()))
60  ;
61 }
62 
64 {
65  // compare based on hops
66  return a.GetVector ().size () < b.GetVector ().size ();
67 }
68 
70 {
71  // compare based on expire time
72  return a.GetExpireTime () > b.GetExpireTime ();
73 }
74 
75 void Link::Print () const
76 {
77  NS_LOG_DEBUG (m_low << "----" << m_high);
78 }
79 
81  : m_nodeStability (nodeStab + Simulator::Now ())
82 {
83 }
84 
86 {
87 }
88 
90  : m_linkStability (linkStab + Simulator::Now ())
91 {
92 }
93 
95 {
96 }
97 
98 void LinkStab::Print ( ) const
99 {
100  NS_LOG_DEBUG ("LifeTime: " << GetLinkStability ().GetSeconds ());
101 }
102 
103 typedef std::list<RouteCacheEntry>::value_type route_pair;
104 
106  : m_ackTimer (Timer::CANCEL_ON_DESTROY),
107  m_dst (dst),
108  m_path (ip),
109  m_expire (exp + Simulator::Now ()),
110  m_reqCount (0),
111  m_blackListState (false),
112  m_blackListTimeout (Simulator::Now ())
113 {
114 }
115 
117 {
118 }
119 
120 void
122 {
123  m_reqCount = 0;
124  m_expire = badLinkLifetime + Simulator::Now ();
125 }
126 
127 void
128 RouteCacheEntry::Print (std::ostream & os) const
129 {
130  os << m_dst << "\t" << (m_expire - Simulator::Now ()).GetSeconds ()
131  << "\t";
132 }
133 
135 
137 {
138  static TypeId tid = TypeId ("ns3::dsr::RouteCache")
139  .SetParent<Object> ()
140  .AddConstructor<RouteCache> ()
141  ;
142  return tid;
143 }
144 
146  : m_vector (0),
147  m_maxEntriesEachDst (3),
148  m_isLinkCache (false),
149  m_ntimer (Timer::CANCEL_ON_DESTROY),
150  m_delay (MilliSeconds (100))
151 {
152  /*
153  * The timer to set layer 2 notification, not fully supported by ns3 yet
154  */
158 }
159 
161 {
163  // clear the route cache when done
164  m_sortedRoutes.clear ();
165 }
166 
167 void
168 RouteCache::RemoveLastEntry (std::list<RouteCacheEntry> & rtVector)
169 {
170  NS_LOG_FUNCTION (this);
171  // release the last entry of route list
172  rtVector.pop_back ();
173 }
174 
175 bool
177 {
178  NS_LOG_FUNCTION (this << dst);
179  std::map<Ipv4Address, std::list<RouteCacheEntry> >::const_iterator i =
180  m_sortedRoutes.find (dst);
181  if (i == m_sortedRoutes.end ())
182  {
183  NS_LOG_DEBUG ("Failed to find the route entry for the destination " << dst);
184  return false;
185  }
186  else
187  {
188  std::list<RouteCacheEntry> rtVector = i->second;
189  RouteCacheEntry successEntry = rtVector.front ();
190  successEntry.SetExpireTime (RouteCacheTimeout);
191  rtVector.pop_front ();
192  rtVector.push_back (successEntry);
193  rtVector.sort (CompareRoutesExpire); // sort the route vector first
194  m_sortedRoutes.erase (dst); // erase the entry first
195  /*
196  * Save the new route cache along with the destination address in map
197  */
198  std::pair<std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator, bool> result =
199  m_sortedRoutes.insert (std::make_pair (dst, rtVector));
200  return result.second;
201  }
202  return false;
203 }
204 
205 bool
207 {
208  NS_LOG_FUNCTION (this << id);
209  if (IsLinkCache ())
210  {
211  return LookupRoute_Link (id, rt);
212  }
213  else
214  {
215  Purge (); // Purge first to remove expired entries
216  if (m_sortedRoutes.empty ())
217  {
218  NS_LOG_LOGIC ("Route to " << id << " not found; m_sortedRoutes is empty");
219  return false;
220  }
221  std::map<Ipv4Address, std::list<RouteCacheEntry> >::const_iterator i = m_sortedRoutes.find (id);
222  if (i == m_sortedRoutes.end ())
223  {
224  NS_LOG_LOGIC ("No Direct Route to " << id << " found");
225  for (std::map<Ipv4Address, std::list<RouteCacheEntry> >::const_iterator j =
226  m_sortedRoutes.begin (); j != m_sortedRoutes.end (); ++j)
227  {
228  std::list<RouteCacheEntry> rtVector = j->second; // The route cache vector linked with destination address
229  /*
230  * Loop through the possibly multiple routes within the route vector
231  */
232  for (std::list<RouteCacheEntry>::const_iterator k = rtVector.begin (); k != rtVector.end (); ++k)
233  {
234  // return the first route in the route vector
235  RouteCacheEntry::IP_VECTOR routeVector = k->GetVector ();
236  RouteCacheEntry::IP_VECTOR changeVector;
237 
238  for (RouteCacheEntry::IP_VECTOR::iterator l = routeVector.begin (); l != routeVector.end (); ++l)
239  {
240  if (*l != id)
241  {
242  changeVector.push_back (*l);
243  }
244  else
245  {
246  changeVector.push_back (*l);
247  break;
248  }
249  }
250  /*
251  * When the changed vector is smaller in size and larger than 1, which means we have found a route with the destination
252  * address we are looking for
253  */
254  if ((changeVector.size () < routeVector.size ()) && (changeVector.size () > 1))
255  {
256  RouteCacheEntry changeEntry; // Create the route entry
257  changeEntry.SetVector (changeVector);
258  changeEntry.SetDestination (id);
259  // Use the expire time from original route entry
260  changeEntry.SetExpireTime (k->GetExpireTime ());
261  // We need to add new route entry here
262  std::list<RouteCacheEntry> newVector;
263  newVector.push_back (changeEntry);
264  newVector.sort (CompareRoutesExpire); // sort the route vector first
265  m_sortedRoutes[id] = newVector; // Only get the first sub route and add it in route cache
266  NS_LOG_INFO ("We have a sub-route to " << id << " add it in route cache");
267  }
268  }
269  }
270  }
271  NS_LOG_INFO ("Here we check the route cache again after updated the sub routes");
272  std::map<Ipv4Address, std::list<RouteCacheEntry> >::const_iterator m = m_sortedRoutes.find (id);
273  if (m == m_sortedRoutes.end ())
274  {
275  NS_LOG_DEBUG ("No updated route till last time");
276  return false;
277  }
278  /*
279  * We have a direct route to the destination address
280  */
281  std::list<RouteCacheEntry> rtVector = m->second;
282  rt = rtVector.front (); // use the first entry in the route vector
283  NS_LOG_DEBUG ("Route to " << id << " with route size " << rtVector.size ());
284  return true;
285  }
286 }
287 
288 void
289 RouteCache::SetCacheType (std::string type)
290 {
291  NS_LOG_FUNCTION (this << type);
292  if (type == std::string ("LinkCache"))
293  {
294  m_isLinkCache = true;
295  }
296  else if (type == std::string ("PathCache"))
297  {
298  m_isLinkCache = false;
299  }
300  else
301  {
302  m_isLinkCache = false; // use path cache as default
303  NS_LOG_INFO ("Error Cache Type");
304  }
305 }
306 
307 bool
309 {
310  NS_LOG_FUNCTION (this);
311  return m_isLinkCache;
312 }
313 
314 void
316 {
317  NS_LOG_FUNCTION (this << source);
321  // @d shortest-path estimate
322  std::map<Ipv4Address, uint32_t> d;
323  // @pre preceeding node
324  std::map<Ipv4Address, Ipv4Address> pre;
325  for (std::map<Ipv4Address, std::map<Ipv4Address, uint32_t> >::iterator i = m_netGraph.begin (); i != m_netGraph.end (); ++i)
326  {
327  if (i->second.find (source) != i->second.end ())
328  {
329  d[i->first] = i->second[source];
330  pre[i->first] = source;
331  }
332  else
333  {
334  d[i->first] = MAXWEIGHT;
335  pre[i->first] = Ipv4Address ("255.255.255.255");
336  }
337  }
338  d[source] = 0;
342  // the node set which shortest distance has been calculated, if true calculated
343  std::map<Ipv4Address, bool> s;
344  double temp = MAXWEIGHT;
345  Ipv4Address tempip = Ipv4Address ("255.255.255.255");
346  for (uint32_t i = 0; i < m_netGraph.size (); i++)
347  {
348  temp = MAXWEIGHT;
349  for (std::map<Ipv4Address,uint32_t>::const_iterator j = d.begin (); j != d.end (); ++j)
350  {
351  Ipv4Address ip = j->first;
352  if (s.find (ip) == s.end ())
353  {
357  if (j->second <= temp)
358  {
359  temp = j->second;
360  tempip = ip;
361  }
362  }
363  }
364  if (!tempip.IsBroadcast ())
365  {
366  s[tempip] = true;
367  for (std::map<Ipv4Address, uint32_t>::const_iterator k = m_netGraph[tempip].begin (); k != m_netGraph[tempip].end (); ++k)
368  {
369  if (s.find (k->first) == s.end () && d[k->first] > d[tempip] + k->second)
370  {
371  d[k->first] = d[tempip] + k->second;
372  pre[k->first] = tempip;
373  }
380  else if (d[k->first] == d[tempip] + k->second)
381  {
382  std::map<Link, LinkStab>::iterator oldlink = m_linkCache.find (Link (k->first, pre[k->first]));
383  std::map<Link, LinkStab>::iterator newlink = m_linkCache.find (Link (k->first, tempip));
384  if (oldlink != m_linkCache.end () && newlink != m_linkCache.end ())
385  {
386  if (oldlink->second.GetLinkStability () < newlink->second.GetLinkStability ())
387  {
388  NS_LOG_INFO ("Select the link with longest expected lifetime");
389  d[k->first] = d[tempip] + k->second;
390  pre[k->first] = tempip;
391  }
392  }
393  else
394  {
395  NS_LOG_INFO ("Link Stability Info Corrupt");
396  }
397  }
398  }
399  }
400  }
401  // clean the best route table
402  m_bestRoutesTable_link.clear ();
403  for (std::map<Ipv4Address, Ipv4Address>::iterator i = pre.begin (); i != pre.end (); ++i)
404  {
405  // loop for all vertexes
407  Ipv4Address iptemp = i->first;
408 
409  if (!i->second.IsBroadcast () && iptemp != source)
410  {
411  while (iptemp != source)
412  {
413  route.push_back (iptemp);
414  iptemp = pre[iptemp];
415  }
416  route.push_back (source);
420  RouteCacheEntry::IP_VECTOR reverseroute;
421  for (RouteCacheEntry::IP_VECTOR::reverse_iterator j = route.rbegin (); j != route.rend (); ++j)
422  {
423  reverseroute.push_back (*j);
424  }
425  NS_LOG_DEBUG ("Add Route: ");
426  PrintVector (reverseroute);
427  m_bestRoutesTable_link[i->first] = reverseroute;
428  }
429  }
430 }
431 
432 bool
434 {
435  NS_LOG_FUNCTION (this << id);
436  std::map<Ipv4Address, RouteCacheEntry::IP_VECTOR>::const_iterator i = m_bestRoutesTable_link.find (id);
437  if (i == m_bestRoutesTable_link.end ())
438  {
439  NS_LOG_INFO ("No Route To " << id);
440  return false;
441  }
442  else
443  {
444  if (i->second.size () < 2)
445  {
446  NS_LOG_DEBUG ("Route To " << id << " error");
447  return false;
448  }
449 
450  RouteCacheEntry newEntry; // Create the route entry
451  newEntry.SetVector (i->second);
452  newEntry.SetDestination (id);
453  newEntry.SetExpireTime (RouteCacheTimeout);
454  NS_LOG_INFO ("Route to " << id << " found with the route length " << i->second.size ());
455  rt = newEntry;
456  std::vector<Ipv4Address> path = rt.GetVector ();
457  PrintVector (path);
458  return true;
459  }
460 }
461 
462 void
464 {
465  NS_LOG_FUNCTION (this);
466  NS_LOG_DEBUG ("The size of the link cache before " << m_linkCache.size ());
467  for (std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end (); )
468  {
469  NS_LOG_DEBUG ("The link stability " << i->second.GetLinkStability ());
470  std::map<Link, LinkStab>::iterator itmp = i;
471  if (i->second.GetLinkStability () <= Seconds (0))
472  {
473  ++i;
474  m_linkCache.erase (itmp);
475  }
476  else
477  {
478  ++i;
479  }
480  }
481  NS_LOG_DEBUG ("The size of the node cache before " << m_nodeCache.size ());
482  for (std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.begin (); i != m_nodeCache.end (); )
483  {
484  NS_LOG_DEBUG ("The node stability " << i->second.GetNodeStability ());
485  std::map<Ipv4Address, NodeStab>::iterator itmp = i;
486  if (i->second.GetNodeStability () <= Seconds (0))
487  {
488  ++i;
489  m_nodeCache.erase (itmp);
490  }
491  else
492  {
493  ++i;
494  }
495  }
496 }
497 
498 void
500 {
501  NS_LOG_FUNCTION (this);
502  m_netGraph.clear ();
503  for (std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end (); ++i)
504  {
505  // Here the weight is set as 1
506  uint32_t weight = 1;
507  m_netGraph[i->first.m_low][i->first.m_high] = weight;
508  m_netGraph[i->first.m_high][i->first.m_low] = weight;
509  }
510 }
511 
512 bool
514 {
515  NS_LOG_FUNCTION (this << node);
516  std::map<Ipv4Address, NodeStab>::const_iterator i = m_nodeCache.find (node);
517  if (i == m_nodeCache.end ())
518  {
519  NS_LOG_INFO ("The initial stability " << m_initStability.GetSeconds ());
521  m_nodeCache[node] = ns;
522  return false;
523  }
524  else
525  {
526  NodeStab ns (Time (i->second.GetNodeStability () * m_stabilityIncrFactor));
527  m_nodeCache[node] = ns;
528  return true;
529  }
530  return false;
531 }
532 
533 bool
535 {
536  NS_LOG_FUNCTION (this << node);
537  std::map<Ipv4Address, NodeStab>::const_iterator i = m_nodeCache.find (node);
538  if (i == m_nodeCache.end ())
539  {
541  m_nodeCache[node] = ns;
542  return false;
543  }
544  else
545  {
546  NodeStab ns (Time (i->second.GetNodeStability () / m_stabilityDecrFactor));
547  m_nodeCache[node] = ns;
548  return true;
549  }
550  return false;
551 }
552 
553 bool
555 {
556  NS_LOG_FUNCTION (this << source);
557  NS_LOG_DEBUG ("Use Link Cache");
558  for (uint32_t i = 0; i < nodelist.size () - 1; i++)
559  {
560  NodeStab ns;
562 
563  if (m_nodeCache.find (nodelist[i]) == m_nodeCache.end ())
564  {
565  m_nodeCache[nodelist[i]] = ns;
566  }
567  if (m_nodeCache.find (nodelist[i + 1]) == m_nodeCache.end ())
568  {
569  m_nodeCache[nodelist[i + 1]] = ns;
570  }
571  Link link (nodelist[i], nodelist[i + 1]);
572  LinkStab stab;
574  if (m_nodeCache[nodelist[i]].GetNodeStability () < m_nodeCache[nodelist[i + 1]].GetNodeStability ())
575  {
576  stab.SetLinkStability (m_nodeCache[nodelist[i]].GetNodeStability ());
577  }
578  else
579  {
580  stab.SetLinkStability (m_nodeCache[nodelist[i + 1]].GetNodeStability ());
581  }
582  if (stab.GetLinkStability () < m_minLifeTime)
583  {
584  NS_LOG_DEBUG ("Stability: " << stab.GetLinkStability ().GetSeconds ());
586  }
587  m_linkCache[link] = stab;
588  NS_LOG_DEBUG ("Add a new link");
589  link.Print ();
590  NS_LOG_DEBUG ("Link Info");
591  stab.Print ();
592  }
593  PurgeLinkNode ();
594  UpdateNetGraph ();
595  RebuildBestRouteTable (source);
596  return true;
597 }
598 
599 void
601 {
602  NS_LOG_FUNCTION (this);
603  if (rt.size () < 2)
604  {
605  NS_LOG_INFO ("The route is too short");
606  }
607  for (RouteCacheEntry::IP_VECTOR::iterator i = rt.begin (); i != rt.end () - 1; ++i)
608  {
609  Link link (*i, *(i + 1));
610  if (m_linkCache.find (link) != m_linkCache.end ())
611  {
612  if (m_linkCache[link].GetLinkStability () < m_useExtends)
613  {
614  m_linkCache[link].SetLinkStability (m_useExtends);
615  NS_LOG_DEBUG ("The time of the link " << m_linkCache[link].GetLinkStability ().GetSeconds ());
616  }
617  }
618  else
619  {
620  NS_LOG_INFO ("we cannot find a link in cache");
621  }
622  }
623  // Increase the stability of the node cache
624  for (RouteCacheEntry::IP_VECTOR::iterator i = rt.begin (); i != rt.end (); ++i)
625  {
626  if (m_nodeCache.find (*i) != m_nodeCache.end ())
627  {
628  NS_LOG_DEBUG ("Increase the stability");
629  if (m_nodeCache[*i].GetNodeStability () <= m_initStability)
630  {
631  IncStability (*i);
632  }
633  else
634  {
635  NS_LOG_INFO ("The node stability has already been increased");
636  }
637  }
638  }
639 }
640 
641 bool
643 {
644  NS_LOG_FUNCTION (this);
645  Purge ();
646  std::list<RouteCacheEntry> rtVector; // Declare the route cache entry vector
647  Ipv4Address dst = rt.GetDestination ();
648  std::vector<Ipv4Address> route = rt.GetVector ();
649 
650  NS_LOG_DEBUG ("The route destination we have " << dst);
651  std::map<Ipv4Address, std::list<RouteCacheEntry> >::const_iterator i =
652  m_sortedRoutes.find (dst);
653 
654  if (i == m_sortedRoutes.end ())
655  {
656  rtVector.push_back (rt);
657  m_sortedRoutes.erase (dst); // Erase the route entries for dst first
661  std::pair<std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator, bool> result =
662  m_sortedRoutes.insert (std::make_pair (dst, rtVector));
663  return result.second;
664  }
665  else
666  {
667  rtVector = i->second;
668  NS_LOG_DEBUG ("The existing route size " << rtVector.size () << " for destination address " << dst);
672  if (rtVector.size () >= m_maxEntriesEachDst)
673  {
674  RemoveLastEntry (rtVector); // Drop the last entry for the sorted route cache, the route has already been sorted
675  }
676 
677  if (FindSameRoute (rt, rtVector))
678  {
679  NS_LOG_DEBUG ("Find same vector, the FindSameRoute function will update the route expire time");
680  return true;
681  }
682  else
683  {
684  // Check if the expire time for the new route has expired or not
685  if (rt.GetExpireTime () > 0)
686  {
687  rtVector.push_back (rt);
688  // This sort function will sort the route cache entries based on the size of route in each of the
689  // route entries
690  rtVector.sort (CompareRoutesExpire);
691  NS_LOG_DEBUG ("The first time" << rtVector.front ().GetExpireTime ().GetSeconds () << " The second time "
692  << rtVector.back ().GetExpireTime ().GetSeconds ());
693  NS_LOG_DEBUG ("The first hop" << rtVector.front ().GetVector ().size () << " The second hop "
694  << rtVector.back ().GetVector ().size ());
695  m_sortedRoutes.erase (dst); // erase the route entries for dst first
699  std::pair<std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator, bool> result =
700  m_sortedRoutes.insert (std::make_pair (dst, rtVector));
701  return result.second;
702  }
703  else
704  {
705  NS_LOG_INFO ("The newly found route is already expired");
706  }
707  }
708  }
709  return false;
710 }
711 
712 bool RouteCache::FindSameRoute (RouteCacheEntry & rt, std::list<RouteCacheEntry> & rtVector)
713 {
714  NS_LOG_FUNCTION (this);
715  for (std::list<RouteCacheEntry>::iterator i = rtVector.begin (); i != rtVector.end (); ++i)
716  {
717  // return the first route in the route vector
718  RouteCacheEntry::IP_VECTOR routeVector = i->GetVector ();
719  RouteCacheEntry::IP_VECTOR newVector = rt.GetVector ();
720 
721  if (routeVector == newVector)
722  {
723  NS_LOG_DEBUG ("Found same routes in the route cache with the vector size "
724  << rt.GetDestination () << " " << rtVector.size ());
725  NS_LOG_DEBUG ("The new route expire time " << rt.GetExpireTime ().GetSeconds ()
726  << " the original expire time " << i->GetExpireTime ().GetSeconds ());
727  if (rt.GetExpireTime () > i->GetExpireTime ())
728  {
729  i->SetExpireTime (rt.GetExpireTime ());
730  }
731  m_sortedRoutes.erase (rt.GetDestination ()); // erase the entry first
732  rtVector.sort (CompareRoutesExpire); // sort the route vector first
733  /*
734  * Save the new route cache along with the destination address in map
735  */
736  std::pair<std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator, bool> result =
737  m_sortedRoutes.insert (std::make_pair (rt.GetDestination (), rtVector));
738  return result.second;
739  }
740  }
741  return false;
742 }
743 
744 bool
746 {
747  NS_LOG_FUNCTION (this << dst);
748  Purge (); // purge the route cache first to remove timeout entries
749  if (m_sortedRoutes.erase (dst) != 0)
750  {
751  NS_LOG_LOGIC ("Route deletion to " << dst << " successful");
752  return true;
753  }
754  NS_LOG_LOGIC ("Route deletion to " << dst << " not successful");
755  return false;
756 }
757 
758 void
760 {
761  NS_LOG_FUNCTION (this << errorSrc << unreachNode << node);
762  if (IsLinkCache ())
763  {
764  /*
765  * The followings are for cleaning the broken link in linkcache
766  *
767  */
768  Link link1 (errorSrc, unreachNode);
769  Link link2 (unreachNode, errorSrc);
770  // erase the two kind of links to make sure the link is removed from the link cache
771  NS_LOG_DEBUG ("Erase the route ");
772  m_linkCache.erase (link1);
773  m_linkCache.erase (link2);
774 
775  std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.find (errorSrc);
776  if (i == m_nodeCache.end ())
777  {
778  NS_LOG_LOGIC ("Update the node stability unsuccessfully");
779  }
780  else
781  {
782  DecStability (i->first);
783  }
784  i = m_nodeCache.find (unreachNode);
785  if (i == m_nodeCache.end ())
786  {
787  NS_LOG_LOGIC ("Update the node stability unsuccessfully");
788  }
789  else
790  {
791  DecStability (i->first);
792  }
793  PurgeLinkNode ();
794  UpdateNetGraph ();
795  RebuildBestRouteTable (node);
796  }
797  else
798  {
799  /*
800  * the followings are for cleaning the broken link in pathcache
801  *
802  */
803  Purge ();
804  if (m_sortedRoutes.empty ())
805  {
806  return;
807  }
808  /*
809  * Loop all the routes saved in the route cache
810  */
811  for (std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator j =
812  m_sortedRoutes.begin (); j != m_sortedRoutes.end (); )
813  {
814  std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator jtmp = j;
815  Ipv4Address address = j->first;
816  std::list<RouteCacheEntry> rtVector = j->second;
817  /*
818  * Loop all the routes for a single destination
819  */
820  for (std::list<RouteCacheEntry>::iterator k = rtVector.begin (); k != rtVector.end (); )
821  {
822  // return the first route in the route vector
823  RouteCacheEntry::IP_VECTOR routeVector = k->GetVector ();
824  RouteCacheEntry::IP_VECTOR changeVector;
825  /*
826  * Loop the ip addresses within a single route entry
827  */
828  for (RouteCacheEntry::IP_VECTOR::iterator i = routeVector.begin (); i != routeVector.end (); ++i)
829  {
830  if (*i != errorSrc)
831  {
832  changeVector.push_back (*i);
833  }
834  else
835  {
836  if (*(i + 1) == unreachNode)
837  {
838  changeVector.push_back (*i);
839  break;
840  }
841  else
842  {
843  changeVector.push_back (*i);
844  }
845  }
846  }
847  /*
848  * Verify if need to remove some affected links
849  */
850  if (changeVector.size () == routeVector.size ())
851  {
852  NS_LOG_DEBUG ("The route does not contain the broken link");
853  ++k;
854  }
855  else if ((changeVector.size () < routeVector.size ()) && (changeVector.size () > 1))
856  {
857  NS_LOG_DEBUG ("sub route " << m_subRoute);
858  if (m_subRoute)
859  {
860  Time expire = k->GetExpireTime ();
861  /*
862  * Remove the route first
863  */
864  k = rtVector.erase (k);
865  RouteCacheEntry changeEntry;
866  changeEntry.SetVector (changeVector);
867  Ipv4Address destination = changeVector.back ();
868  NS_LOG_DEBUG ("The destination of the newly formed route " << destination << " and the size of the route " << changeVector.size ());
869  changeEntry.SetDestination (destination);
870  changeEntry.SetExpireTime (expire); // Initialize the timeout value to the one it has
871  rtVector.push_back (changeEntry); // Add the route entry to the route list
872  NS_LOG_DEBUG ("We have a sub-route to " << destination);
873  }
874  else
875  {
876  /*
877  * Remove the route
878  */
879  k = rtVector.erase (k);
880  }
881  }
882  else
883  {
884  NS_LOG_LOGIC ("Cut route unsuccessful and erase the route");
885  /*
886  * Remove the route
887  */
888  k = rtVector.erase (k);
889  }
890  }
891  ++j;
892  if (!IsLinkCache ())
893  {
894  m_sortedRoutes.erase (jtmp);
895  }
896  if (rtVector.size ())
897  {
898  /*
899  * Save the new route cache along with the destination address in map
900  */
901  rtVector.sort (CompareRoutesExpire);
902  m_sortedRoutes[address] = rtVector;
903  }
904  else
905  {
906  NS_LOG_DEBUG ("There is no route left for that destination " << address);
907  }
908  }
909  }
910 }
911 
912 void
913 RouteCache::PrintVector (std::vector<Ipv4Address>& vec)
914 {
915  NS_LOG_FUNCTION (this);
916  /*
917  * Check elements in a route vector, used when one wants to check the IP addresses saved in
918  */
919  if (!vec.size ())
920  {
921  NS_LOG_DEBUG ("The vector is empty");
922  }
923  else
924  {
925  NS_LOG_DEBUG ("Print all the elements in a vector");
926  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
927  {
928  NS_LOG_DEBUG ("The ip address " << *i);
929  }
930  }
931 }
932 
933 void
934 RouteCache::PrintRouteVector (std::list<RouteCacheEntry> route)
935 {
936  NS_LOG_FUNCTION (this);
937  for (std::list<RouteCacheEntry>::iterator i = route.begin (); i != route.end (); i++)
938  {
939  std::vector<Ipv4Address> path = i->GetVector ();
940  NS_LOG_INFO ("Route NO. ");
941  PrintVector (path);
942  }
943 }
944 
945 void
947 {
948  NS_LOG_FUNCTION (this);
949  //Trying to purge the route cache
950  if (m_sortedRoutes.empty ())
951  {
952  NS_LOG_DEBUG ("The route cache is empty");
953  return;
954  }
955  for (std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator i =
956  m_sortedRoutes.begin (); i != m_sortedRoutes.end (); )
957  {
958  // Loop of route cache entry with the route size
959  std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator itmp = i;
960  /*
961  * The route cache entry vector
962  */
963  Ipv4Address dst = i->first;
964  std::list<RouteCacheEntry> rtVector = i->second;
965  NS_LOG_DEBUG ("The route vector size of 1 " << dst << " " << rtVector.size ());
966  if (rtVector.size ())
967  {
968  for (std::list<RouteCacheEntry>::iterator j = rtVector.begin (); j != rtVector.end (); )
969  {
970  NS_LOG_DEBUG ("The expire time of every entry with expire time " << j->GetExpireTime ());
971  /*
972  * First verify if the route has expired or not
973  */
974  if (j->GetExpireTime () <= Seconds (0))
975  {
976  /*
977  * When the expire time has passed, erase the certain route
978  */
979  NS_LOG_DEBUG ("Erase the expired route for " << dst << " with expire time " << j->GetExpireTime ());
980  j = rtVector.erase (j);
981  }
982  else
983  {
984  ++j;
985  }
986  }
987  NS_LOG_DEBUG ("The route vector size of 2 " << dst << " " << rtVector.size ());
988  if (rtVector.size ())
989  {
990  ++i;
991  m_sortedRoutes.erase (itmp); // erase the entry first
992  /*
993  * Save the new route cache along with the destination address in map
994  */
995  m_sortedRoutes.insert (std::make_pair (dst, rtVector));
996  }
997  else
998  {
999  ++i;
1000  m_sortedRoutes.erase (itmp);
1001  }
1002  }
1003  else
1004  {
1005  ++i;
1006  m_sortedRoutes.erase (itmp);
1007  }
1008  }
1009  return;
1010 }
1011 
1012 void
1013 RouteCache::Print (std::ostream &os)
1014 {
1015  NS_LOG_FUNCTION (this);
1016  Purge ();
1017  os << "\nDSR Route Cache\n"
1018  << "Destination\tGateway\t\tInterface\tFlag\tExpire\tHops\n";
1019  for (std::list<RouteCacheEntry>::const_iterator i =
1020  m_routeEntryVector.begin (); i != m_routeEntryVector.end (); ++i)
1021  {
1022  i->Print (os);
1023  }
1024  os << "\n";
1025 }
1026 
1027 // ----------------------------------------------------------------------------------------------------------
1031 uint16_t
1033 {
1034  NS_LOG_FUNCTION (this);
1035  std::map<Ipv4Address, uint16_t>::const_iterator i =
1036  m_ackIdCache.find (nextHop);
1037  if (i == m_ackIdCache.end ())
1038  {
1039  NS_LOG_LOGIC ("No Ack id for " << nextHop << " found and use id 1 for the first network ack id");
1040  m_ackIdCache[nextHop] = 1;
1041  return 1;
1042  }
1043  else
1044  {
1045  uint16_t ackId = m_ackIdCache[nextHop];
1046  NS_LOG_LOGIC ("Ack id for " << nextHop << " found in the cache has value " << ackId);
1047  ackId++;
1048  m_ackIdCache[nextHop] = ackId;
1049  return ackId;
1050  }
1051 }
1052 
1053 uint16_t
1055 {
1056  return m_ackIdCache.size ();
1057 }
1058 
1059 // ----------------------------------------------------------------------------------------------------------
1063 bool
1065 {
1066  NS_LOG_FUNCTION (this);
1067  PurgeMac (); // purge the mac cache
1068  for (std::vector<Neighbor>::const_iterator i = m_nb.begin ();
1069  i != m_nb.end (); ++i)
1070  {
1071  if (i->m_neighborAddress == addr)
1072  {
1073  return true;
1074  }
1075  }
1076  return false;
1077 }
1078 
1079 Time
1081 {
1082  NS_LOG_FUNCTION (this);
1083  PurgeMac ();
1084  for (std::vector<Neighbor>::const_iterator i = m_nb.begin (); i
1085  != m_nb.end (); ++i)
1086  {
1087  if (i->m_neighborAddress == addr)
1088  {
1089  return (i->m_expireTime - Simulator::Now ());
1090  }
1091  }
1092  return Seconds (0);
1093 }
1094 
1095 void
1096 RouteCache::UpdateNeighbor (std::vector<Ipv4Address> nodeList, Time expire)
1097 {
1098  NS_LOG_FUNCTION (this);
1099  for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
1100  {
1101  for (std::vector<Ipv4Address>::iterator j = nodeList.begin (); j != nodeList.end (); ++j)
1102  {
1103  if (i->m_neighborAddress == (*j))
1104  {
1105  i->m_expireTime
1106  = std::max (expire + Simulator::Now (), i->m_expireTime);
1107  if (i->m_hardwareAddress == Mac48Address ())
1108  {
1109  i->m_hardwareAddress = LookupMacAddress (i->m_neighborAddress);
1110  }
1111  return;
1112  }
1113  }
1114  }
1115 
1116  Ipv4Address addr;
1117  NS_LOG_LOGIC ("Open link to " << addr);
1118  Neighbor neighbor (addr, LookupMacAddress (addr), expire + Simulator::Now ());
1119  m_nb.push_back (neighbor);
1120  PurgeMac ();
1121 }
1122 
1123 void
1124 RouteCache::AddNeighbor (std::vector<Ipv4Address> nodeList, Ipv4Address ownAddress, Time expire)
1125 {
1126  NS_LOG_LOGIC ("Add neighbor number " << nodeList.size ());
1127  for (std::vector<Ipv4Address>::iterator j = nodeList.begin (); j != nodeList.end (); ++j)
1128  {
1129  Ipv4Address addr = *j;
1130  if (addr == ownAddress)
1131  {
1132  nodeList.erase (j);
1133  NS_LOG_DEBUG ("The node list size " << nodeList.size ());
1134  }
1135  Neighbor neighbor (addr, LookupMacAddress (addr), expire + Simulator::Now ());
1136  m_nb.push_back (neighbor);
1137  PurgeMac ();
1138  }
1139 }
1140 
1142 {
1143  bool operator() (const RouteCache::Neighbor & nb) const
1144  {
1145  return ((nb.m_expireTime < Simulator::Now ()) || nb.close);
1146  }
1147 };
1148 
1149 void
1151 {
1152  if (m_nb.empty ())
1153  {
1154  return;
1155  }
1156 
1157  CloseNeighbor pred;
1158  if (!m_handleLinkFailure.IsNull ())
1159  {
1160  for (std::vector<Neighbor>::iterator j = m_nb.begin (); j != m_nb.end (); ++j)
1161  {
1162  if (pred (*j))
1163  {
1164  NS_LOG_LOGIC ("Close link to " << j->m_neighborAddress);
1165  // disable temporarily TODO
1166 // m_handleLinkFailure (j->m_neighborAddress);
1167  }
1168  }
1169  }
1170  m_nb.erase (std::remove_if (m_nb.begin (), m_nb.end (), pred), m_nb.end ());
1171  m_ntimer.Cancel ();
1172  m_ntimer.Schedule ();
1173 }
1174 
1175 void
1177 {
1178  m_ntimer.Cancel ();
1179  m_ntimer.Schedule ();
1180 }
1181 
1182 void
1184 {
1185  m_arp.push_back (a);
1186 }
1187 
1188 void
1190 {
1191  m_arp.erase (std::remove (m_arp.begin (), m_arp.end (), a), m_arp.end ());
1192 }
1193 
1196 {
1197  Mac48Address hwaddr;
1198  for (std::vector<Ptr<ArpCache> >::const_iterator i = m_arp.begin ();
1199  i != m_arp.end (); ++i)
1200  {
1201  ArpCache::Entry * entry = (*i)->Lookup (addr);
1202  if (entry != 0 && entry->IsAlive () && !entry->IsExpired ())
1203  {
1204  hwaddr = Mac48Address::ConvertFrom (entry->GetMacAddress ());
1205  break;
1206  }
1207  }
1208  return hwaddr;
1209 }
1210 
1211 void
1213 {
1214  Mac48Address addr = hdr.GetAddr1 ();
1215 
1216  for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
1217  {
1218  if (i->m_hardwareAddress == addr)
1219  {
1220  i->close = true;
1221  }
1222  }
1223  PurgeMac ();
1224 }
1225 } // namespace dsr
1226 } // namespace ns3