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").SetParent<Tag> ().SetGroupName ("Dsdv");
70  return tid;
71  }
72 
73  TypeId
75  {
76  return GetTypeId ();
77  }
78 
79  uint32_t
81  {
82  return sizeof(int32_t);
83  }
84 
85  void
86  Serialize (TagBuffer i) const
87  {
88  i.WriteU32 (oif);
89  }
90 
91  void
93  {
94  oif = i.ReadU32 ();
95  }
96 
97  void
98  Print (std::ostream &os) const
99  {
100  os << "DeferredRouteOutputTag: output interface = " << oif;
101  }
102 };
103 
104 TypeId
106 {
107  static TypeId tid = TypeId ("ns3::dsdv::RoutingProtocol")
109  .SetGroupName ("Dsdv")
110  .AddConstructor<RoutingProtocol> ()
111  .AddAttribute ("PeriodicUpdateInterval","Periodic interval between exchange of full routing tables among nodes. ",
112  TimeValue (Seconds (15)),
114  MakeTimeChecker ())
115  .AddAttribute ("SettlingTime", "Minimum time an update is to be stored in adv table before sending out"
116  "in case of change in metric (in seconds)",
117  TimeValue (Seconds (5)),
119  MakeTimeChecker ())
120  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
121  UintegerValue (500 /*assuming maximum nodes in simulation is 100*/),
123  MakeUintegerChecker<uint32_t> ())
124  .AddAttribute ("MaxQueuedPacketsPerDst", "Maximum number of packets that we allow per destination to buffer.",
125  UintegerValue (5),
127  MakeUintegerChecker<uint32_t> ())
128  .AddAttribute ("MaxQueueTime","Maximum time packets can be queued (in seconds)",
129  TimeValue (Seconds (30)),
131  MakeTimeChecker ())
132  .AddAttribute ("EnableBuffering","Enables buffering of data packets if no route to destination is available",
133  BooleanValue (true),
137  .AddAttribute ("EnableWST","Enables Weighted Settling Time for the updates before advertising",
138  BooleanValue (true),
142  .AddAttribute ("Holdtimes","Times the forwarding Interval to purge the route.",
143  UintegerValue (3),
145  MakeUintegerChecker<uint32_t> ())
146  .AddAttribute ("WeightedFactor","WeightedFactor for the settling time if Weighted Settling Time is enabled",
147  DoubleValue (0.875),
149  MakeDoubleChecker<double> ())
150  .AddAttribute ("EnableRouteAggregation","Enables Weighted Settling Time for the updates before advertising",
151  BooleanValue (false),
155  .AddAttribute ("RouteAggregationTime","Time to aggregate updates before sending them out (in seconds)",
156  TimeValue (Seconds (1)),
158  MakeTimeChecker ());
159  return tid;
160 }
161 
162 void
164 {
165  EnableBuffering = f;
166 }
167 bool
169 {
170  return EnableBuffering;
171 }
172 void
174 {
175  EnableWST = f;
176 }
177 bool
179 {
180  return EnableWST;
181 }
182 void
184 {
186 }
187 bool
189 {
190  return EnableRouteAggregation;
191 }
192 
193 int64_t
195 {
196  NS_LOG_FUNCTION (this << stream);
198  return 1;
199 }
200 
202  : m_routingTable (),
203  m_advRoutingTable (),
204  m_queue (),
205  m_periodicUpdateTimer (Timer::CANCEL_ON_DESTROY)
206 {
207  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
208 }
209 
211 {
212 }
213 
214 void
216 {
217  m_ipv4 = 0;
218  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter = m_socketAddresses.begin (); iter
219  != m_socketAddresses.end (); iter++)
220  {
221  iter->first->Close ();
222  }
223  m_socketAddresses.clear ();
225 }
226 
227 void
229 {
230  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now ().GetSeconds () << "s ";
231  m_routingTable.Print (stream);
232 }
233 
234 void
236 {
241  m_advRoutingTable.Setholddowntime (Time (Holdtimes * m_periodicUpdateInterval));
246 }
247 
250  const Ipv4Header &header,
251  Ptr<NetDevice> oif,
252  Socket::SocketErrno &sockerr)
253 {
254  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
255 
256  if (!p)
257  {
258  return LoopbackRoute (header,oif);
259  }
260  if (m_socketAddresses.empty ())
261  {
262  sockerr = Socket::ERROR_NOROUTETOHOST;
263  NS_LOG_LOGIC ("No dsdv interfaces");
264  Ptr<Ipv4Route> route;
265  return route;
266  }
267  std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
268  sockerr = Socket::ERROR_NOTERROR;
269  Ptr<Ipv4Route> route;
270  Ipv4Address dst = header.GetDestination ();
271  NS_LOG_DEBUG ("Packet Size: " << p->GetSize ()
272  << ", Packet id: " << p->GetUid () << ", Destination address in Packet: " << dst);
274  m_routingTable.Purge (removedAddresses);
275  for (std::map<Ipv4Address, RoutingTableEntry>::iterator rmItr = removedAddresses.begin ();
276  rmItr != removedAddresses.end (); ++rmItr)
277  {
278  rmItr->second.SetEntriesChanged (true);
279  rmItr->second.SetSeqNo (rmItr->second.GetSeqNo () + 1);
280  m_advRoutingTable.AddRoute (rmItr->second);
281  }
282  if (!removedAddresses.empty ())
283  {
285  }
286  if (m_routingTable.LookupRoute (dst,rt))
287  {
288  if (EnableBuffering)
289  {
291  }
292  if (rt.GetHop () == 1)
293  {
294  route = rt.GetRoute ();
295  NS_ASSERT (route != 0);
296  NS_LOG_DEBUG ("A route exists from " << route->GetSource ()
297  << " to neighboring destination "
298  << route->GetDestination ());
299  if (oif != 0 && route->GetOutputDevice () != oif)
300  {
301  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
302  sockerr = Socket::ERROR_NOROUTETOHOST;
303  return Ptr<Ipv4Route> ();
304  }
305  return route;
306  }
307  else
308  {
309  RoutingTableEntry newrt;
310  if (m_routingTable.LookupRoute (rt.GetNextHop (),newrt))
311  {
312  route = newrt.GetRoute ();
313  NS_ASSERT (route != 0);
314  NS_LOG_DEBUG ("A route exists from " << route->GetSource ()
315  << " to destination " << dst << " via "
316  << rt.GetNextHop ());
317  if (oif != 0 && route->GetOutputDevice () != oif)
318  {
319  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
320  sockerr = Socket::ERROR_NOROUTETOHOST;
321  return Ptr<Ipv4Route> ();
322  }
323  return route;
324  }
325  }
326  }
327 
328  if (EnableBuffering)
329  {
330  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
331  DeferredRouteOutputTag tag (iif);
332  if (!p->PeekPacketTag (tag))
333  {
334  p->AddPacketTag (tag);
335  }
336  }
337  return LoopbackRoute (header,oif);
338 }
339 
340 void
342  const Ipv4Header & header,
343  UnicastForwardCallback ucb,
344  ErrorCallback ecb)
345 {
346  NS_LOG_FUNCTION (this << p << header);
347  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
348  QueueEntry newEntry (p,header,ucb,ecb);
349  bool result = m_queue.Enqueue (newEntry);
350  if (result)
351  {
352  NS_LOG_DEBUG ("Added packet " << p->GetUid () << " to queue.");
353  }
354 }
355 
356 bool
358  const Ipv4Header &header,
360  UnicastForwardCallback ucb,
363  ErrorCallback ecb)
364 {
365  NS_LOG_FUNCTION (m_mainAddress << " received packet " << p->GetUid ()
366  << " from " << header.GetSource ()
367  << " on interface " << idev->GetAddress ()
368  << " to destination " << header.GetDestination ());
369  if (m_socketAddresses.empty ())
370  {
371  NS_LOG_DEBUG ("No dsdv interfaces");
372  return false;
373  }
374  NS_ASSERT (m_ipv4 != 0);
375  // Check if input device supports IP
376  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
377  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
378 
379  Ipv4Address dst = header.GetDestination ();
380  Ipv4Address origin = header.GetSource ();
381 
382  // DSDV is not a multicast routing protocol
383  if (dst.IsMulticast ())
384  {
385  return false;
386  }
387 
388  // Deferred route request
389  if (EnableBuffering == true && idev == m_lo)
390  {
392  if (p->PeekPacketTag (tag))
393  {
394  DeferredRouteOutput (p,header,ucb,ecb);
395  return true;
396  }
397  }
398  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
399  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
400  {
401  Ipv4InterfaceAddress iface = j->second;
402  if (origin == iface.GetLocal ())
403  {
404  return true;
405  }
406  }
407  // LOCAL DELIVARY TO DSDV INTERFACES
408  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
409  != m_socketAddresses.end (); ++j)
410  {
411  Ipv4InterfaceAddress iface = j->second;
412  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
413  {
414  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
415  {
416  Ptr<Packet> packet = p->Copy ();
417  if (lcb.IsNull () == false)
418  {
419  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
420  lcb (p, header, iif);
421  // Fall through to additional processing
422  }
423  else
424  {
425  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
426  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
427  }
428  if (header.GetTtl () > 1)
429  {
430  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
431  RoutingTableEntry toBroadcast;
432  if (m_routingTable.LookupRoute (dst,toBroadcast,true))
433  {
434  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
435  ucb (route,packet,header);
436  }
437  else
438  {
439  NS_LOG_DEBUG ("No route to forward. Drop packet " << p->GetUid ());
440  }
441  }
442  return true;
443  }
444  }
445  }
446 
447  if (m_ipv4->IsDestinationAddress (dst, iif))
448  {
449  if (lcb.IsNull () == false)
450  {
451  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
452  lcb (p, header, iif);
453  }
454  else
455  {
456  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
457  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
458  }
459  return true;
460  }
461  RoutingTableEntry toDst;
462  if (m_routingTable.LookupRoute (dst,toDst))
463  {
465  if (m_routingTable.LookupRoute (toDst.GetNextHop (),ne))
466  {
467  Ptr<Ipv4Route> route = ne.GetRoute ();
468  NS_LOG_LOGIC (m_mainAddress << " is forwarding packet " << p->GetUid ()
469  << " to " << dst
470  << " from " << header.GetSource ()
471  << " via nexthop neighbor " << toDst.GetNextHop ());
472  ucb (route,p,header);
473  return true;
474  }
475  }
476  NS_LOG_LOGIC ("Drop packet " << p->GetUid ()
477  << " as there is no route to forward it.");
478  return false;
479 }
480 
483 {
484  NS_ASSERT (m_lo != 0);
485  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
486  rt->SetDestination (hdr.GetDestination ());
487  // rt->SetSource (hdr.GetSource ());
488  //
489  // Source address selection here is tricky. The loopback route is
490  // returned when DSDV does not have a route; this causes the packet
491  // to be looped back and handled (cached) in RouteInput() method
492  // while a route is found. However, connection-oriented protocols
493  // like TCP need to create an endpoint four-tuple (src, src port,
494  // dst, dst port) and create a pseudo-header for checksumming. So,
495  // DSDV needs to guess correctly what the eventual source address
496  // will be.
497  //
498  // For single interface, single address nodes, this is not a problem.
499  // When there are possibly multiple outgoing interfaces, the policy
500  // implemented here is to pick the first available DSDV interface.
501  // If RouteOutput() caller specified an outgoing interface, that
502  // further constrains the selection of source address
503  //
504  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
505  if (oif)
506  {
507  // Iterate to find an address on the oif device
508  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
509  {
510  Ipv4Address addr = j->second.GetLocal ();
511  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
512  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
513  {
514  rt->SetSource (addr);
515  break;
516  }
517  }
518  }
519  else
520  {
521  rt->SetSource (j->second.GetLocal ());
522  }
523  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid DSDV source address not found");
524  rt->SetGateway (Ipv4Address ("127.0.0.1"));
525  rt->SetOutputDevice (m_lo);
526  return rt;
527 }
528 
529 void
531 {
532  Address sourceAddress;
533  Ptr<Packet> advpacket = Create<Packet> ();
534  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
535  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
536  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
537  Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
538  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
539  uint32_t packetSize = packet->GetSize ();
540  NS_LOG_FUNCTION (m_mainAddress << " received dsdv packet of size: " << packetSize
541  << " and packet id: " << packet->GetUid ());
542  uint32_t count = 0;
543  for (; packetSize > 0; packetSize = packetSize - 12)
544  {
545  count = 0;
546  DsdvHeader dsdvHeader, tempDsdvHeader;
547  packet->RemoveHeader (dsdvHeader);
548  NS_LOG_DEBUG ("Processing new update for " << dsdvHeader.GetDst ());
549  /*Verifying if the packets sent by me were returned back to me. If yes, discarding them!*/
550  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
551  != m_socketAddresses.end (); ++j)
552  {
553  Ipv4InterfaceAddress interface = j->second;
554  if (dsdvHeader.GetDst () == interface.GetLocal ())
555  {
556  if (dsdvHeader.GetDstSeqno () % 2 == 1)
557  {
558  NS_LOG_DEBUG ("Sent Dsdv update back to the same Destination, "
559  "with infinite metric. Time left to send fwd update: "
561  count++;
562  }
563  else
564  {
565  NS_LOG_DEBUG ("Received update for my address. Discarding this.");
566  count++;
567  }
568  }
569  }
570  if (count > 0)
571  {
572  continue;
573  }
574  NS_LOG_DEBUG ("Received a DSDV packet from "
575  << sender << " to " << receiver << ". Details are: Destination: " << dsdvHeader.GetDst () << ", Seq No: "
576  << dsdvHeader.GetDstSeqno () << ", HopCount: " << dsdvHeader.GetHopCount ());
577  RoutingTableEntry fwdTableEntry, advTableEntry;
578  EventId event;
579  bool permanentTableVerifier = m_routingTable.LookupRoute (dsdvHeader.GetDst (),fwdTableEntry);
580  if (permanentTableVerifier == false)
581  {
582  if (dsdvHeader.GetDstSeqno () % 2 != 1)
583  {
584  NS_LOG_DEBUG ("Received New Route!");
585  RoutingTableEntry newEntry (
586  /*device=*/ dev, /*dst=*/
587  dsdvHeader.GetDst (), /*seqno=*/
588  dsdvHeader.GetDstSeqno (),
589  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
590  /*hops=*/ dsdvHeader.GetHopCount (), /*next hop=*/
591  sender, /*lifetime=*/
592  Simulator::Now (), /*settlingTime*/
593  m_settlingTime, /*entries changed*/
594  true);
595  newEntry.SetFlag (VALID);
596  m_routingTable.AddRoute (newEntry);
597  NS_LOG_DEBUG ("New Route added to both tables");
598  m_advRoutingTable.AddRoute (newEntry);
599  }
600  else
601  {
602  // received update not present in main routing table and also with infinite metric
603  NS_LOG_DEBUG ("Discarding this update as this route is not present in "
604  "main routing table and received with infinite metric");
605  }
606  }
607  else
608  {
609  if (!m_advRoutingTable.LookupRoute (dsdvHeader.GetDst (),advTableEntry))
610  {
612  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
614  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
615  {
616  NS_LOG_DEBUG ("ADV table routes are:" << i->second.GetDestination ());
617  }
618  // present in fwd table and not in advtable
619  m_advRoutingTable.AddRoute (fwdTableEntry);
620  m_advRoutingTable.LookupRoute (dsdvHeader.GetDst (),advTableEntry);
621  }
622  if (dsdvHeader.GetDstSeqno () % 2 != 1)
623  {
624  if (dsdvHeader.GetDstSeqno () > advTableEntry.GetSeqNo ())
625  {
626  // Received update with better seq number. Clear any old events that are running
627  if (m_advRoutingTable.ForceDeleteIpv4Event (dsdvHeader.GetDst ()))
628  {
629  NS_LOG_DEBUG ("Canceling the timer to update route with better seq number");
630  }
631  // if its a changed metric *nomatter* where the update came from, wait for WST
632  if (dsdvHeader.GetHopCount () != advTableEntry.GetHop ())
633  {
634  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
635  advTableEntry.SetLifeTime (Simulator::Now ());
636  advTableEntry.SetFlag (VALID);
637  advTableEntry.SetEntriesChanged (true);
638  advTableEntry.SetNextHop (sender);
639  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
640  NS_LOG_DEBUG ("Received update with better sequence number and changed metric.Waiting for WST");
641  Time tempSettlingtime = GetSettlingTime (dsdvHeader.GetDst ());
642  advTableEntry.SetSettlingTime (tempSettlingtime);
643  NS_LOG_DEBUG ("Added Settling Time:" << tempSettlingtime.GetSeconds ()
644  << "s as there is no event running for this route");
645  event = Simulator::Schedule (tempSettlingtime,&RoutingProtocol::SendTriggeredUpdate,this);
646  m_advRoutingTable.AddIpv4Event (dsdvHeader.GetDst (),event);
647  NS_LOG_DEBUG ("EventCreated EventUID: " << event.GetUid ());
648  // if received changed metric, use it but adv it only after wst
649  m_routingTable.Update (advTableEntry);
650  m_advRoutingTable.Update (advTableEntry);
651  }
652  else
653  {
654  // Received update with better seq number and same metric.
655  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
656  advTableEntry.SetLifeTime (Simulator::Now ());
657  advTableEntry.SetFlag (VALID);
658  advTableEntry.SetEntriesChanged (true);
659  advTableEntry.SetNextHop (sender);
660  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
661  m_advRoutingTable.Update (advTableEntry);
662  NS_LOG_DEBUG ("Route with better sequence number and same metric received. Advertised without WST");
663  }
664  }
665  else if (dsdvHeader.GetDstSeqno () == advTableEntry.GetSeqNo ())
666  {
667  if (dsdvHeader.GetHopCount () < advTableEntry.GetHop ())
668  {
669  /*Received update with same seq number and better hop count.
670  * As the metric is changed, we will have to wait for WST before sending out this update.
671  */
672  NS_LOG_DEBUG ("Canceling any existing timer to update route with same sequence number "
673  "and better hop count");
675  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
676  advTableEntry.SetLifeTime (Simulator::Now ());
677  advTableEntry.SetFlag (VALID);
678  advTableEntry.SetEntriesChanged (true);
679  advTableEntry.SetNextHop (sender);
680  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
681  Time tempSettlingtime = GetSettlingTime (dsdvHeader.GetDst ());
682  advTableEntry.SetSettlingTime (tempSettlingtime);
683  NS_LOG_DEBUG ("Added Settling Time," << tempSettlingtime.GetSeconds ()
684  << " as there is no current event running for this route");
685  event = Simulator::Schedule (tempSettlingtime,&RoutingProtocol::SendTriggeredUpdate,this);
686  m_advRoutingTable.AddIpv4Event (dsdvHeader.GetDst (),event);
687  NS_LOG_DEBUG ("EventCreated EventUID: " << event.GetUid ());
688  // if received changed metric, use it but adv it only after wst
689  m_routingTable.Update (advTableEntry);
690  m_advRoutingTable.Update (advTableEntry);
691  }
692  else
693  {
694  /*Received update with same seq number but with same or greater hop count.
695  * Discard that update.
696  */
697  if (!m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
698  {
699  /*update the timer only if nexthop address matches thus discarding
700  * updates to that destination from other nodes.
701  */
702  if (advTableEntry.GetNextHop () == sender)
703  {
704  advTableEntry.SetLifeTime (Simulator::Now ());
705  m_routingTable.Update (advTableEntry);
706  }
708  dsdvHeader.GetDst ());
709  }
710  NS_LOG_DEBUG ("Received update with same seq number and "
711  "same/worst metric for, " << dsdvHeader.GetDst () << ". Discarding the update.");
712  }
713  }
714  else
715  {
716  // Received update with an old sequence number. Discard the update
717  if (!m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
718  {
719  m_advRoutingTable.DeleteRoute (dsdvHeader.GetDst ());
720  }
721  NS_LOG_DEBUG (dsdvHeader.GetDst () << " : Received update with old seq number. Discarding the update.");
722  }
723  }
724  else
725  {
726  NS_LOG_DEBUG ("Route with infinite metric received for "
727  << dsdvHeader.GetDst () << " from " << sender);
728  // Delete route only if update was received from my nexthop neighbor
729  if (sender == advTableEntry.GetNextHop ())
730  {
731  NS_LOG_DEBUG ("Triggering an update for this unreachable route:");
732  std::map<Ipv4Address, RoutingTableEntry> dstsWithNextHopSrc;
733  m_routingTable.GetListOfDestinationWithNextHop (dsdvHeader.GetDst (),dstsWithNextHopSrc);
734  m_routingTable.DeleteRoute (dsdvHeader.GetDst ());
735  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
736  advTableEntry.SetEntriesChanged (true);
737  m_advRoutingTable.Update (advTableEntry);
738  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i = dstsWithNextHopSrc.begin (); i
739  != dstsWithNextHopSrc.end (); ++i)
740  {
741  i->second.SetSeqNo (i->second.GetSeqNo () + 1);
742  i->second.SetEntriesChanged (true);
743  m_advRoutingTable.AddRoute (i->second);
744  m_routingTable.DeleteRoute (i->second.GetDestination ());
745  }
746  }
747  else
748  {
749  if (!m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
750  {
751  m_advRoutingTable.DeleteRoute (dsdvHeader.GetDst ());
752  }
753  NS_LOG_DEBUG (dsdvHeader.GetDst () <<
754  " : Discard this link break update as it was received from a different neighbor "
755  "and I can reach the destination");
756  }
757  }
758  }
759  }
760  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
762  if (EnableRouteAggregation && allRoutes.size () > 0)
763  {
765  }
766  else
767  {
769  }
770 }
771 
772 
773 void
775 {
776  NS_LOG_FUNCTION (m_mainAddress << " is sending a triggered update");
777  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
779  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
780  != m_socketAddresses.end (); ++j)
781  {
782  DsdvHeader dsdvHeader;
783  Ptr<Socket> socket = j->first;
784  Ipv4InterfaceAddress iface = j->second;
785  Ptr<Packet> packet = Create<Packet> ();
786  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
787  {
788  NS_LOG_LOGIC ("Destination: " << i->second.GetDestination ()
789  << " SeqNo:" << i->second.GetSeqNo () << " HopCount:"
790  << i->second.GetHop () + 1);
791  RoutingTableEntry temp = i->second;
792  if ((i->second.GetEntriesChanged () == true) && (!m_advRoutingTable.AnyRunningEvent (temp.GetDestination ())))
793  {
794  dsdvHeader.SetDst (i->second.GetDestination ());
795  dsdvHeader.SetDstSeqno (i->second.GetSeqNo ());
796  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
797  temp.SetFlag (VALID);
798  temp.SetEntriesChanged (false);
799  m_advRoutingTable.DeleteIpv4Event (temp.GetDestination ());
800  if (!(temp.GetSeqNo () % 2))
801  {
802  m_routingTable.Update (temp);
803  }
804  packet->AddHeader (dsdvHeader);
805  m_advRoutingTable.DeleteRoute (temp.GetDestination ());
806  NS_LOG_DEBUG ("Deleted this route from the advertised table");
807  }
808  else
809  {
810  EventId event = m_advRoutingTable.GetEventId (temp.GetDestination ());
811  NS_ASSERT (event.GetUid () != 0);
812  NS_LOG_DEBUG ("EventID " << event.GetUid () << " associated with "
813  << temp.GetDestination () << " has not expired, waiting in adv table");
814  }
815  }
816  if (packet->GetSize () >= 12)
817  {
818  RoutingTableEntry temp2;
819  m_routingTable.LookupRoute (m_ipv4->GetAddress (1, 0).GetBroadcast (), temp2);
820  dsdvHeader.SetDst (m_ipv4->GetAddress (1, 0).GetLocal ());
821  dsdvHeader.SetDstSeqno (temp2.GetSeqNo ());
822  dsdvHeader.SetHopCount (temp2.GetHop () + 1);
823  NS_LOG_DEBUG ("Adding my update as well to the packet");
824  packet->AddHeader (dsdvHeader);
825  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
826  Ipv4Address destination;
827  if (iface.GetMask () == Ipv4Mask::GetOnes ())
828  {
829  destination = Ipv4Address ("255.255.255.255");
830  }
831  else
832  {
833  destination = iface.GetBroadcast ();
834  }
835  socket->SendTo (packet, 0, InetSocketAddress (destination, DSDV_PORT));
836  NS_LOG_FUNCTION ("Sent Triggered Update from "
837  << dsdvHeader.GetDst ()
838  << " with packet id : " << packet->GetUid () << " and packet Size: " << packet->GetSize ());
839  }
840  else
841  {
842  NS_LOG_FUNCTION ("Update not sent as there are no updates to be triggered");
843  }
844  }
845 }
846 
847 void
849 {
850  std::map<Ipv4Address, RoutingTableEntry> removedAddresses, allRoutes;
851  m_routingTable.Purge (removedAddresses);
854  if (allRoutes.empty ())
855  {
856  return;
857  }
858  NS_LOG_FUNCTION (m_mainAddress << " is sending out its periodic update");
859  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
860  != m_socketAddresses.end (); ++j)
861  {
862  Ptr<Socket> socket = j->first;
863  Ipv4InterfaceAddress iface = j->second;
864  Ptr<Packet> packet = Create<Packet> ();
865  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
866  {
867  DsdvHeader dsdvHeader;
868  if (i->second.GetHop () == 0)
869  {
870  RoutingTableEntry ownEntry;
871  dsdvHeader.SetDst (m_ipv4->GetAddress (1,0).GetLocal ());
872  dsdvHeader.SetDstSeqno (i->second.GetSeqNo () + 2);
873  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
874  m_routingTable.LookupRoute (m_ipv4->GetAddress (1,0).GetBroadcast (),ownEntry);
875  ownEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
876  m_routingTable.Update (ownEntry);
877  packet->AddHeader (dsdvHeader);
878  }
879  else
880  {
881  dsdvHeader.SetDst (i->second.GetDestination ());
882  dsdvHeader.SetDstSeqno ((i->second.GetSeqNo ()));
883  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
884  packet->AddHeader (dsdvHeader);
885  }
886  NS_LOG_DEBUG ("Forwarding the update for " << i->first);
887  NS_LOG_DEBUG ("Forwarding details are, Destination: " << dsdvHeader.GetDst ()
888  << ", SeqNo:" << dsdvHeader.GetDstSeqno ()
889  << ", HopCount:" << dsdvHeader.GetHopCount ()
890  << ", LifeTime: " << i->second.GetLifeTime ().GetSeconds ());
891  }
892  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator rmItr = removedAddresses.begin (); rmItr
893  != removedAddresses.end (); ++rmItr)
894  {
895  DsdvHeader removedHeader;
896  removedHeader.SetDst (rmItr->second.GetDestination ());
897  removedHeader.SetDstSeqno (rmItr->second.GetSeqNo () + 1);
898  removedHeader.SetHopCount (rmItr->second.GetHop () + 1);
899  packet->AddHeader (removedHeader);
900  NS_LOG_DEBUG ("Update for removed record is: Destination: " << removedHeader.GetDst ()
901  << " SeqNo:" << removedHeader.GetDstSeqno ()
902  << " HopCount:" << removedHeader.GetHopCount ());
903  }
904  socket->Send (packet);
905  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
906  Ipv4Address destination;
907  if (iface.GetMask () == Ipv4Mask::GetOnes ())
908  {
909  destination = Ipv4Address ("255.255.255.255");
910  }
911  else
912  {
913  destination = iface.GetBroadcast ();
914  }
915  socket->SendTo (packet, 0, InetSocketAddress (destination, DSDV_PORT));
916  NS_LOG_FUNCTION ("PeriodicUpdate Packet UID is : " << packet->GetUid ());
917  }
919 }
920 
921 void
923 {
924  NS_ASSERT (ipv4 != 0);
925  NS_ASSERT (m_ipv4 == 0);
926  m_ipv4 = ipv4;
927  // Create lo route. It is asserted that the only one interface up for now is loopback
928  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
929  m_lo = m_ipv4->GetNetDevice (0);
930  NS_ASSERT (m_lo != 0);
931  // Remember lo route
932  RoutingTableEntry rt (
933  /*device=*/ m_lo, /*dst=*/
934  Ipv4Address::GetLoopback (), /*seqno=*/
935  0,
936  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (),Ipv4Mask ("255.0.0.0")),
937  /*hops=*/ 0, /*next hop=*/
939  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
940  rt.SetFlag (INVALID);
941  rt.SetEntriesChanged (false);
944 }
945 
946 void
948 {
949  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ()
950  << " interface is up");
951  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
952  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
953  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
954  {
955  return;
956  }
957  // Create a socket to listen only on this interface
958  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
959  NS_ASSERT (socket != 0);
962  socket->BindToNetDevice (l3->GetNetDevice (i));
963  socket->SetAllowBroadcast (true);
964  socket->SetAttribute ("IpTtl",UintegerValue (1));
965  m_socketAddresses.insert (std::make_pair (socket,iface));
966  // Add local broadcast record to the routing table
967  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
968  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*seqno=*/ 0,/*iface=*/ iface,/*hops=*/ 0,
969  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
971  if (m_mainAddress == Ipv4Address ())
972  {
973  m_mainAddress = iface.GetLocal ();
974  }
976 }
977 
978 void
980 {
981  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
982  Ptr<NetDevice> dev = l3->GetNetDevice (i);
983  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i,0));
984  NS_ASSERT (socket);
985  socket->Close ();
986  m_socketAddresses.erase (socket);
987  if (m_socketAddresses.empty ())
988  {
989  NS_LOG_LOGIC ("No dsdv interfaces");
991  return;
992  }
995 }
996 
997 void
1000 {
1001  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
1002  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1003  if (!l3->IsUp (i))
1004  {
1005  return;
1006  }
1007  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
1009  if (!socket)
1010  {
1011  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
1012  {
1013  return;
1014  }
1015  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
1016  NS_ASSERT (socket != 0);
1018  // Bind to any IP address so that broadcasts can be received
1020  socket->BindToNetDevice (l3->GetNetDevice (i));
1021  socket->SetAllowBroadcast (true);
1022  m_socketAddresses.insert (std::make_pair (socket,iface));
1023  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
1024  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (),/*seqno=*/ 0, /*iface=*/ iface,/*hops=*/ 0,
1025  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
1026  m_routingTable.AddRoute (rt);
1027  }
1028 }
1029 
1030 void
1033 {
1034  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
1035  if (socket)
1036  {
1037  m_socketAddresses.erase (socket);
1038  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1039  if (l3->GetNAddresses (i))
1040  {
1041  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
1042  // Create a socket to listen only on this interface
1043  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
1044  NS_ASSERT (socket != 0);
1046  // Bind to any IP address so that broadcasts can be received
1048  socket->SetAllowBroadcast (true);
1049  m_socketAddresses.insert (std::make_pair (socket,iface));
1050  }
1051  }
1052 }
1053 
1056 {
1057  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
1058  != m_socketAddresses.end (); ++j)
1059  {
1060  Ptr<Socket> socket = j->first;
1061  Ipv4InterfaceAddress iface = j->second;
1062  if (iface == addr)
1063  {
1064  return socket;
1065  }
1066  }
1067  Ptr<Socket> socket;
1068  return socket;
1069 }
1070 
1071 void
1073  Ptr<const Packet> packet,
1074  const Ipv4Header & header)
1075 {
1076  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1077  NS_ASSERT (l3 != 0);
1078  Ptr<Packet> p = packet->Copy ();
1079  l3->Send (p,route->GetSource (),header.GetDestination (),header.GetProtocol (),route);
1080 }
1081 
1082 void
1084  const Ipv4Header & header,
1085  Socket::SocketErrno err)
1086 {
1087  NS_LOG_DEBUG (m_mainAddress << " drop packet " << packet->GetUid () << " to "
1088  << header.GetDestination () << " from queue. Error " << err);
1089 }
1090 
1091 void
1093 {
1094  NS_LOG_FUNCTION (this);
1095  Ptr<Ipv4Route> route;
1096  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1097  m_routingTable.GetListOfAllRoutes (allRoutes);
1098  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1099  {
1100  RoutingTableEntry rt;
1101  rt = i->second;
1102  if (m_queue.Find (rt.GetDestination ()))
1103  {
1104  if (rt.GetHop () == 1)
1105  {
1106  route = rt.GetRoute ();
1107  NS_LOG_LOGIC ("A route exists from " << route->GetSource ()
1108  << " to neighboring destination "
1109  << route->GetDestination ());
1110  NS_ASSERT (route != 0);
1111  }
1112  else
1113  {
1114  RoutingTableEntry newrt;
1115  m_routingTable.LookupRoute (rt.GetNextHop (),newrt);
1116  route = newrt.GetRoute ();
1117  NS_LOG_LOGIC ("A route exists from " << route->GetSource ()
1118  << " to destination " << route->GetDestination () << " via "
1119  << rt.GetNextHop ());
1120  NS_ASSERT (route != 0);
1121  }
1122  SendPacketFromQueue (rt.GetDestination (),route);
1123  }
1124  }
1125 }
1126 
1127 void
1129  Ptr<Ipv4Route> route)
1130 {
1131  NS_LOG_DEBUG (m_mainAddress << " is sending a queued packet to destination " << dst);
1132  QueueEntry queueEntry;
1133  if (m_queue.Dequeue (dst,queueEntry))
1134  {
1136  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1137  if (p->RemovePacketTag (tag))
1138  {
1139  if (tag.oif != -1 && tag.oif != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1140  {
1141  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1142  return;
1143  }
1144  }
1146  Ipv4Header header = queueEntry.GetIpv4Header ();
1147  header.SetSource (route->GetSource ());
1148  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1149  ucb (route,p,header);
1150  if (m_queue.GetSize () != 0 && m_queue.Find (dst))
1151  {
1153  &RoutingProtocol::SendPacketFromQueue,this,dst,route);
1154  }
1155  }
1156 }
1157 
1158 Time
1160 {
1161  NS_LOG_FUNCTION ("Calculating the settling time for " << address);
1162  RoutingTableEntry mainrt;
1163  Time weightedTime;
1164  m_routingTable.LookupRoute (address,mainrt);
1165  if (EnableWST)
1166  {
1167  if (mainrt.GetSettlingTime () == Seconds (0))
1168  {
1169  return Seconds (0);
1170  }
1171  else
1172  {
1173  NS_LOG_DEBUG ("Route SettlingTime: " << mainrt.GetSettlingTime ().GetSeconds ()
1174  << " and LifeTime:" << mainrt.GetLifeTime ().GetSeconds ());
1175  weightedTime = Time (m_weightedFactor * mainrt.GetSettlingTime ().GetSeconds () + (1.0 - m_weightedFactor)
1176  * mainrt.GetLifeTime ().GetSeconds ());
1177  NS_LOG_DEBUG ("Calculated weightedTime:" << weightedTime.GetSeconds ());
1178  return weightedTime;
1179  }
1180  }
1181  return mainrt.GetSettlingTime ();
1182 }
1183 
1184 void
1186 {
1187  NS_LOG_FUNCTION ("Merging advertised table changes with main table before sending out periodic update");
1188  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1190  if (allRoutes.size () > 0)
1191  {
1192  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1193  {
1194  RoutingTableEntry advEntry = i->second;
1195  if ((advEntry.GetEntriesChanged () == true) && (!m_advRoutingTable.AnyRunningEvent (advEntry.GetDestination ())))
1196  {
1197  if (!(advEntry.GetSeqNo () % 2))
1198  {
1199  advEntry.SetFlag (VALID);
1200  advEntry.SetEntriesChanged (false);
1201  m_routingTable.Update (advEntry);
1202  NS_LOG_DEBUG ("Merged update for " << advEntry.GetDestination () << " with main routing Table");
1203  }
1205  }
1206  else
1207  {
1208  NS_LOG_DEBUG ("Event currently running. Cannot Merge Routing Tables");
1209  }
1210  }
1211  }
1212 }
1213 }
1214 }
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:984
Ipv4Address GetNextHop() const
Definition: dsdv-rtable.h:86
bool EnableRouteAggregation
This is a flag to enable route aggregation.
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: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:836
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:380
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:1078
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:874
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:766
virtual void DoDispose()
Destructor implementation.
bool IsMulticast(void) const
virtual void NotifyInterfaceDown(uint32_t interface)
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
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.
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:215
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
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:334
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:858
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find socket with local interface address iface.
AttributeValue implementation for Time.
Definition: nstime.h:928
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:305
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:1296
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:980
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:929
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:843
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:866
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:882
#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:190
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:57
Time m_settlingTime
SettlingTime specifies the time for which a node waits before propagating an update.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638
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:253
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...