A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
dsdv-routing-protocol.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Hemanth Narra, 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: Hemanth Narra <hemanth@ittc.ku.com>
19  * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
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 "dsdv-routing-protocol.h"
34 #include "ns3/log.h"
35 #include "ns3/inet-socket-address.h"
36 #include "ns3/trace-source-accessor.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/wifi-net-device.h"
39 #include "ns3/boolean.h"
40 #include "ns3/double.h"
41 #include "ns3/uinteger.h"
42 
43 NS_LOG_COMPONENT_DEFINE ("DsdvRoutingProtocol");
44 
45 namespace ns3 {
46 namespace dsdv {
47 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
48 
50 const uint32_t RoutingProtocol::DSDV_PORT = 269;
51 
53 struct DeferredRouteOutputTag : public Tag
54 {
56  int32_t oif;
57 
58  DeferredRouteOutputTag (int32_t o = -1)
59  : Tag (),
60  oif (o)
61  {
62  }
63 
64  static TypeId
65  GetTypeId ()
66  {
67  static TypeId tid = TypeId ("ns3::dsdv::DeferredRouteOutputTag").SetParent<Tag> ();
68  return tid;
69  }
70 
71  TypeId
73  {
74  return GetTypeId ();
75  }
76 
77  uint32_t
79  {
80  return sizeof(int32_t);
81  }
82 
83  void
84  Serialize (TagBuffer i) const
85  {
86  i.WriteU32 (oif);
87  }
88 
89  void
91  {
92  oif = i.ReadU32 ();
93  }
94 
95  void
96  Print (std::ostream &os) const
97  {
98  os << "DeferredRouteOutputTag: output interface = " << oif;
99  }
100 };
101 
102 TypeId
103 RoutingProtocol::GetTypeId (void)
104 {
105  static TypeId tid = TypeId ("ns3::dsdv::RoutingProtocol")
107  .AddConstructor<RoutingProtocol> ()
108  .AddAttribute ("PeriodicUpdateInterval","Periodic interval between exchange of full routing tables among nodes. ",
109  TimeValue (Seconds (15)),
110  MakeTimeAccessor (&RoutingProtocol::m_periodicUpdateInterval),
111  MakeTimeChecker ())
112  .AddAttribute ("SettlingTime", "Minimum time an update is to be stored in adv table before sending out"
113  "in case of change in metric (in seconds)",
114  TimeValue (Seconds (5)),
115  MakeTimeAccessor (&RoutingProtocol::m_settlingTime),
116  MakeTimeChecker ())
117  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
118  UintegerValue (500 /*assuming maximum nodes in simulation is 100*/),
119  MakeUintegerAccessor (&RoutingProtocol::m_maxQueueLen),
120  MakeUintegerChecker<uint32_t> ())
121  .AddAttribute ("MaxQueuedPacketsPerDst", "Maximum number of packets that we allow per destination to buffer.",
122  UintegerValue (5),
123  MakeUintegerAccessor (&RoutingProtocol::m_maxQueuedPacketsPerDst),
124  MakeUintegerChecker<uint32_t> ())
125  .AddAttribute ("MaxQueueTime","Maximum time packets can be queued (in seconds)",
126  TimeValue (Seconds (30)),
127  MakeTimeAccessor (&RoutingProtocol::m_maxQueueTime),
128  MakeTimeChecker ())
129  .AddAttribute ("EnableBuffering","Enables buffering of data packets if no route to destination is available",
130  BooleanValue (true),
131  MakeBooleanAccessor (&RoutingProtocol::SetEnableBufferFlag,
132  &RoutingProtocol::GetEnableBufferFlag),
133  MakeBooleanChecker ())
134  .AddAttribute ("EnableWST","Enables Weighted Settling Time for the updates before advertising",
135  BooleanValue (true),
136  MakeBooleanAccessor (&RoutingProtocol::SetWSTFlag,
137  &RoutingProtocol::GetWSTFlag),
138  MakeBooleanChecker ())
139  .AddAttribute ("Holdtimes","Times the forwarding Interval to purge the route.",
140  UintegerValue (3),
141  MakeUintegerAccessor (&RoutingProtocol::Holdtimes),
142  MakeUintegerChecker<uint32_t> ())
143  .AddAttribute ("WeightedFactor","WeightedFactor for the settling time if Weighted Settling Time is enabled",
144  DoubleValue (0.875),
145  MakeDoubleAccessor (&RoutingProtocol::m_weightedFactor),
146  MakeDoubleChecker<double> ())
147  .AddAttribute ("EnableRouteAggregation","Enables Weighted Settling Time for the updates before advertising",
148  BooleanValue (false),
149  MakeBooleanAccessor (&RoutingProtocol::SetEnableRAFlag,
150  &RoutingProtocol::GetEnableRAFlag),
151  MakeBooleanChecker ())
152  .AddAttribute ("RouteAggregationTime","Time to aggregate updates before sending them out (in seconds)",
153  TimeValue (Seconds (1)),
154  MakeTimeAccessor (&RoutingProtocol::m_routeAggregationTime),
155  MakeTimeChecker ());
156  return tid;
157 }
158 
159 void
160 RoutingProtocol::SetEnableBufferFlag (bool f)
161 {
162  EnableBuffering = f;
163 }
164 bool
165 RoutingProtocol::GetEnableBufferFlag () const
166 {
167  return EnableBuffering;
168 }
169 void
170 RoutingProtocol::SetWSTFlag (bool f)
171 {
172  EnableWST = f;
173 }
174 bool
175 RoutingProtocol::GetWSTFlag () const
176 {
177  return EnableWST;
178 }
179 void
180 RoutingProtocol::SetEnableRAFlag (bool f)
181 {
183 }
184 bool
185 RoutingProtocol::GetEnableRAFlag () const
186 {
187  return EnableRouteAggregation;
188 }
189 
190 int64_t
192 {
193  NS_LOG_FUNCTION (this << stream);
195  return 1;
196 }
197 
199  : m_routingTable (),
200  m_advRoutingTable (),
201  m_queue (),
202  m_periodicUpdateTimer (Timer::CANCEL_ON_DESTROY)
203 {
204  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
205 }
206 
207 RoutingProtocol::~RoutingProtocol ()
208 {
209 }
210 
211 void
213 {
214  m_ipv4 = 0;
215  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter = m_socketAddresses.begin (); iter
216  != m_socketAddresses.end (); iter++)
217  {
218  iter->first->Close ();
219  }
220  m_socketAddresses.clear ();
222 }
223 
224 void
226 {
227  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now ().GetSeconds () << "s ";
228  m_routingTable.Print (stream);
229 }
230 
231 void
233 {
234  m_queue.SetMaxPacketsPerDst (m_maxQueuedPacketsPerDst);
235  m_queue.SetMaxQueueLen (m_maxQueueLen);
236  m_queue.SetQueueTimeout (m_maxQueueTime);
238  m_advRoutingTable.Setholddowntime (Time (Holdtimes * m_periodicUpdateInterval));
239  m_scb = MakeCallback (&RoutingProtocol::Send,this);
243 }
244 
247  const Ipv4Header &header,
248  Ptr<NetDevice> oif,
249  Socket::SocketErrno &sockerr)
250 {
251  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
252 
253  if (!p)
254  {
255  return LoopbackRoute (header,oif);
256  }
257  if (m_socketAddresses.empty ())
258  {
259  sockerr = Socket::ERROR_NOROUTETOHOST;
260  NS_LOG_LOGIC ("No dsdv interfaces");
261  Ptr<Ipv4Route> route;
262  return route;
263  }
264  std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
265  sockerr = Socket::ERROR_NOTERROR;
266  Ptr<Ipv4Route> route;
267  Ipv4Address dst = header.GetDestination ();
268  NS_LOG_DEBUG ("Packet Size: " << p->GetSize ()
269  << ", Packet id: " << p->GetUid () << ", Destination address in Packet: " << dst);
271  m_routingTable.Purge (removedAddresses);
272  for (std::map<Ipv4Address, RoutingTableEntry>::iterator rmItr = removedAddresses.begin ();
273  rmItr != removedAddresses.end (); ++rmItr)
274  {
275  rmItr->second.SetEntriesChanged (true);
276  rmItr->second.SetSeqNo (rmItr->second.GetSeqNo () + 1);
277  m_advRoutingTable.AddRoute (rmItr->second);
278  }
279  if (!removedAddresses.empty ())
280  {
282  }
283  if (m_routingTable.LookupRoute (dst,rt))
284  {
285  if (EnableBuffering)
286  {
288  }
289  if (rt.GetHop () == 1)
290  {
291  route = rt.GetRoute ();
292  NS_ASSERT (route != 0);
293  NS_LOG_DEBUG ("A route exists from " << route->GetSource ()
294  << " to neighboring destination "
295  << route->GetDestination ());
296  if (oif != 0 && route->GetOutputDevice () != oif)
297  {
298  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
299  sockerr = Socket::ERROR_NOROUTETOHOST;
300  return Ptr<Ipv4Route> ();
301  }
302  return route;
303  }
304  else
305  {
306  RoutingTableEntry newrt;
307  if (m_routingTable.LookupRoute (rt.GetNextHop (),newrt))
308  {
309  route = newrt.GetRoute ();
310  NS_ASSERT (route != 0);
311  NS_LOG_DEBUG ("A route exists from " << route->GetSource ()
312  << " to destination " << dst << " via "
313  << rt.GetNextHop ());
314  if (oif != 0 && route->GetOutputDevice () != oif)
315  {
316  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
317  sockerr = Socket::ERROR_NOROUTETOHOST;
318  return Ptr<Ipv4Route> ();
319  }
320  return route;
321  }
322  }
323  }
324 
325  if (EnableBuffering)
326  {
327  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
328  DeferredRouteOutputTag tag (iif);
329  if (!p->PeekPacketTag (tag))
330  {
331  p->AddPacketTag (tag);
332  }
333  }
334  return LoopbackRoute (header,oif);
335 }
336 
337 void
339  const Ipv4Header & header,
340  UnicastForwardCallback ucb,
341  ErrorCallback ecb)
342 {
343  NS_LOG_FUNCTION (this << p << header);
344  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
345  QueueEntry newEntry (p,header,ucb,ecb);
346  bool result = m_queue.Enqueue (newEntry);
347  if (result)
348  {
349  NS_LOG_DEBUG ("Added packet " << p->GetUid () << " to queue.");
350  }
351 }
352 
353 bool
354 RoutingProtocol::RouteInput (Ptr<const Packet> p,
355  const Ipv4Header &header,
357  UnicastForwardCallback ucb,
358  MulticastForwardCallback mcb,
359  LocalDeliverCallback lcb,
360  ErrorCallback ecb)
361 {
362  NS_LOG_FUNCTION (m_mainAddress << " received packet " << p->GetUid ()
363  << " from " << header.GetSource ()
364  << " on interface " << idev->GetAddress ()
365  << " to destination " << header.GetDestination ());
366  if (m_socketAddresses.empty ())
367  {
368  NS_LOG_DEBUG ("No dsdv interfaces");
369  return false;
370  }
371  NS_ASSERT (m_ipv4 != 0);
372  // Check if input device supports IP
373  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
374  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
375 
376  Ipv4Address dst = header.GetDestination ();
377  Ipv4Address origin = header.GetSource ();
378 
379  // DSDV is not a multicast routing protocol
380  if (dst.IsMulticast ())
381  {
382  return false;
383  }
384 
385  // Deferred route request
386  if (EnableBuffering == true && idev == m_lo)
387  {
388  DeferredRouteOutputTag tag;
389  if (p->PeekPacketTag (tag))
390  {
391  DeferredRouteOutput (p,header,ucb,ecb);
392  return true;
393  }
394  }
395  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
396  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
397  {
398  Ipv4InterfaceAddress iface = j->second;
399  if (origin == iface.GetLocal ())
400  {
401  return true;
402  }
403  }
404  // LOCAL DELIVARY TO DSDV INTERFACES
405  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
406  != m_socketAddresses.end (); ++j)
407  {
408  Ipv4InterfaceAddress iface = j->second;
409  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
410  {
411  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
412  {
413  Ptr<Packet> packet = p->Copy ();
414  if (lcb.IsNull () == false)
415  {
416  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
417  lcb (p, header, iif);
418  // Fall through to additional processing
419  }
420  else
421  {
422  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
423  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
424  }
425  if (header.GetTtl () > 1)
426  {
427  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
428  RoutingTableEntry toBroadcast;
429  if (m_routingTable.LookupRoute (dst,toBroadcast,true))
430  {
431  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
432  ucb (route,packet,header);
433  }
434  else
435  {
436  NS_LOG_DEBUG ("No route to forward. Drop packet " << p->GetUid ());
437  }
438  }
439  return true;
440  }
441  }
442  }
443 
444  if (m_ipv4->IsDestinationAddress (dst, iif))
445  {
446  if (lcb.IsNull () == false)
447  {
448  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
449  lcb (p, header, iif);
450  }
451  else
452  {
453  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
454  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
455  }
456  return true;
457  }
458  RoutingTableEntry toDst;
459  if (m_routingTable.LookupRoute (dst,toDst))
460  {
461  RoutingTableEntry ne;
462  if (m_routingTable.LookupRoute (toDst.GetNextHop (),ne))
463  {
464  Ptr<Ipv4Route> route = ne.GetRoute ();
465  NS_LOG_LOGIC (m_mainAddress << " is forwarding packet " << p->GetUid ()
466  << " to " << dst
467  << " from " << header.GetSource ()
468  << " via nexthop neighbor " << toDst.GetNextHop ());
469  ucb (route,p,header);
470  return true;
471  }
472  }
473  NS_LOG_LOGIC ("Drop packet " << p->GetUid ()
474  << " as there is no route to forward it.");
475  return false;
476 }
477 
478 Ptr<Ipv4Route>
480 {
481  NS_ASSERT (m_lo != 0);
482  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
483  rt->SetDestination (hdr.GetDestination ());
484  // rt->SetSource (hdr.GetSource ());
485  //
486  // Source address selection here is tricky. The loopback route is
487  // returned when DSDV does not have a route; this causes the packet
488  // to be looped back and handled (cached) in RouteInput() method
489  // while a route is found. However, connection-oriented protocols
490  // like TCP need to create an endpoint four-tuple (src, src port,
491  // dst, dst port) and create a pseudo-header for checksumming. So,
492  // DSDV needs to guess correctly what the eventual source address
493  // will be.
494  //
495  // For single interface, single address nodes, this is not a problem.
496  // When there are possibly multiple outgoing interfaces, the policy
497  // implemented here is to pick the first available DSDV interface.
498  // If RouteOutput() caller specified an outgoing interface, that
499  // further constrains the selection of source address
500  //
501  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
502  if (oif)
503  {
504  // Iterate to find an address on the oif device
505  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
506  {
507  Ipv4Address addr = j->second.GetLocal ();
508  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
509  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
510  {
511  rt->SetSource (addr);
512  break;
513  }
514  }
515  }
516  else
517  {
518  rt->SetSource (j->second.GetLocal ());
519  }
520  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid DSDV source address not found");
521  rt->SetGateway (Ipv4Address ("127.0.0.1"));
522  rt->SetOutputDevice (m_lo);
523  return rt;
524 }
525 
526 void
528 {
529  Address sourceAddress;
530  Ptr<Packet> advpacket = Create<Packet> ();
531  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
532  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
533  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
534  Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
535  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
536  uint32_t packetSize = packet->GetSize ();
537  NS_LOG_FUNCTION (m_mainAddress << " received dsdv packet of size: " << packetSize
538  << " and packet id: " << packet->GetUid ());
539  uint32_t count = 0;
540  for (; packetSize > 0; packetSize = packetSize - 12)
541  {
542  count = 0;
543  DsdvHeader dsdvHeader, tempDsdvHeader;
544  packet->RemoveHeader (dsdvHeader);
545  NS_LOG_DEBUG ("Processing new update for " << dsdvHeader.GetDst ());
546  /*Verifying if the packets sent by me were returned back to me. If yes, discarding them!*/
547  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
548  != m_socketAddresses.end (); ++j)
549  {
550  Ipv4InterfaceAddress interface = j->second;
551  if (dsdvHeader.GetDst () == interface.GetLocal ())
552  {
553  if (dsdvHeader.GetDstSeqno () % 2 == 1)
554  {
555  NS_LOG_DEBUG ("Sent Dsdv update back to the same Destination, "
556  "with infinite metric. Time left to send fwd update: "
558  count++;
559  }
560  else
561  {
562  NS_LOG_DEBUG ("Received update for my address. Discarding this.");
563  count++;
564  }
565  }
566  }
567  if (count > 0)
568  {
569  continue;
570  }
571  NS_LOG_DEBUG ("Received a DSDV packet from "
572  << sender << " to " << receiver << ". Details are: Destination: " << dsdvHeader.GetDst () << ", Seq No: "
573  << dsdvHeader.GetDstSeqno () << ", HopCount: " << dsdvHeader.GetHopCount ());
574  RoutingTableEntry fwdTableEntry, advTableEntry;
575  EventId event;
576  bool permanentTableVerifier = m_routingTable.LookupRoute (dsdvHeader.GetDst (),fwdTableEntry);
577  if (permanentTableVerifier == false)
578  {
579  if (dsdvHeader.GetDstSeqno () % 2 != 1)
580  {
581  NS_LOG_DEBUG ("Received New Route!");
582  RoutingTableEntry newEntry (
583  /*device=*/ dev, /*dst=*/
584  dsdvHeader.GetDst (), /*seqno=*/
585  dsdvHeader.GetDstSeqno (),
586  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
587  /*hops=*/ dsdvHeader.GetHopCount (), /*next hop=*/
588  sender, /*lifetime=*/
589  Simulator::Now (), /*settlingTime*/
590  m_settlingTime, /*entries changed*/
591  true);
592  newEntry.SetFlag (VALID);
593  m_routingTable.AddRoute (newEntry);
594  NS_LOG_DEBUG ("New Route added to both tables");
595  m_advRoutingTable.AddRoute (newEntry);
596  }
597  else
598  {
599  // received update not present in main routing table and also with infinite metric
600  NS_LOG_DEBUG ("Discarding this update as this route is not present in "
601  "main routing table and received with infinite metric");
602  }
603  }
604  else
605  {
606  if (!m_advRoutingTable.LookupRoute (dsdvHeader.GetDst (),advTableEntry))
607  {
609  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
611  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
612  {
613  NS_LOG_DEBUG ("ADV table routes are:" << i->second.GetDestination ());
614  }
615  // present in fwd table and not in advtable
616  m_advRoutingTable.AddRoute (fwdTableEntry);
617  m_advRoutingTable.LookupRoute (dsdvHeader.GetDst (),advTableEntry);
618  }
619  if (dsdvHeader.GetDstSeqno () % 2 != 1)
620  {
621  if (dsdvHeader.GetDstSeqno () > advTableEntry.GetSeqNo ())
622  {
623  // Received update with better seq number. Clear any old events that are running
624  if (m_advRoutingTable.ForceDeleteIpv4Event (dsdvHeader.GetDst ()))
625  {
626  NS_LOG_DEBUG ("Canceling the timer to update route with better seq number");
627  }
628  // if its a changed metric *nomatter* where the update came from, wait for WST
629  if (dsdvHeader.GetHopCount () != advTableEntry.GetHop ())
630  {
631  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
632  advTableEntry.SetLifeTime (Simulator::Now ());
633  advTableEntry.SetFlag (VALID);
634  advTableEntry.SetEntriesChanged (true);
635  advTableEntry.SetNextHop (sender);
636  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
637  NS_LOG_DEBUG ("Received update with better sequence number and changed metric.Waiting for WST");
638  Time tempSettlingtime = GetSettlingTime (dsdvHeader.GetDst ());
639  advTableEntry.SetSettlingTime (tempSettlingtime);
640  NS_LOG_DEBUG ("Added Settling Time:" << tempSettlingtime.GetSeconds ()
641  << "s as there is no event running for this route");
642  event = Simulator::Schedule (tempSettlingtime,&RoutingProtocol::SendTriggeredUpdate,this);
643  m_advRoutingTable.AddIpv4Event (dsdvHeader.GetDst (),event);
644  NS_LOG_DEBUG ("EventCreated EventUID: " << event.GetUid ());
645  // if received changed metric, use it but adv it only after wst
646  m_routingTable.Update (advTableEntry);
647  m_advRoutingTable.Update (advTableEntry);
648  }
649  else
650  {
651  // Received update with better seq number and same metric.
652  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
653  advTableEntry.SetLifeTime (Simulator::Now ());
654  advTableEntry.SetFlag (VALID);
655  advTableEntry.SetEntriesChanged (true);
656  advTableEntry.SetNextHop (sender);
657  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
658  m_advRoutingTable.Update (advTableEntry);
659  NS_LOG_DEBUG ("Route with better sequence number and same metric received. Advertised without WST");
660  }
661  }
662  else if (dsdvHeader.GetDstSeqno () == advTableEntry.GetSeqNo ())
663  {
664  if (dsdvHeader.GetHopCount () < advTableEntry.GetHop ())
665  {
666  /*Received update with same seq number and better hop count.
667  * As the metric is changed, we will have to wait for WST before sending out this update.
668  */
669  NS_LOG_DEBUG ("Canceling any existing timer to update route with same sequence number "
670  "and better hop count");
671  m_advRoutingTable.ForceDeleteIpv4Event (dsdvHeader.GetDst ());
672  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
673  advTableEntry.SetLifeTime (Simulator::Now ());
674  advTableEntry.SetFlag (VALID);
675  advTableEntry.SetEntriesChanged (true);
676  advTableEntry.SetNextHop (sender);
677  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
678  Time tempSettlingtime = GetSettlingTime (dsdvHeader.GetDst ());
679  advTableEntry.SetSettlingTime (tempSettlingtime);
680  NS_LOG_DEBUG ("Added Settling Time," << tempSettlingtime.GetSeconds ()
681  << " as there is no current event running for this route");
682  event = Simulator::Schedule (tempSettlingtime,&RoutingProtocol::SendTriggeredUpdate,this);
683  m_advRoutingTable.AddIpv4Event (dsdvHeader.GetDst (),event);
684  NS_LOG_DEBUG ("EventCreated EventUID: " << event.GetUid ());
685  // if received changed metric, use it but adv it only after wst
686  m_routingTable.Update (advTableEntry);
687  m_advRoutingTable.Update (advTableEntry);
688  }
689  else
690  {
691  /*Received update with same seq number but with same or greater hop count.
692  * Discard that update.
693  */
694  if (not m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
695  {
696  /*update the timer only if nexthop address matches thus discarding
697  * updates to that destination from other nodes.
698  */
699  if (advTableEntry.GetNextHop () == sender)
700  {
701  advTableEntry.SetLifeTime (Simulator::Now ());
702  m_routingTable.Update (advTableEntry);
703  }
705  dsdvHeader.GetDst ());
706  }
707  NS_LOG_DEBUG ("Received update with same seq number and "
708  "same/worst metric for, " << dsdvHeader.GetDst () << ". Discarding the update.");
709  }
710  }
711  else
712  {
713  // Received update with an old sequence number. Discard the update
714  if (not m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
715  {
716  m_advRoutingTable.DeleteRoute (dsdvHeader.GetDst ());
717  }
718  NS_LOG_DEBUG (dsdvHeader.GetDst () << " : Received update with old seq number. Discarding the update.");
719  }
720  }
721  else
722  {
723  NS_LOG_DEBUG ("Route with infinite metric received for "
724  << dsdvHeader.GetDst () << " from " << sender);
725  // Delete route only if update was received from my nexthop neighbor
726  if (sender == advTableEntry.GetNextHop ())
727  {
728  NS_LOG_DEBUG ("Triggering an update for this unreachable route:");
729  std::map<Ipv4Address, RoutingTableEntry> dstsWithNextHopSrc;
730  m_routingTable.GetListOfDestinationWithNextHop (dsdvHeader.GetDst (),dstsWithNextHopSrc);
731  m_routingTable.DeleteRoute (dsdvHeader.GetDst ());
732  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
733  advTableEntry.SetEntriesChanged (true);
734  m_advRoutingTable.Update (advTableEntry);
735  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i = dstsWithNextHopSrc.begin (); i
736  != dstsWithNextHopSrc.end (); ++i)
737  {
738  i->second.SetSeqNo (i->second.GetSeqNo () + 1);
739  i->second.SetEntriesChanged (true);
740  m_advRoutingTable.AddRoute (i->second);
741  m_routingTable.DeleteRoute (i->second.GetDestination ());
742  }
743  }
744  else
745  {
746  if (not m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
747  {
748  m_advRoutingTable.DeleteRoute (dsdvHeader.GetDst ());
749  }
750  NS_LOG_DEBUG (dsdvHeader.GetDst () <<
751  " : Discard this link break update as it was received from a different neighbor "
752  "and I can reach the destination");
753  }
754  }
755  }
756  }
757  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
759  if (EnableRouteAggregation && allRoutes.size () > 0)
760  {
762  }
763  else
764  {
766  }
767 }
768 
769 
770 void
772 {
773  NS_LOG_FUNCTION (m_mainAddress << " is sending a triggered update");
774  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
776  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
777  != m_socketAddresses.end (); ++j)
778  {
779  DsdvHeader dsdvHeader;
780  Ptr<Socket> socket = j->first;
781  Ipv4InterfaceAddress iface = j->second;
782  Ptr<Packet> packet = Create<Packet> ();
783  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
784  {
785  NS_LOG_LOGIC ("Destination: " << i->second.GetDestination ()
786  << " SeqNo:" << i->second.GetSeqNo () << " HopCount:"
787  << i->second.GetHop () + 1);
788  RoutingTableEntry temp = i->second;
789  if ((i->second.GetEntriesChanged () == true) && (not m_advRoutingTable.AnyRunningEvent (temp.GetDestination ())))
790  {
791  dsdvHeader.SetDst (i->second.GetDestination ());
792  dsdvHeader.SetDstSeqno (i->second.GetSeqNo ());
793  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
794  temp.SetFlag (VALID);
795  temp.SetEntriesChanged (false);
796  m_advRoutingTable.DeleteIpv4Event (temp.GetDestination ());
797  if (!(temp.GetSeqNo () % 2))
798  {
799  m_routingTable.Update (temp);
800  }
801  packet->AddHeader (dsdvHeader);
802  m_advRoutingTable.DeleteRoute (temp.GetDestination ());
803  NS_LOG_DEBUG ("Deleted this route from the advertised table");
804  }
805  else
806  {
807  EventId event = m_advRoutingTable.GetEventId (temp.GetDestination ());
808  NS_ASSERT (event.GetUid () != 0);
809  NS_LOG_DEBUG ("EventID " << event.GetUid () << " associated with "
810  << temp.GetDestination () << " has not expired, waiting in adv table");
811  }
812  }
813  if (packet->GetSize () >= 12)
814  {
815  RoutingTableEntry temp2;
816  m_routingTable.LookupRoute (m_ipv4->GetAddress (1, 0).GetBroadcast (), temp2);
817  dsdvHeader.SetDst (m_ipv4->GetAddress (1, 0).GetLocal ());
818  dsdvHeader.SetDstSeqno (temp2.GetSeqNo ());
819  dsdvHeader.SetHopCount (temp2.GetHop () + 1);
820  NS_LOG_DEBUG ("Adding my update as well to the packet");
821  packet->AddHeader (dsdvHeader);
822  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
823  Ipv4Address destination;
824  if (iface.GetMask () == Ipv4Mask::GetOnes ())
825  {
826  destination = Ipv4Address ("255.255.255.255");
827  }
828  else
829  {
830  destination = iface.GetBroadcast ();
831  }
832  socket->SendTo (packet, 0, InetSocketAddress (destination, DSDV_PORT));
833  NS_LOG_FUNCTION ("Sent Triggered Update from "
834  << dsdvHeader.GetDst ()
835  << " with packet id : " << packet->GetUid () << " and packet Size: " << packet->GetSize ());
836  }
837  else
838  {
839  NS_LOG_FUNCTION ("Update not sent as there are no updates to be triggered");
840  }
841  }
842 }
843 
844 void
846 {
847  std::map<Ipv4Address, RoutingTableEntry> removedAddresses, allRoutes;
848  m_routingTable.Purge (removedAddresses);
849  MergeTriggerPeriodicUpdates ();
851  if (allRoutes.empty ())
852  {
853  return;
854  }
855  NS_LOG_FUNCTION (m_mainAddress << " is sending out its periodic update");
856  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
857  != m_socketAddresses.end (); ++j)
858  {
859  Ptr<Socket> socket = j->first;
860  Ipv4InterfaceAddress iface = j->second;
861  Ptr<Packet> packet = Create<Packet> ();
862  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
863  {
864  DsdvHeader dsdvHeader;
865  if (i->second.GetHop () == 0)
866  {
867  RoutingTableEntry ownEntry;
868  dsdvHeader.SetDst (m_ipv4->GetAddress (1,0).GetLocal ());
869  dsdvHeader.SetDstSeqno (i->second.GetSeqNo () + 2);
870  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
871  m_routingTable.LookupRoute (m_ipv4->GetAddress (1,0).GetBroadcast (),ownEntry);
872  ownEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
873  m_routingTable.Update (ownEntry);
874  packet->AddHeader (dsdvHeader);
875  }
876  else
877  {
878  dsdvHeader.SetDst (i->second.GetDestination ());
879  dsdvHeader.SetDstSeqno ((i->second.GetSeqNo ()));
880  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
881  packet->AddHeader (dsdvHeader);
882  }
883  NS_LOG_DEBUG ("Forwarding the update for " << i->first);
884  NS_LOG_DEBUG ("Forwarding details are, Destination: " << dsdvHeader.GetDst ()
885  << ", SeqNo:" << dsdvHeader.GetDstSeqno ()
886  << ", HopCount:" << dsdvHeader.GetHopCount ()
887  << ", LifeTime: " << i->second.GetLifeTime ().GetSeconds ());
888  }
889  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator rmItr = removedAddresses.begin (); rmItr
890  != removedAddresses.end (); ++rmItr)
891  {
892  DsdvHeader removedHeader;
893  removedHeader.SetDst (rmItr->second.GetDestination ());
894  removedHeader.SetDstSeqno (rmItr->second.GetSeqNo () + 1);
895  removedHeader.SetHopCount (rmItr->second.GetHop () + 1);
896  packet->AddHeader (removedHeader);
897  NS_LOG_DEBUG ("Update for removed record is: Destination: " << removedHeader.GetDst ()
898  << " SeqNo:" << removedHeader.GetDstSeqno ()
899  << " HopCount:" << removedHeader.GetHopCount ());
900  }
901  socket->Send (packet);
902  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
903  Ipv4Address destination;
904  if (iface.GetMask () == Ipv4Mask::GetOnes ())
905  {
906  destination = Ipv4Address ("255.255.255.255");
907  }
908  else
909  {
910  destination = iface.GetBroadcast ();
911  }
912  socket->SendTo (packet, 0, InetSocketAddress (destination, DSDV_PORT));
913  NS_LOG_FUNCTION ("PeriodicUpdate Packet UID is : " << packet->GetUid ());
914  }
916 }
917 
918 void
920 {
921  NS_ASSERT (ipv4 != 0);
922  NS_ASSERT (m_ipv4 == 0);
923  m_ipv4 = ipv4;
924  // Create lo route. It is asserted that the only one interface up for now is loopback
925  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
926  m_lo = m_ipv4->GetNetDevice (0);
927  NS_ASSERT (m_lo != 0);
928  // Remember lo route
929  RoutingTableEntry rt (
930  /*device=*/ m_lo, /*dst=*/
931  Ipv4Address::GetLoopback (), /*seqno=*/
932  0,
933  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (),Ipv4Mask ("255.0.0.0")),
934  /*hops=*/ 0, /*next hop=*/
936  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
937  rt.SetFlag (INVALID);
938  rt.SetEntriesChanged (false);
941 }
942 
943 void
945 {
946  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ()
947  << " interface is up");
948  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
949  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
950  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
951  {
952  return;
953  }
954  // Create a socket to listen only on this interface
955  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
956  NS_ASSERT (socket != 0);
958  socket->BindToNetDevice (l3->GetNetDevice (i));
960  socket->SetAllowBroadcast (true);
961  socket->SetAttribute ("IpTtl",UintegerValue (1));
962  m_socketAddresses.insert (std::make_pair (socket,iface));
963  // Add local broadcast record to the routing table
964  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
965  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*seqno=*/ 0,/*iface=*/ iface,/*hops=*/ 0,
966  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
968  if (m_mainAddress == Ipv4Address ())
969  {
970  m_mainAddress = iface.GetLocal ();
971  }
973 }
974 
975 void
977 {
978  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
979  Ptr<NetDevice> dev = l3->GetNetDevice (i);
980  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i,0));
981  NS_ASSERT (socket);
982  socket->Close ();
983  m_socketAddresses.erase (socket);
984  if (m_socketAddresses.empty ())
985  {
986  NS_LOG_LOGIC ("No dsdv interfaces");
988  return;
989  }
992 }
993 
994 void
996  Ipv4InterfaceAddress address)
997 {
998  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
999  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1000  if (!l3->IsUp (i))
1001  {
1002  return;
1003  }
1004  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
1006  if (!socket)
1007  {
1008  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
1009  {
1010  return;
1011  }
1012  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
1013  NS_ASSERT (socket != 0);
1015  socket->BindToNetDevice (l3->GetNetDevice (i));
1016  // Bind to any IP address so that broadcasts can be received
1018  socket->SetAllowBroadcast (true);
1019  m_socketAddresses.insert (std::make_pair (socket,iface));
1020  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
1021  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (),/*seqno=*/ 0, /*iface=*/ iface,/*hops=*/ 0,
1022  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
1023  m_routingTable.AddRoute (rt);
1024  }
1025 }
1026 
1027 void
1029  Ipv4InterfaceAddress address)
1030 {
1031  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
1032  if (socket)
1033  {
1034  m_socketAddresses.erase (socket);
1035  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1036  if (l3->GetNAddresses (i))
1037  {
1038  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
1039  // Create a socket to listen only on this interface
1040  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
1041  NS_ASSERT (socket != 0);
1043  // Bind to any IP address so that broadcasts can be received
1045  socket->SetAllowBroadcast (true);
1046  m_socketAddresses.insert (std::make_pair (socket,iface));
1047  }
1048  }
1049 }
1050 
1053 {
1054  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
1055  != m_socketAddresses.end (); ++j)
1056  {
1057  Ptr<Socket> socket = j->first;
1058  Ipv4InterfaceAddress iface = j->second;
1059  if (iface == addr)
1060  {
1061  return socket;
1062  }
1063  }
1064  Ptr<Socket> socket;
1065  return socket;
1066 }
1067 
1068 void
1069 RoutingProtocol::Send (Ptr<Ipv4Route> route,
1070  Ptr<const Packet> packet,
1071  const Ipv4Header & header)
1072 {
1073  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1074  NS_ASSERT (l3 != 0);
1075  Ptr<Packet> p = packet->Copy ();
1076  l3->Send (p,route->GetSource (),header.GetDestination (),header.GetProtocol (),route);
1077 }
1078 
1079 void
1081  const Ipv4Header & header,
1082  Socket::SocketErrno err)
1083 {
1084  NS_LOG_DEBUG (m_mainAddress << " drop packet " << packet->GetUid () << " to "
1085  << header.GetDestination () << " from queue. Error " << err);
1086 }
1087 
1088 void
1090 {
1091  NS_LOG_FUNCTION (this);
1092  Ptr<Ipv4Route> route;
1093  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1094  m_routingTable.GetListOfAllRoutes (allRoutes);
1095  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1096  {
1097  RoutingTableEntry rt;
1098  rt = i->second;
1099  if (m_queue.Find (rt.GetDestination ()))
1100  {
1101  if (rt.GetHop () == 1)
1102  {
1103  route = rt.GetRoute ();
1104  NS_LOG_LOGIC ("A route exists from " << route->GetSource ()
1105  << " to neighboring destination "
1106  << route->GetDestination ());
1107  NS_ASSERT (route != 0);
1108  }
1109  else
1110  {
1111  RoutingTableEntry newrt;
1112  m_routingTable.LookupRoute (rt.GetNextHop (),newrt);
1113  route = newrt.GetRoute ();
1114  NS_LOG_LOGIC ("A route exists from " << route->GetSource ()
1115  << " to destination " << route->GetDestination () << " via "
1116  << rt.GetNextHop ());
1117  NS_ASSERT (route != 0);
1118  }
1119  SendPacketFromQueue (rt.GetDestination (),route);
1120  }
1121  }
1122 }
1123 
1124 void
1126  Ptr<Ipv4Route> route)
1127 {
1128  NS_LOG_DEBUG (m_mainAddress << " is sending a queued packet to destination " << dst);
1129  QueueEntry queueEntry;
1130  if (m_queue.Dequeue (dst,queueEntry))
1131  {
1133  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1134  if (p->RemovePacketTag (tag))
1135  {
1136  if (tag.oif != -1 && tag.oif != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1137  {
1138  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1139  return;
1140  }
1141  }
1142  UnicastForwardCallback ucb = queueEntry.GetUnicastForwardCallback ();
1143  Ipv4Header header = queueEntry.GetIpv4Header ();
1144  header.SetSource (route->GetSource ());
1145  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1146  ucb (route,p,header);
1147  if (m_queue.GetSize () != 0 && m_queue.Find (dst))
1148  {
1150  &RoutingProtocol::SendPacketFromQueue,this,dst,route);
1151  }
1152  }
1153 }
1154 
1155 Time
1157 {
1158  NS_LOG_FUNCTION ("Calculating the settling time for " << address);
1159  RoutingTableEntry mainrt;
1160  Time weightedTime;
1161  m_routingTable.LookupRoute (address,mainrt);
1162  if (EnableWST)
1163  {
1164  if (mainrt.GetSettlingTime () == Seconds (0))
1165  {
1166  return Seconds (0);
1167  }
1168  else
1169  {
1170  NS_LOG_DEBUG ("Route SettlingTime: " << mainrt.GetSettlingTime ().GetSeconds ()
1171  << " and LifeTime:" << mainrt.GetLifeTime ().GetSeconds ());
1172  weightedTime = Time (m_weightedFactor * mainrt.GetSettlingTime ().GetSeconds () + (1.0 - m_weightedFactor)
1173  * mainrt.GetLifeTime ().GetSeconds ());
1174  NS_LOG_DEBUG ("Calculated weightedTime:" << weightedTime.GetSeconds ());
1175  return weightedTime;
1176  }
1177  }
1178  return mainrt.GetSettlingTime ();
1179 }
1180 
1181 void
1182 RoutingProtocol::MergeTriggerPeriodicUpdates ()
1183 {
1184  NS_LOG_FUNCTION ("Merging advertised table changes with main table before sending out periodic update");
1185  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1187  if (allRoutes.size () > 0)
1188  {
1189  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1190  {
1191  RoutingTableEntry advEntry = i->second;
1192  if ((advEntry.GetEntriesChanged () == true) && (not m_advRoutingTable.AnyRunningEvent (advEntry.GetDestination ())))
1193  {
1194  if (!(advEntry.GetSeqNo () % 2))
1195  {
1196  advEntry.SetFlag (VALID);
1197  advEntry.SetEntriesChanged (false);
1198  m_routingTable.Update (advEntry);
1199  NS_LOG_DEBUG ("Merged update for " << advEntry.GetDestination () << " with main routing Table");
1200  }
1201  m_advRoutingTable.DeleteRoute (advEntry.GetDestination ());
1202  }
1203  else
1204  {
1205  NS_LOG_DEBUG ("Event currently running. Cannot Merge Routing Tables");
1206  }
1207  }
1208  }
1209 }
1210 }
1211 }
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:284
void Start()
Start protocol operation.
static const uint32_t DSDV_PORT
UDP Port for DSDV control traffic.
static Ipv4Mask GetOnes(void)
keep track of time unit.
Definition: nstime.h:149
int64_t AssignStreams(int64_t stream)
Routing table entry.
Definition: dsdv-rtable.h:56
an Inet address class
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw socket per each IP interface, map socket -> iface address (IP + mask)
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
Hold a bool native type.
Definition: boolean.h:38
Callback template class.
Definition: callback.h:369
uint32_t GetInteger(uint32_t min, uint32_t max)
Returns a random unsigned integer from a uniform distribution over the interval [min,max] including both ends.
a simple Timer class
Definition: timer.h:45
bool EnableBuffering
Flag that is used to enable or disable buffering.
bool AnyRunningEvent(Ipv4Address address)
Definition: dsdv-rtable.cc:271
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
ErrorCallback m_ecb
Error callback for own packets.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:868
uint64_t GetUid(void) const
Definition: packet.cc:412
EventId GetEventId(Ipv4Address address)
Definition: dsdv-rtable.cc:337
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
bool EnableWST
Flag that is used to enable or disable Weighted Settling Time.
#define NS_ASSERT(condition)
Definition: assert.h:64
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:271
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
uint32_t GetSize(void) const
Definition: packet.h:620
bool IsMulticast(void) const
virtual void NotifyInterfaceDown(uint32_t interface)
virtual void DoDispose(void)
Definition: object.cc:335
void GetListOfAllRoutes(std::map< Ipv4Address, RoutingTableEntry > &allRoutes)
Definition: dsdv-rtable.cc:169
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
double m_weightedFactor
This is the wighted factor to determine the weighted settling time.
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:199
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route)
int32_t oif
Positive if output device is fixed in RouteOutput.
bool Update(RoutingTableEntry &rt)
Definition: dsdv-rtable.cc:135
a polymophic address class
Definition: address.h:86
void SendPeriodicUpdate()
Broadcasts the entire routing table for every PeriodicUpdateInterval.
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
Packet header for IPv4.
Definition: ipv4-header.h:31
bool ForceDeleteIpv4Event(Ipv4Address address)
Definition: dsdv-rtable.cc:295
double GetSeconds(void) const
Definition: nstime.h:262
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:881
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find socket with local interface address iface.
hold objects of type ns3::Time
Definition: nstime.h:700
void Schedule(void)
Definition: timer.cc:152
DSDV Queue Entry.
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
void SetFunction(FN fn)
Definition: timer.h:254
Hold an unsigned integer type.
Definition: uinteger.h:46
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:170
void Purge(std::map< Ipv4Address, RoutingTableEntry > &removedAddresses)
Delete all outdated entries if Lifetime is expired.
Definition: dsdv-rtable.cc:207
bool IsBroadcast(void) const
uint32_t m_maxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:127
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
static Ipv4Address GetBroadcast(void)
UnicastForwardCallback m_scb
Unicast callback for own packets.
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
tag a set of bytes in a packet
Definition: tag.h:36
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
Implement the Ipv4 layer.
Time GetSettlingTime(Ipv4Address dst)
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet untill we find a route.
void LookForQueuedPackets(void)
Look for any queued packets to send them out.
Time m_routeAggregationTime
Parameter that holds the route aggregation time interval.
static InetSocketAddress ConvertFrom(const Address &address)
bool Dequeue(Ipv4Address dst, QueueEntry &entry)
Return first found (the earliest) entry for given destination.
PacketQueue m_queue
A "drop front on full" queue used by the routing layer to buffer packets to which it does not have a ...
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: dsdv-rtable.cc:147
Time m_maxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
bool AddRoute(RoutingTableEntry &r)
Definition: dsdv-rtable.cc:127
void RecvDsdv(Ptr< Socket > socket)
Receive and process dsdv control packet.
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
Ipv4Address m_mainAddress
Nodes IP address.
static Time Now(void)
Definition: simulator.cc:179
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Definition: ipv4-route.cc:77
static Ipv4Address GetLoopback(void)
void SendTriggeredUpdate()
Sends trigger update from a node.
uint32_t m_maxQueuedPacketsPerDst
The maximum number of packets that we allow per destination to buffer.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void GetListOfDestinationWithNextHop(Ipv4Address nxtHp, std::map< Ipv4Address, RoutingTableEntry > &dstList)
Definition: dsdv-rtable.cc:182
bool DeleteIpv4Event(Ipv4Address address)
Definition: dsdv-rtable.cc:310
Ipv4Address GetDestination(void) const
Definition: ipv4-route.cc:42
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
read and write tag data
Definition: tag-buffer.h:51
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
bool DeleteRoute(Ipv4Address dst)
Definition: dsdv-rtable.cc:110
a class to store IPv4 address information on an interface
an identifier for simulation events.
Definition: event-id.h:46
Ptr< NetDevice > m_lo
Loopback device used to defer route requests until a route is found.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:874
A network Node.
Definition: node.h:56
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:258
Tag used by DSDV implementation.
DSDV Update Packet Format.
Definition: dsdv-packet.h:58
Abstract base class for IPv4 routing protocols.
void Clear()
Delete all entries from routing table.
Definition: dsdv-rtable.h:273
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
Ptr< Ipv4 > m_ipv4
IP protocol.
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
RoutingTable m_advRoutingTable
Advertised Routing table for the node.
#define NS_LOG_ERROR(msg)
Definition: log.h:237
virtual void NotifyInterfaceUp(uint32_t interface)
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:264
void Print(std::ostream &os) const
bool AddIpv4Event(Ipv4Address address, EventId id)
Definition: dsdv-rtable.cc:263
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: dsdv-rtable.cc:251
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Definition: dsdv-rtable.cc:71
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
Timer m_periodicUpdateTimer
Timer to trigger periodic updates from a node.
uint32_t GetSize()
Number of entries.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual int Close(void)=0
Close a socket.
RoutingTable m_routingTable
Main Routing table for the node.
void Drop(Ptr< const Packet >, const Ipv4Header &, Socket::SocketErrno)
Notify that packet is dropped for some reason.
Time GetDelayLeft(void) const
Definition: timer.cc:81
Hold an floating point type.
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
static Time GetMaximumSimulationTime(void)
Definition: simulator.cc:292
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
Definition: nstime.h:615
std::ostream * GetStream(void)
void AddHeader(const Header &header)
Definition: packet.cc:270
bool Find(Ipv4Address dst)
Finds whether a packet with destination dst exists in the queue.
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
bool Enqueue(QueueEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue...