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 ()
235  << ", Time: " << Now().As (Time::S)
236  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (Time::S)
237  << ", DSDV Routing table" << std::endl;
238 
239  m_routingTable.Print (stream);
240  *stream->GetStream () << std::endl;
241 }
242 
243 void
245 {
250  m_advRoutingTable.Setholddowntime (Time (Holdtimes * m_periodicUpdateInterval));
255 }
256 
259  const Ipv4Header &header,
260  Ptr<NetDevice> oif,
261  Socket::SocketErrno &sockerr)
262 {
263  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
264 
265  if (!p)
266  {
267  return LoopbackRoute (header,oif);
268  }
269  if (m_socketAddresses.empty ())
270  {
271  sockerr = Socket::ERROR_NOROUTETOHOST;
272  NS_LOG_LOGIC ("No dsdv interfaces");
273  Ptr<Ipv4Route> route;
274  return route;
275  }
276  std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
277  sockerr = Socket::ERROR_NOTERROR;
278  Ptr<Ipv4Route> route;
279  Ipv4Address dst = header.GetDestination ();
280  NS_LOG_DEBUG ("Packet Size: " << p->GetSize ()
281  << ", Packet id: " << p->GetUid () << ", Destination address in Packet: " << dst);
283  m_routingTable.Purge (removedAddresses);
284  for (std::map<Ipv4Address, RoutingTableEntry>::iterator rmItr = removedAddresses.begin ();
285  rmItr != removedAddresses.end (); ++rmItr)
286  {
287  rmItr->second.SetEntriesChanged (true);
288  rmItr->second.SetSeqNo (rmItr->second.GetSeqNo () + 1);
289  m_advRoutingTable.AddRoute (rmItr->second);
290  }
291  if (!removedAddresses.empty ())
292  {
294  }
295  if (m_routingTable.LookupRoute (dst,rt))
296  {
297  if (EnableBuffering)
298  {
300  }
301  if (rt.GetHop () == 1)
302  {
303  route = rt.GetRoute ();
304  NS_ASSERT (route != 0);
305  NS_LOG_DEBUG ("A route exists from " << route->GetSource ()
306  << " to neighboring destination "
307  << route->GetDestination ());
308  if (oif != 0 && route->GetOutputDevice () != oif)
309  {
310  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
311  sockerr = Socket::ERROR_NOROUTETOHOST;
312  return Ptr<Ipv4Route> ();
313  }
314  return route;
315  }
316  else
317  {
318  RoutingTableEntry newrt;
319  if (m_routingTable.LookupRoute (rt.GetNextHop (),newrt))
320  {
321  route = newrt.GetRoute ();
322  NS_ASSERT (route != 0);
323  NS_LOG_DEBUG ("A route exists from " << route->GetSource ()
324  << " to destination " << dst << " via "
325  << rt.GetNextHop ());
326  if (oif != 0 && route->GetOutputDevice () != oif)
327  {
328  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
329  sockerr = Socket::ERROR_NOROUTETOHOST;
330  return Ptr<Ipv4Route> ();
331  }
332  return route;
333  }
334  }
335  }
336 
337  if (EnableBuffering)
338  {
339  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
340  DeferredRouteOutputTag tag (iif);
341  if (!p->PeekPacketTag (tag))
342  {
343  p->AddPacketTag (tag);
344  }
345  }
346  return LoopbackRoute (header,oif);
347 }
348 
349 void
351  const Ipv4Header & header,
352  UnicastForwardCallback ucb,
353  ErrorCallback ecb)
354 {
355  NS_LOG_FUNCTION (this << p << header);
356  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
357  QueueEntry newEntry (p,header,ucb,ecb);
358  bool result = m_queue.Enqueue (newEntry);
359  if (result)
360  {
361  NS_LOG_DEBUG ("Added packet " << p->GetUid () << " to queue.");
362  }
363 }
364 
365 bool
367  const Ipv4Header &header,
369  UnicastForwardCallback ucb,
372  ErrorCallback ecb)
373 {
374  NS_LOG_FUNCTION (m_mainAddress << " received packet " << p->GetUid ()
375  << " from " << header.GetSource ()
376  << " on interface " << idev->GetAddress ()
377  << " to destination " << header.GetDestination ());
378  if (m_socketAddresses.empty ())
379  {
380  NS_LOG_DEBUG ("No dsdv interfaces");
381  return false;
382  }
383  NS_ASSERT (m_ipv4 != 0);
384  // Check if input device supports IP
385  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
386  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
387 
388  Ipv4Address dst = header.GetDestination ();
389  Ipv4Address origin = header.GetSource ();
390 
391  // DSDV is not a multicast routing protocol
392  if (dst.IsMulticast ())
393  {
394  return false;
395  }
396 
397  // Deferred route request
398  if (EnableBuffering == true && idev == m_lo)
399  {
401  if (p->PeekPacketTag (tag))
402  {
403  DeferredRouteOutput (p,header,ucb,ecb);
404  return true;
405  }
406  }
407  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
408  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
409  {
410  Ipv4InterfaceAddress iface = j->second;
411  if (origin == iface.GetLocal ())
412  {
413  return true;
414  }
415  }
416  // LOCAL DELIVARY TO DSDV INTERFACES
417  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
418  != m_socketAddresses.end (); ++j)
419  {
420  Ipv4InterfaceAddress iface = j->second;
421  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
422  {
423  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
424  {
425  Ptr<Packet> packet = p->Copy ();
426  if (lcb.IsNull () == false)
427  {
428  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
429  lcb (p, header, iif);
430  // Fall through to additional processing
431  }
432  else
433  {
434  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
435  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
436  }
437  if (header.GetTtl () > 1)
438  {
439  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
440  RoutingTableEntry toBroadcast;
441  if (m_routingTable.LookupRoute (dst,toBroadcast,true))
442  {
443  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
444  ucb (route,packet,header);
445  }
446  else
447  {
448  NS_LOG_DEBUG ("No route to forward. Drop packet " << p->GetUid ());
449  }
450  }
451  return true;
452  }
453  }
454  }
455 
456  if (m_ipv4->IsDestinationAddress (dst, iif))
457  {
458  if (lcb.IsNull () == false)
459  {
460  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
461  lcb (p, header, iif);
462  }
463  else
464  {
465  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
466  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
467  }
468  return true;
469  }
470 
471  // Check if input device supports IP forwarding
472  if (m_ipv4->IsForwarding (iif) == false)
473  {
474  NS_LOG_LOGIC ("Forwarding disabled for this interface");
475  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
476  return true;
477  }
478 
479  RoutingTableEntry toDst;
480  if (m_routingTable.LookupRoute (dst,toDst))
481  {
483  if (m_routingTable.LookupRoute (toDst.GetNextHop (),ne))
484  {
485  Ptr<Ipv4Route> route = ne.GetRoute ();
486  NS_LOG_LOGIC (m_mainAddress << " is forwarding packet " << p->GetUid ()
487  << " to " << dst
488  << " from " << header.GetSource ()
489  << " via nexthop neighbor " << toDst.GetNextHop ());
490  ucb (route,p,header);
491  return true;
492  }
493  }
494  NS_LOG_LOGIC ("Drop packet " << p->GetUid ()
495  << " as there is no route to forward it.");
496  return false;
497 }
498 
501 {
502  NS_ASSERT (m_lo != 0);
503  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
504  rt->SetDestination (hdr.GetDestination ());
505  // rt->SetSource (hdr.GetSource ());
506  //
507  // Source address selection here is tricky. The loopback route is
508  // returned when DSDV does not have a route; this causes the packet
509  // to be looped back and handled (cached) in RouteInput() method
510  // while a route is found. However, connection-oriented protocols
511  // like TCP need to create an endpoint four-tuple (src, src port,
512  // dst, dst port) and create a pseudo-header for checksumming. So,
513  // DSDV needs to guess correctly what the eventual source address
514  // will be.
515  //
516  // For single interface, single address nodes, this is not a problem.
517  // When there are possibly multiple outgoing interfaces, the policy
518  // implemented here is to pick the first available DSDV interface.
519  // If RouteOutput() caller specified an outgoing interface, that
520  // further constrains the selection of source address
521  //
522  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
523  if (oif)
524  {
525  // Iterate to find an address on the oif device
526  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
527  {
528  Ipv4Address addr = j->second.GetLocal ();
529  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
530  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
531  {
532  rt->SetSource (addr);
533  break;
534  }
535  }
536  }
537  else
538  {
539  rt->SetSource (j->second.GetLocal ());
540  }
541  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid DSDV source address not found");
542  rt->SetGateway (Ipv4Address ("127.0.0.1"));
543  rt->SetOutputDevice (m_lo);
544  return rt;
545 }
546 
547 void
549 {
550  Address sourceAddress;
551  Ptr<Packet> advpacket = Create<Packet> ();
552  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
553  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
554  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
555  Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
556  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
557  uint32_t packetSize = packet->GetSize ();
558  NS_LOG_FUNCTION (m_mainAddress << " received dsdv packet of size: " << packetSize
559  << " and packet id: " << packet->GetUid ());
560  uint32_t count = 0;
561  for (; packetSize > 0; packetSize = packetSize - 12)
562  {
563  count = 0;
564  DsdvHeader dsdvHeader, tempDsdvHeader;
565  packet->RemoveHeader (dsdvHeader);
566  NS_LOG_DEBUG ("Processing new update for " << dsdvHeader.GetDst ());
567  /*Verifying if the packets sent by me were returned back to me. If yes, discarding them!*/
568  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
569  != m_socketAddresses.end (); ++j)
570  {
571  Ipv4InterfaceAddress interface = j->second;
572  if (dsdvHeader.GetDst () == interface.GetLocal ())
573  {
574  if (dsdvHeader.GetDstSeqno () % 2 == 1)
575  {
576  NS_LOG_DEBUG ("Sent Dsdv update back to the same Destination, "
577  "with infinite metric. Time left to send fwd update: "
579  count++;
580  }
581  else
582  {
583  NS_LOG_DEBUG ("Received update for my address. Discarding this.");
584  count++;
585  }
586  }
587  }
588  if (count > 0)
589  {
590  continue;
591  }
592  NS_LOG_DEBUG ("Received a DSDV packet from "
593  << sender << " to " << receiver << ". Details are: Destination: " << dsdvHeader.GetDst () << ", Seq No: "
594  << dsdvHeader.GetDstSeqno () << ", HopCount: " << dsdvHeader.GetHopCount ());
595  RoutingTableEntry fwdTableEntry, advTableEntry;
596  EventId event;
597  bool permanentTableVerifier = m_routingTable.LookupRoute (dsdvHeader.GetDst (),fwdTableEntry);
598  if (permanentTableVerifier == false)
599  {
600  if (dsdvHeader.GetDstSeqno () % 2 != 1)
601  {
602  NS_LOG_DEBUG ("Received New Route!");
603  RoutingTableEntry newEntry (
604  /*device=*/ dev, /*dst=*/
605  dsdvHeader.GetDst (), /*seqno=*/
606  dsdvHeader.GetDstSeqno (),
607  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
608  /*hops=*/ dsdvHeader.GetHopCount (), /*next hop=*/
609  sender, /*lifetime=*/
610  Simulator::Now (), /*settlingTime*/
611  m_settlingTime, /*entries changed*/
612  true);
613  newEntry.SetFlag (VALID);
614  m_routingTable.AddRoute (newEntry);
615  NS_LOG_DEBUG ("New Route added to both tables");
616  m_advRoutingTable.AddRoute (newEntry);
617  }
618  else
619  {
620  // received update not present in main routing table and also with infinite metric
621  NS_LOG_DEBUG ("Discarding this update as this route is not present in "
622  "main routing table and received with infinite metric");
623  }
624  }
625  else
626  {
627  if (!m_advRoutingTable.LookupRoute (dsdvHeader.GetDst (),advTableEntry))
628  {
630  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
632  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
633  {
634  NS_LOG_DEBUG ("ADV table routes are:" << i->second.GetDestination ());
635  }
636  // present in fwd table and not in advtable
637  m_advRoutingTable.AddRoute (fwdTableEntry);
638  m_advRoutingTable.LookupRoute (dsdvHeader.GetDst (),advTableEntry);
639  }
640  if (dsdvHeader.GetDstSeqno () % 2 != 1)
641  {
642  if (dsdvHeader.GetDstSeqno () > advTableEntry.GetSeqNo ())
643  {
644  // Received update with better seq number. Clear any old events that are running
645  if (m_advRoutingTable.ForceDeleteIpv4Event (dsdvHeader.GetDst ()))
646  {
647  NS_LOG_DEBUG ("Canceling the timer to update route with better seq number");
648  }
649  // if its a changed metric *nomatter* where the update came from, wait for WST
650  if (dsdvHeader.GetHopCount () != advTableEntry.GetHop ())
651  {
652  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
653  advTableEntry.SetLifeTime (Simulator::Now ());
654  advTableEntry.SetFlag (VALID);
655  advTableEntry.SetEntriesChanged (true);
656  advTableEntry.SetNextHop (sender);
657  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
658  NS_LOG_DEBUG ("Received update with better sequence number and changed metric.Waiting for WST");
659  Time tempSettlingtime = GetSettlingTime (dsdvHeader.GetDst ());
660  advTableEntry.SetSettlingTime (tempSettlingtime);
661  NS_LOG_DEBUG ("Added Settling Time:" << tempSettlingtime.GetSeconds ()
662  << "s as there is no event running for this route");
663  event = Simulator::Schedule (tempSettlingtime,&RoutingProtocol::SendTriggeredUpdate,this);
664  m_advRoutingTable.AddIpv4Event (dsdvHeader.GetDst (),event);
665  NS_LOG_DEBUG ("EventCreated EventUID: " << event.GetUid ());
666  // if received changed metric, use it but adv it only after wst
667  m_routingTable.Update (advTableEntry);
668  m_advRoutingTable.Update (advTableEntry);
669  }
670  else
671  {
672  // Received update with better seq number and same metric.
673  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
674  advTableEntry.SetLifeTime (Simulator::Now ());
675  advTableEntry.SetFlag (VALID);
676  advTableEntry.SetEntriesChanged (true);
677  advTableEntry.SetNextHop (sender);
678  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
679  m_advRoutingTable.Update (advTableEntry);
680  NS_LOG_DEBUG ("Route with better sequence number and same metric received. Advertised without WST");
681  }
682  }
683  else if (dsdvHeader.GetDstSeqno () == advTableEntry.GetSeqNo ())
684  {
685  if (dsdvHeader.GetHopCount () < advTableEntry.GetHop ())
686  {
687  /*Received update with same seq number and better hop count.
688  * As the metric is changed, we will have to wait for WST before sending out this update.
689  */
690  NS_LOG_DEBUG ("Canceling any existing timer to update route with same sequence number "
691  "and better hop count");
693  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
694  advTableEntry.SetLifeTime (Simulator::Now ());
695  advTableEntry.SetFlag (VALID);
696  advTableEntry.SetEntriesChanged (true);
697  advTableEntry.SetNextHop (sender);
698  advTableEntry.SetHop (dsdvHeader.GetHopCount ());
699  Time tempSettlingtime = GetSettlingTime (dsdvHeader.GetDst ());
700  advTableEntry.SetSettlingTime (tempSettlingtime);
701  NS_LOG_DEBUG ("Added Settling Time," << tempSettlingtime.GetSeconds ()
702  << " as there is no current event running for this route");
703  event = Simulator::Schedule (tempSettlingtime,&RoutingProtocol::SendTriggeredUpdate,this);
704  m_advRoutingTable.AddIpv4Event (dsdvHeader.GetDst (),event);
705  NS_LOG_DEBUG ("EventCreated EventUID: " << event.GetUid ());
706  // if received changed metric, use it but adv it only after wst
707  m_routingTable.Update (advTableEntry);
708  m_advRoutingTable.Update (advTableEntry);
709  }
710  else
711  {
712  /*Received update with same seq number but with same or greater hop count.
713  * Discard that update.
714  */
715  if (!m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
716  {
717  /*update the timer only if nexthop address matches thus discarding
718  * updates to that destination from other nodes.
719  */
720  if (advTableEntry.GetNextHop () == sender)
721  {
722  advTableEntry.SetLifeTime (Simulator::Now ());
723  m_routingTable.Update (advTableEntry);
724  }
726  dsdvHeader.GetDst ());
727  }
728  NS_LOG_DEBUG ("Received update with same seq number and "
729  "same/worst metric for, " << dsdvHeader.GetDst () << ". Discarding the update.");
730  }
731  }
732  else
733  {
734  // Received update with an old sequence number. Discard the update
735  if (!m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
736  {
737  m_advRoutingTable.DeleteRoute (dsdvHeader.GetDst ());
738  }
739  NS_LOG_DEBUG (dsdvHeader.GetDst () << " : Received update with old seq number. Discarding the update.");
740  }
741  }
742  else
743  {
744  NS_LOG_DEBUG ("Route with infinite metric received for "
745  << dsdvHeader.GetDst () << " from " << sender);
746  // Delete route only if update was received from my nexthop neighbor
747  if (sender == advTableEntry.GetNextHop ())
748  {
749  NS_LOG_DEBUG ("Triggering an update for this unreachable route:");
750  std::map<Ipv4Address, RoutingTableEntry> dstsWithNextHopSrc;
751  m_routingTable.GetListOfDestinationWithNextHop (dsdvHeader.GetDst (),dstsWithNextHopSrc);
752  m_routingTable.DeleteRoute (dsdvHeader.GetDst ());
753  advTableEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
754  advTableEntry.SetEntriesChanged (true);
755  m_advRoutingTable.Update (advTableEntry);
756  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i = dstsWithNextHopSrc.begin (); i
757  != dstsWithNextHopSrc.end (); ++i)
758  {
759  i->second.SetSeqNo (i->second.GetSeqNo () + 1);
760  i->second.SetEntriesChanged (true);
761  m_advRoutingTable.AddRoute (i->second);
762  m_routingTable.DeleteRoute (i->second.GetDestination ());
763  }
764  }
765  else
766  {
767  if (!m_advRoutingTable.AnyRunningEvent (dsdvHeader.GetDst ()))
768  {
769  m_advRoutingTable.DeleteRoute (dsdvHeader.GetDst ());
770  }
771  NS_LOG_DEBUG (dsdvHeader.GetDst () <<
772  " : Discard this link break update as it was received from a different neighbor "
773  "and I can reach the destination");
774  }
775  }
776  }
777  }
778  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
780  if (EnableRouteAggregation && allRoutes.size () > 0)
781  {
783  }
784  else
785  {
787  }
788 }
789 
790 
791 void
793 {
794  NS_LOG_FUNCTION (m_mainAddress << " is sending a triggered update");
795  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
797  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
798  != m_socketAddresses.end (); ++j)
799  {
800  DsdvHeader dsdvHeader;
801  Ptr<Socket> socket = j->first;
802  Ipv4InterfaceAddress iface = j->second;
803  Ptr<Packet> packet = Create<Packet> ();
804  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
805  {
806  NS_LOG_LOGIC ("Destination: " << i->second.GetDestination ()
807  << " SeqNo:" << i->second.GetSeqNo () << " HopCount:"
808  << i->second.GetHop () + 1);
809  RoutingTableEntry temp = i->second;
810  if ((i->second.GetEntriesChanged () == true) && (!m_advRoutingTable.AnyRunningEvent (temp.GetDestination ())))
811  {
812  dsdvHeader.SetDst (i->second.GetDestination ());
813  dsdvHeader.SetDstSeqno (i->second.GetSeqNo ());
814  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
815  temp.SetFlag (VALID);
816  temp.SetEntriesChanged (false);
817  m_advRoutingTable.DeleteIpv4Event (temp.GetDestination ());
818  if (!(temp.GetSeqNo () % 2))
819  {
820  m_routingTable.Update (temp);
821  }
822  packet->AddHeader (dsdvHeader);
823  m_advRoutingTable.DeleteRoute (temp.GetDestination ());
824  NS_LOG_DEBUG ("Deleted this route from the advertised table");
825  }
826  else
827  {
828  EventId event = m_advRoutingTable.GetEventId (temp.GetDestination ());
829  NS_ASSERT (event.GetUid () != 0);
830  NS_LOG_DEBUG ("EventID " << event.GetUid () << " associated with "
831  << temp.GetDestination () << " has not expired, waiting in adv table");
832  }
833  }
834  if (packet->GetSize () >= 12)
835  {
836  RoutingTableEntry temp2;
837  m_routingTable.LookupRoute (m_ipv4->GetAddress (1, 0).GetBroadcast (), temp2);
838  dsdvHeader.SetDst (m_ipv4->GetAddress (1, 0).GetLocal ());
839  dsdvHeader.SetDstSeqno (temp2.GetSeqNo ());
840  dsdvHeader.SetHopCount (temp2.GetHop () + 1);
841  NS_LOG_DEBUG ("Adding my update as well to the packet");
842  packet->AddHeader (dsdvHeader);
843  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
844  Ipv4Address destination;
845  if (iface.GetMask () == Ipv4Mask::GetOnes ())
846  {
847  destination = Ipv4Address ("255.255.255.255");
848  }
849  else
850  {
851  destination = iface.GetBroadcast ();
852  }
853  socket->SendTo (packet, 0, InetSocketAddress (destination, DSDV_PORT));
854  NS_LOG_FUNCTION ("Sent Triggered Update from "
855  << dsdvHeader.GetDst ()
856  << " with packet id : " << packet->GetUid () << " and packet Size: " << packet->GetSize ());
857  }
858  else
859  {
860  NS_LOG_FUNCTION ("Update not sent as there are no updates to be triggered");
861  }
862  }
863 }
864 
865 void
867 {
868  std::map<Ipv4Address, RoutingTableEntry> removedAddresses, allRoutes;
869  m_routingTable.Purge (removedAddresses);
872  if (allRoutes.empty ())
873  {
874  return;
875  }
876  NS_LOG_FUNCTION (m_mainAddress << " is sending out its periodic update");
877  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
878  != m_socketAddresses.end (); ++j)
879  {
880  Ptr<Socket> socket = j->first;
881  Ipv4InterfaceAddress iface = j->second;
882  Ptr<Packet> packet = Create<Packet> ();
883  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
884  {
885  DsdvHeader dsdvHeader;
886  if (i->second.GetHop () == 0)
887  {
888  RoutingTableEntry ownEntry;
889  dsdvHeader.SetDst (m_ipv4->GetAddress (1,0).GetLocal ());
890  dsdvHeader.SetDstSeqno (i->second.GetSeqNo () + 2);
891  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
892  m_routingTable.LookupRoute (m_ipv4->GetAddress (1,0).GetBroadcast (),ownEntry);
893  ownEntry.SetSeqNo (dsdvHeader.GetDstSeqno ());
894  m_routingTable.Update (ownEntry);
895  packet->AddHeader (dsdvHeader);
896  }
897  else
898  {
899  dsdvHeader.SetDst (i->second.GetDestination ());
900  dsdvHeader.SetDstSeqno ((i->second.GetSeqNo ()));
901  dsdvHeader.SetHopCount (i->second.GetHop () + 1);
902  packet->AddHeader (dsdvHeader);
903  }
904  NS_LOG_DEBUG ("Forwarding the update for " << i->first);
905  NS_LOG_DEBUG ("Forwarding details are, Destination: " << dsdvHeader.GetDst ()
906  << ", SeqNo:" << dsdvHeader.GetDstSeqno ()
907  << ", HopCount:" << dsdvHeader.GetHopCount ()
908  << ", LifeTime: " << i->second.GetLifeTime ().GetSeconds ());
909  }
910  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator rmItr = removedAddresses.begin (); rmItr
911  != removedAddresses.end (); ++rmItr)
912  {
913  DsdvHeader removedHeader;
914  removedHeader.SetDst (rmItr->second.GetDestination ());
915  removedHeader.SetDstSeqno (rmItr->second.GetSeqNo () + 1);
916  removedHeader.SetHopCount (rmItr->second.GetHop () + 1);
917  packet->AddHeader (removedHeader);
918  NS_LOG_DEBUG ("Update for removed record is: Destination: " << removedHeader.GetDst ()
919  << " SeqNo:" << removedHeader.GetDstSeqno ()
920  << " HopCount:" << removedHeader.GetHopCount ());
921  }
922  socket->Send (packet);
923  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
924  Ipv4Address destination;
925  if (iface.GetMask () == Ipv4Mask::GetOnes ())
926  {
927  destination = Ipv4Address ("255.255.255.255");
928  }
929  else
930  {
931  destination = iface.GetBroadcast ();
932  }
933  socket->SendTo (packet, 0, InetSocketAddress (destination, DSDV_PORT));
934  NS_LOG_FUNCTION ("PeriodicUpdate Packet UID is : " << packet->GetUid ());
935  }
937 }
938 
939 void
941 {
942  NS_ASSERT (ipv4 != 0);
943  NS_ASSERT (m_ipv4 == 0);
944  m_ipv4 = ipv4;
945  // Create lo route. It is asserted that the only one interface up for now is loopback
946  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
947  m_lo = m_ipv4->GetNetDevice (0);
948  NS_ASSERT (m_lo != 0);
949  // Remember lo route
950  RoutingTableEntry rt (
951  /*device=*/ m_lo, /*dst=*/
952  Ipv4Address::GetLoopback (), /*seqno=*/
953  0,
954  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (),Ipv4Mask ("255.0.0.0")),
955  /*hops=*/ 0, /*next hop=*/
957  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
958  rt.SetFlag (INVALID);
959  rt.SetEntriesChanged (false);
962 }
963 
964 void
966 {
967  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ()
968  << " interface is up");
969  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
970  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
971  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
972  {
973  return;
974  }
975  // Create a socket to listen only on this interface
976  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
977  NS_ASSERT (socket != 0);
980  socket->BindToNetDevice (l3->GetNetDevice (i));
981  socket->SetAllowBroadcast (true);
982  socket->SetAttribute ("IpTtl",UintegerValue (1));
983  m_socketAddresses.insert (std::make_pair (socket,iface));
984  // Add local broadcast record to the routing table
985  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
986  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*seqno=*/ 0,/*iface=*/ iface,/*hops=*/ 0,
987  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
989  if (m_mainAddress == Ipv4Address ())
990  {
991  m_mainAddress = iface.GetLocal ();
992  }
994 }
995 
996 void
998 {
999  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1000  Ptr<NetDevice> dev = l3->GetNetDevice (i);
1001  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i,0));
1002  NS_ASSERT (socket);
1003  socket->Close ();
1004  m_socketAddresses.erase (socket);
1005  if (m_socketAddresses.empty ())
1006  {
1007  NS_LOG_LOGIC ("No dsdv interfaces");
1008  m_routingTable.Clear ();
1009  return;
1010  }
1013 }
1014 
1015 void
1018 {
1019  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
1020  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1021  if (!l3->IsUp (i))
1022  {
1023  return;
1024  }
1025  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
1027  if (!socket)
1028  {
1029  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
1030  {
1031  return;
1032  }
1033  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
1034  NS_ASSERT (socket != 0);
1036  // Bind to any IP address so that broadcasts can be received
1038  socket->BindToNetDevice (l3->GetNetDevice (i));
1039  socket->SetAllowBroadcast (true);
1040  m_socketAddresses.insert (std::make_pair (socket,iface));
1041  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
1042  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (),/*seqno=*/ 0, /*iface=*/ iface,/*hops=*/ 0,
1043  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
1044  m_routingTable.AddRoute (rt);
1045  }
1046 }
1047 
1048 void
1051 {
1052  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
1053  if (socket)
1054  {
1055  m_socketAddresses.erase (socket);
1056  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1057  if (l3->GetNAddresses (i))
1058  {
1059  Ipv4InterfaceAddress iface = l3->GetAddress (i,0);
1060  // Create a socket to listen only on this interface
1061  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
1062  NS_ASSERT (socket != 0);
1064  // Bind to any IP address so that broadcasts can be received
1066  socket->SetAllowBroadcast (true);
1067  m_socketAddresses.insert (std::make_pair (socket,iface));
1068  }
1069  }
1070 }
1071 
1074 {
1075  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j
1076  != m_socketAddresses.end (); ++j)
1077  {
1078  Ptr<Socket> socket = j->first;
1079  Ipv4InterfaceAddress iface = j->second;
1080  if (iface == addr)
1081  {
1082  return socket;
1083  }
1084  }
1085  Ptr<Socket> socket;
1086  return socket;
1087 }
1088 
1089 void
1091  Ptr<const Packet> packet,
1092  const Ipv4Header & header)
1093 {
1094  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
1095  NS_ASSERT (l3 != 0);
1096  Ptr<Packet> p = packet->Copy ();
1097  l3->Send (p,route->GetSource (),header.GetDestination (),header.GetProtocol (),route);
1098 }
1099 
1100 void
1102  const Ipv4Header & header,
1103  Socket::SocketErrno err)
1104 {
1105  NS_LOG_DEBUG (m_mainAddress << " drop packet " << packet->GetUid () << " to "
1106  << header.GetDestination () << " from queue. Error " << err);
1107 }
1108 
1109 void
1111 {
1112  NS_LOG_FUNCTION (this);
1113  Ptr<Ipv4Route> route;
1114  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1115  m_routingTable.GetListOfAllRoutes (allRoutes);
1116  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1117  {
1118  RoutingTableEntry rt;
1119  rt = i->second;
1120  if (m_queue.Find (rt.GetDestination ()))
1121  {
1122  if (rt.GetHop () == 1)
1123  {
1124  route = rt.GetRoute ();
1125  NS_LOG_LOGIC ("A route exists from " << route->GetSource ()
1126  << " to neighboring destination "
1127  << route->GetDestination ());
1128  NS_ASSERT (route != 0);
1129  }
1130  else
1131  {
1132  RoutingTableEntry newrt;
1133  m_routingTable.LookupRoute (rt.GetNextHop (),newrt);
1134  route = newrt.GetRoute ();
1135  NS_LOG_LOGIC ("A route exists from " << route->GetSource ()
1136  << " to destination " << route->GetDestination () << " via "
1137  << rt.GetNextHop ());
1138  NS_ASSERT (route != 0);
1139  }
1140  SendPacketFromQueue (rt.GetDestination (),route);
1141  }
1142  }
1143 }
1144 
1145 void
1147  Ptr<Ipv4Route> route)
1148 {
1149  NS_LOG_DEBUG (m_mainAddress << " is sending a queued packet to destination " << dst);
1150  QueueEntry queueEntry;
1151  if (m_queue.Dequeue (dst,queueEntry))
1152  {
1154  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1155  if (p->RemovePacketTag (tag))
1156  {
1157  if (tag.oif != -1 && tag.oif != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1158  {
1159  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1160  return;
1161  }
1162  }
1164  Ipv4Header header = queueEntry.GetIpv4Header ();
1165  header.SetSource (route->GetSource ());
1166  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1167  ucb (route,p,header);
1168  if (m_queue.GetSize () != 0 && m_queue.Find (dst))
1169  {
1171  &RoutingProtocol::SendPacketFromQueue,this,dst,route);
1172  }
1173  }
1174 }
1175 
1176 Time
1178 {
1179  NS_LOG_FUNCTION ("Calculating the settling time for " << address);
1180  RoutingTableEntry mainrt;
1181  Time weightedTime;
1182  m_routingTable.LookupRoute (address,mainrt);
1183  if (EnableWST)
1184  {
1185  if (mainrt.GetSettlingTime () == Seconds (0))
1186  {
1187  return Seconds (0);
1188  }
1189  else
1190  {
1191  NS_LOG_DEBUG ("Route SettlingTime: " << mainrt.GetSettlingTime ().GetSeconds ()
1192  << " and LifeTime:" << mainrt.GetLifeTime ().GetSeconds ());
1193  weightedTime = Time (m_weightedFactor * mainrt.GetSettlingTime ().GetSeconds () + (1.0 - m_weightedFactor)
1194  * mainrt.GetLifeTime ().GetSeconds ());
1195  NS_LOG_DEBUG ("Calculated weightedTime:" << weightedTime.GetSeconds ());
1196  return weightedTime;
1197  }
1198  }
1199  return mainrt.GetSettlingTime ();
1200 }
1201 
1202 void
1204 {
1205  NS_LOG_FUNCTION ("Merging advertised table changes with main table before sending out periodic update");
1206  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1208  if (allRoutes.size () > 0)
1209  {
1210  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1211  {
1212  RoutingTableEntry advEntry = i->second;
1213  if ((advEntry.GetEntriesChanged () == true) && (!m_advRoutingTable.AnyRunningEvent (advEntry.GetDestination ())))
1214  {
1215  if (!(advEntry.GetSeqNo () % 2))
1216  {
1217  advEntry.SetFlag (VALID);
1218  advEntry.SetEntriesChanged (false);
1219  m_routingTable.Update (advEntry);
1220  NS_LOG_DEBUG ("Merged update for " << advEntry.GetDestination () << " with main routing Table");
1221  }
1223  }
1224  else
1225  {
1226  NS_LOG_DEBUG ("Event currently running. Cannot Merge Routing Tables");
1227  }
1228  }
1229  }
1230 }
1231 }
1232 }
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:1176
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:257
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:824
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:368
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:1270
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:792
second
Definition: nstime.h:114
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:346
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:33
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
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
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:846
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:1238
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:1489
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
double f(double x, void *params)
Definition: 80211b.c:60
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:1401
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:224
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.
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
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:831
A network Node.
Definition: node.h:56
#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
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:340
#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:904
Time GetLifeTime() const
Definition: dsdv-rtable.h:136
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:346
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
virtual Address GetAddress(void) const =0
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
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...