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