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