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