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