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