A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 (auto iter = m_socketAddresses.begin(); iter != m_socketAddresses.end(); iter++)
245  {
246  iter->first->Close();
247  }
248  m_socketAddresses.clear();
250 }
251 
252 void
254 {
255  *stream->GetStream() << "Node: " << m_ipv4->GetObject<Node>()->GetId()
256  << ", Time: " << Now().As(unit)
257  << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
258  << ", DSDV Routing table" << std::endl;
259 
260  m_routingTable.Print(stream, unit);
261  *stream->GetStream() << std::endl;
262 }
263 
264 void
266 {
276 }
277 
280  const Ipv4Header& header,
281  Ptr<NetDevice> oif,
282  Socket::SocketErrno& sockerr)
283 {
284  NS_LOG_FUNCTION(this << header << (oif ? oif->GetIfIndex() : 0));
285 
286  if (!p)
287  {
288  return LoopbackRoute(header, oif);
289  }
290  if (m_socketAddresses.empty())
291  {
292  sockerr = Socket::ERROR_NOROUTETOHOST;
293  NS_LOG_LOGIC("No dsdv interfaces");
294  Ptr<Ipv4Route> route;
295  return route;
296  }
297  std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
298  sockerr = Socket::ERROR_NOTERROR;
299  Ptr<Ipv4Route> route;
300  Ipv4Address dst = header.GetDestination();
301  NS_LOG_DEBUG("Packet Size: " << p->GetSize() << ", Packet id: " << p->GetUid()
302  << ", Destination address in Packet: " << dst);
304  m_routingTable.Purge(removedAddresses);
305  for (auto rmItr = removedAddresses.begin(); rmItr != removedAddresses.end(); ++rmItr)
306  {
307  rmItr->second.SetEntriesChanged(true);
308  rmItr->second.SetSeqNo(rmItr->second.GetSeqNo() + 1);
309  m_advRoutingTable.AddRoute(rmItr->second);
310  }
311  if (!removedAddresses.empty())
312  {
315  this);
316  }
317  if (m_routingTable.LookupRoute(dst, rt))
318  {
319  if (EnableBuffering)
320  {
322  }
323  if (rt.GetHop() == 1)
324  {
325  route = rt.GetRoute();
326  NS_ASSERT(route);
327  NS_LOG_DEBUG("A route exists from " << route->GetSource()
328  << " to neighboring destination "
329  << route->GetDestination());
330  if (oif && route->GetOutputDevice() != oif)
331  {
332  NS_LOG_DEBUG("Output device doesn't match. Dropped.");
333  sockerr = Socket::ERROR_NOROUTETOHOST;
334  return Ptr<Ipv4Route>();
335  }
336  return route;
337  }
338  else
339  {
340  RoutingTableEntry newrt;
341  if (m_routingTable.LookupRoute(rt.GetNextHop(), newrt))
342  {
343  route = newrt.GetRoute();
344  NS_ASSERT(route);
345  NS_LOG_DEBUG("A route exists from " << route->GetSource() << " to destination "
346  << dst << " via " << rt.GetNextHop());
347  if (oif && route->GetOutputDevice() != oif)
348  {
349  NS_LOG_DEBUG("Output device doesn't match. Dropped.");
350  sockerr = Socket::ERROR_NOROUTETOHOST;
351  return Ptr<Ipv4Route>();
352  }
353  return route;
354  }
355  }
356  }
357 
358  if (EnableBuffering)
359  {
360  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice(oif) : -1);
361  DeferredRouteOutputTag tag(iif);
362  if (!p->PeekPacketTag(tag))
363  {
364  p->AddPacketTag(tag);
365  }
366  }
367  return LoopbackRoute(header, oif);
368 }
369 
370 void
372  const Ipv4Header& header,
374  ErrorCallback ecb)
375 {
376  NS_LOG_FUNCTION(this << p << header);
377  NS_ASSERT(p && p != Ptr<Packet>());
378  QueueEntry newEntry(p, header, ucb, ecb);
379  bool result = m_queue.Enqueue(newEntry);
380  if (result)
381  {
382  NS_LOG_DEBUG("Added packet " << p->GetUid() << " to queue.");
383  }
384 }
385 
386 bool
388  const Ipv4Header& header,
390  const UnicastForwardCallback& ucb,
391  const MulticastForwardCallback& mcb,
392  const LocalDeliverCallback& lcb,
393  const ErrorCallback& ecb)
394 {
395  NS_LOG_FUNCTION(m_mainAddress << " received packet " << p->GetUid() << " from "
396  << header.GetSource() << " on interface " << idev->GetAddress()
397  << " to destination " << header.GetDestination());
398  if (m_socketAddresses.empty())
399  {
400  NS_LOG_DEBUG("No dsdv interfaces");
401  return false;
402  }
403  NS_ASSERT(m_ipv4);
404  // Check if input device supports IP
405  NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
406  int32_t iif = m_ipv4->GetInterfaceForDevice(idev);
407 
408  Ipv4Address dst = header.GetDestination();
409  Ipv4Address origin = header.GetSource();
410 
411  // DSDV is not a multicast routing protocol
412  if (dst.IsMulticast())
413  {
414  return false;
415  }
416 
417  // Deferred route request
418  if (EnableBuffering && idev == m_lo)
419  {
421  if (p->PeekPacketTag(tag))
422  {
423  DeferredRouteOutput(p, header, ucb, ecb);
424  return true;
425  }
426  }
427  for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
428  {
429  Ipv4InterfaceAddress iface = j->second;
430  if (origin == iface.GetLocal())
431  {
432  return true;
433  }
434  }
435  // LOCAL DELIVARY TO DSDV INTERFACES
436  for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
437  {
438  Ipv4InterfaceAddress iface = j->second;
439  if (m_ipv4->GetInterfaceForAddress(iface.GetLocal()) == iif)
440  {
441  if (dst == iface.GetBroadcast() || dst.IsBroadcast())
442  {
443  Ptr<Packet> packet = p->Copy();
444  if (!lcb.IsNull())
445  {
446  NS_LOG_LOGIC("Broadcast local delivery to " << iface.GetLocal());
447  lcb(p, header, iif);
448  // Fall through to additional processing
449  }
450  else
451  {
452  NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
453  << p->GetUid() << " from " << origin);
454  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
455  }
456  if (header.GetTtl() > 1)
457  {
458  NS_LOG_LOGIC("Forward broadcast. TTL " << (uint16_t)header.GetTtl());
459  RoutingTableEntry toBroadcast;
460  if (m_routingTable.LookupRoute(dst, toBroadcast, true))
461  {
462  Ptr<Ipv4Route> route = toBroadcast.GetRoute();
463  ucb(route, packet, header);
464  }
465  else
466  {
467  NS_LOG_DEBUG("No route to forward. Drop packet " << p->GetUid());
468  }
469  }
470  return true;
471  }
472  }
473  }
474 
475  if (m_ipv4->IsDestinationAddress(dst, iif))
476  {
477  if (!lcb.IsNull())
478  {
479  NS_LOG_LOGIC("Unicast local delivery to " << dst);
480  lcb(p, header, iif);
481  }
482  else
483  {
484  NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
485  << p->GetUid() << " from " << origin);
486  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
487  }
488  return true;
489  }
490 
491  // Check if input device supports IP forwarding
492  if (!m_ipv4->IsForwarding(iif))
493  {
494  NS_LOG_LOGIC("Forwarding disabled for this interface");
495  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
496  return true;
497  }
498 
499  RoutingTableEntry toDst;
500  if (m_routingTable.LookupRoute(dst, toDst))
501  {
503  if (m_routingTable.LookupRoute(toDst.GetNextHop(), ne))
504  {
505  Ptr<Ipv4Route> route = ne.GetRoute();
506  NS_LOG_LOGIC(m_mainAddress << " is forwarding packet " << p->GetUid() << " to " << dst
507  << " from " << header.GetSource() << " via nexthop neighbor "
508  << toDst.GetNextHop());
509  ucb(route, p, header);
510  return true;
511  }
512  }
513  NS_LOG_LOGIC("Drop packet " << p->GetUid() << " as there is no route to forward it.");
514  return false;
515 }
516 
519 {
520  NS_ASSERT(m_lo);
521  Ptr<Ipv4Route> rt = Create<Ipv4Route>();
522  rt->SetDestination(hdr.GetDestination());
523  // rt->SetSource (hdr.GetSource ());
524  //
525  // Source address selection here is tricky. The loopback route is
526  // returned when DSDV does not have a route; this causes the packet
527  // to be looped back and handled (cached) in RouteInput() method
528  // while a route is found. However, connection-oriented protocols
529  // like TCP need to create an endpoint four-tuple (src, src port,
530  // dst, dst port) and create a pseudo-header for checksumming. So,
531  // DSDV needs to guess correctly what the eventual source address
532  // will be.
533  //
534  // For single interface, single address nodes, this is not a problem.
535  // When there are possibly multiple outgoing interfaces, the policy
536  // implemented here is to pick the first available DSDV interface.
537  // If RouteOutput() caller specified an outgoing interface, that
538  // further constrains the selection of source address
539  //
540  auto j = m_socketAddresses.begin();
541  if (oif)
542  {
543  // Iterate to find an address on the oif device
544  for (j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
545  {
546  Ipv4Address addr = j->second.GetLocal();
547  int32_t interface = m_ipv4->GetInterfaceForAddress(addr);
548  if (oif == m_ipv4->GetNetDevice(static_cast<uint32_t>(interface)))
549  {
550  rt->SetSource(addr);
551  break;
552  }
553  }
554  }
555  else
556  {
557  rt->SetSource(j->second.GetLocal());
558  }
559  NS_ASSERT_MSG(rt->GetSource() != Ipv4Address(), "Valid DSDV source address not found");
560  rt->SetGateway(Ipv4Address("127.0.0.1"));
561  rt->SetOutputDevice(m_lo);
562  return rt;
563 }
564 
565 void
567 {
568  Address sourceAddress;
569  Ptr<Packet> advpacket = Create<Packet>();
570  Ptr<Packet> packet = socket->RecvFrom(sourceAddress);
571  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom(sourceAddress);
572  Ipv4Address sender = inetSourceAddr.GetIpv4();
573  Ipv4Address receiver = m_socketAddresses[socket].GetLocal();
574  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
575  uint32_t packetSize = packet->GetSize();
576  NS_LOG_FUNCTION(m_mainAddress << " received dsdv packet of size: " << packetSize
577  << " and packet id: " << packet->GetUid());
578  uint32_t count = 0;
579  for (; packetSize > 0; packetSize = packetSize - 12)
580  {
581  count = 0;
582  DsdvHeader dsdvHeader;
583  DsdvHeader tempDsdvHeader;
584  packet->RemoveHeader(dsdvHeader);
585  NS_LOG_DEBUG("Processing new update for " << dsdvHeader.GetDst());
586  /*Verifying if the packets sent by me were returned back to me. If yes, discarding them!*/
587  for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
588  {
589  Ipv4InterfaceAddress interface = j->second;
590  if (dsdvHeader.GetDst() == interface.GetLocal())
591  {
592  if (dsdvHeader.GetDstSeqno() % 2 == 1)
593  {
594  NS_LOG_DEBUG("Sent Dsdv update back to the same Destination, "
595  "with infinite metric. Time left to send fwd update: "
597  count++;
598  }
599  else
600  {
601  NS_LOG_DEBUG("Received update for my address. Discarding this.");
602  count++;
603  }
604  }
605  }
606  if (count > 0)
607  {
608  continue;
609  }
610  NS_LOG_DEBUG("Received a DSDV packet from "
611  << sender << " to " << receiver << ". Details are: Destination: "
612  << dsdvHeader.GetDst() << ", Seq No: " << dsdvHeader.GetDstSeqno()
613  << ", HopCount: " << dsdvHeader.GetHopCount());
614  RoutingTableEntry fwdTableEntry;
615  RoutingTableEntry advTableEntry;
616  EventId event;
617  bool permanentTableVerifier =
618  m_routingTable.LookupRoute(dsdvHeader.GetDst(), fwdTableEntry);
619  if (!permanentTableVerifier)
620  {
621  if (dsdvHeader.GetDstSeqno() % 2 != 1)
622  {
623  NS_LOG_DEBUG("Received New Route!");
624  RoutingTableEntry newEntry(
625  /*dev=*/dev,
626  /*dst=*/dsdvHeader.GetDst(),
627  /*seqNo=*/dsdvHeader.GetDstSeqno(),
628  /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
629  /*hops=*/dsdvHeader.GetHopCount(),
630  /*nextHop=*/sender,
631  /*lifetime=*/Simulator::Now(),
632  /*settlingTime=*/m_settlingTime,
633  /*changedEntries=*/true);
634  newEntry.SetFlag(VALID);
635  m_routingTable.AddRoute(newEntry);
636  NS_LOG_DEBUG("New Route added to both tables");
637  m_advRoutingTable.AddRoute(newEntry);
638  }
639  else
640  {
641  // received update not present in main routing table and also with infinite metric
642  NS_LOG_DEBUG("Discarding this update as this route is not present in "
643  "main routing table and received with infinite metric");
644  }
645  }
646  else
647  {
648  if (!m_advRoutingTable.LookupRoute(dsdvHeader.GetDst(), advTableEntry))
649  {
651  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
653  for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
654  {
655  NS_LOG_DEBUG("ADV table routes are:" << i->second.GetDestination());
656  }
657  // present in fwd table and not in advtable
658  m_advRoutingTable.AddRoute(fwdTableEntry);
659  m_advRoutingTable.LookupRoute(dsdvHeader.GetDst(), advTableEntry);
660  }
661  if (dsdvHeader.GetDstSeqno() % 2 != 1)
662  {
663  if (dsdvHeader.GetDstSeqno() > advTableEntry.GetSeqNo())
664  {
665  // Received update with better seq number. Clear any old events that are running
667  {
668  NS_LOG_DEBUG("Canceling the timer to update route with better seq number");
669  }
670  // if its a changed metric *nomatter* where the update came from, wait for WST
671  if (dsdvHeader.GetHopCount() != advTableEntry.GetHop())
672  {
673  advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
674  advTableEntry.SetLifeTime(Simulator::Now());
675  advTableEntry.SetFlag(VALID);
676  advTableEntry.SetEntriesChanged(true);
677  advTableEntry.SetNextHop(sender);
678  advTableEntry.SetHop(dsdvHeader.GetHopCount());
679  NS_LOG_DEBUG("Received update with better sequence number and changed "
680  "metric.Waiting for WST");
681  Time tempSettlingtime = GetSettlingTime(dsdvHeader.GetDst());
682  advTableEntry.SetSettlingTime(tempSettlingtime);
683  NS_LOG_DEBUG("Added Settling Time:"
684  << tempSettlingtime.As(Time::S)
685  << " as there is no event running for this route");
686  event = Simulator::Schedule(tempSettlingtime,
688  this);
689  m_advRoutingTable.AddIpv4Event(dsdvHeader.GetDst(), event);
690  NS_LOG_DEBUG("EventCreated EventUID: " << event.GetUid());
691  // if received changed metric, use it but adv it only after wst
692  m_routingTable.Update(advTableEntry);
693  m_advRoutingTable.Update(advTableEntry);
694  }
695  else
696  {
697  // Received update with better seq number and same metric.
698  advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
699  advTableEntry.SetLifeTime(Simulator::Now());
700  advTableEntry.SetFlag(VALID);
701  advTableEntry.SetEntriesChanged(true);
702  advTableEntry.SetNextHop(sender);
703  advTableEntry.SetHop(dsdvHeader.GetHopCount());
704  m_advRoutingTable.Update(advTableEntry);
705  NS_LOG_DEBUG("Route with better sequence number and same metric received. "
706  "Advertised without WST");
707  }
708  }
709  else if (dsdvHeader.GetDstSeqno() == advTableEntry.GetSeqNo())
710  {
711  if (dsdvHeader.GetHopCount() < advTableEntry.GetHop())
712  {
713  /*Received update with same seq number and better hop count.
714  * As the metric is changed, we will have to wait for WST before sending out
715  * this update.
716  */
717  NS_LOG_DEBUG("Canceling any existing timer to update route with same "
718  "sequence number "
719  "and better hop count");
721  advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
722  advTableEntry.SetLifeTime(Simulator::Now());
723  advTableEntry.SetFlag(VALID);
724  advTableEntry.SetEntriesChanged(true);
725  advTableEntry.SetNextHop(sender);
726  advTableEntry.SetHop(dsdvHeader.GetHopCount());
727  Time tempSettlingtime = GetSettlingTime(dsdvHeader.GetDst());
728  advTableEntry.SetSettlingTime(tempSettlingtime);
729  NS_LOG_DEBUG("Added Settling Time,"
730  << tempSettlingtime.As(Time::S)
731  << " as there is no current event running for this route");
732  event = Simulator::Schedule(tempSettlingtime,
734  this);
735  m_advRoutingTable.AddIpv4Event(dsdvHeader.GetDst(), event);
736  NS_LOG_DEBUG("EventCreated EventUID: " << event.GetUid());
737  // if received changed metric, use it but adv it only after wst
738  m_routingTable.Update(advTableEntry);
739  m_advRoutingTable.Update(advTableEntry);
740  }
741  else
742  {
743  /*Received update with same seq number but with same or greater hop count.
744  * Discard that update.
745  */
746  if (!m_advRoutingTable.AnyRunningEvent(dsdvHeader.GetDst()))
747  {
748  /*update the timer only if nexthop address matches thus discarding
749  * updates to that destination from other nodes.
750  */
751  if (advTableEntry.GetNextHop() == sender)
752  {
753  advTableEntry.SetLifeTime(Simulator::Now());
754  m_routingTable.Update(advTableEntry);
755  }
756  m_advRoutingTable.DeleteRoute(dsdvHeader.GetDst());
757  }
758  NS_LOG_DEBUG("Received update with same seq number and "
759  "same/worst metric for, "
760  << dsdvHeader.GetDst() << ". Discarding the update.");
761  }
762  }
763  else
764  {
765  // Received update with an old sequence number. Discard the update
766  if (!m_advRoutingTable.AnyRunningEvent(dsdvHeader.GetDst()))
767  {
768  m_advRoutingTable.DeleteRoute(dsdvHeader.GetDst());
769  }
770  NS_LOG_DEBUG(
771  dsdvHeader.GetDst()
772  << " : Received update with old seq number. Discarding the update.");
773  }
774  }
775  else
776  {
777  NS_LOG_DEBUG("Route with infinite metric received for " << dsdvHeader.GetDst()
778  << " from " << sender);
779  // Delete route only if update was received from my nexthop neighbor
780  if (sender == advTableEntry.GetNextHop())
781  {
782  NS_LOG_DEBUG("Triggering an update for this unreachable route:");
783  std::map<Ipv4Address, RoutingTableEntry> dstsWithNextHopSrc;
785  dstsWithNextHopSrc);
786  m_routingTable.DeleteRoute(dsdvHeader.GetDst());
787  advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
788  advTableEntry.SetEntriesChanged(true);
789  m_advRoutingTable.Update(advTableEntry);
790  for (auto i = dstsWithNextHopSrc.begin(); i != dstsWithNextHopSrc.end(); ++i)
791  {
792  i->second.SetSeqNo(i->second.GetSeqNo() + 1);
793  i->second.SetEntriesChanged(true);
794  m_advRoutingTable.AddRoute(i->second);
795  m_routingTable.DeleteRoute(i->second.GetDestination());
796  }
797  }
798  else
799  {
800  if (!m_advRoutingTable.AnyRunningEvent(dsdvHeader.GetDst()))
801  {
802  m_advRoutingTable.DeleteRoute(dsdvHeader.GetDst());
803  }
804  NS_LOG_DEBUG(dsdvHeader.GetDst() << " : Discard this link break update as it "
805  "was received from a different neighbor "
806  "and I can reach the destination");
807  }
808  }
809  }
810  }
811  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
813  if (EnableRouteAggregation && !allRoutes.empty())
814  {
816  }
817  else
818  {
821  this);
822  }
823 }
824 
825 void
827 {
828  NS_LOG_FUNCTION(m_mainAddress << " is sending a triggered update");
829  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
831  for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
832  {
833  DsdvHeader dsdvHeader;
834  Ptr<Socket> socket = j->first;
835  Ipv4InterfaceAddress iface = j->second;
836  Ptr<Packet> packet = Create<Packet>();
837  for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
838  {
839  NS_LOG_LOGIC("Destination: " << i->second.GetDestination()
840  << " SeqNo:" << i->second.GetSeqNo()
841  << " HopCount:" << i->second.GetHop() + 1);
842  RoutingTableEntry temp = i->second;
843  if (i->second.GetEntriesChanged() &&
845  {
846  dsdvHeader.SetDst(i->second.GetDestination());
847  dsdvHeader.SetDstSeqno(i->second.GetSeqNo());
848  dsdvHeader.SetHopCount(i->second.GetHop() + 1);
849  temp.SetFlag(VALID);
850  temp.SetEntriesChanged(false);
852  if (!(temp.GetSeqNo() % 2))
853  {
854  m_routingTable.Update(temp);
855  }
856  packet->AddHeader(dsdvHeader);
858  NS_LOG_DEBUG("Deleted this route from the advertised table");
859  }
860  else
861  {
863  NS_ASSERT(event.GetUid() != 0);
864  NS_LOG_DEBUG("EventID " << event.GetUid() << " associated with "
865  << temp.GetDestination()
866  << " has not expired, waiting in adv table");
867  }
868  }
869  if (packet->GetSize() >= 12)
870  {
871  RoutingTableEntry temp2;
872  m_routingTable.LookupRoute(m_ipv4->GetAddress(1, 0).GetBroadcast(), temp2);
873  dsdvHeader.SetDst(m_ipv4->GetAddress(1, 0).GetLocal());
874  dsdvHeader.SetDstSeqno(temp2.GetSeqNo());
875  dsdvHeader.SetHopCount(temp2.GetHop() + 1);
876  NS_LOG_DEBUG("Adding my update as well to the packet");
877  packet->AddHeader(dsdvHeader);
878  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
879  Ipv4Address destination;
880  if (iface.GetMask() == Ipv4Mask::GetOnes())
881  {
882  destination = Ipv4Address("255.255.255.255");
883  }
884  else
885  {
886  destination = iface.GetBroadcast();
887  }
888  socket->SendTo(packet, 0, InetSocketAddress(destination, DSDV_PORT));
889  NS_LOG_FUNCTION("Sent Triggered Update from "
890  << dsdvHeader.GetDst() << " with packet id : " << packet->GetUid()
891  << " and packet Size: " << packet->GetSize());
892  }
893  else
894  {
895  NS_LOG_FUNCTION("Update not sent as there are no updates to be triggered");
896  }
897  }
898 }
899 
900 void
902 {
903  std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
904  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
905  m_routingTable.Purge(removedAddresses);
908  if (allRoutes.empty())
909  {
910  return;
911  }
912  NS_LOG_FUNCTION(m_mainAddress << " is sending out its periodic update");
913  for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
914  {
915  Ptr<Socket> socket = j->first;
916  Ipv4InterfaceAddress iface = j->second;
917  Ptr<Packet> packet = Create<Packet>();
918  for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
919  {
920  DsdvHeader dsdvHeader;
921  if (i->second.GetHop() == 0)
922  {
923  RoutingTableEntry ownEntry;
924  dsdvHeader.SetDst(m_ipv4->GetAddress(1, 0).GetLocal());
925  dsdvHeader.SetDstSeqno(i->second.GetSeqNo() + 2);
926  dsdvHeader.SetHopCount(i->second.GetHop() + 1);
927  m_routingTable.LookupRoute(m_ipv4->GetAddress(1, 0).GetBroadcast(), ownEntry);
928  ownEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
929  m_routingTable.Update(ownEntry);
930  packet->AddHeader(dsdvHeader);
931  }
932  else
933  {
934  dsdvHeader.SetDst(i->second.GetDestination());
935  dsdvHeader.SetDstSeqno(i->second.GetSeqNo());
936  dsdvHeader.SetHopCount(i->second.GetHop() + 1);
937  packet->AddHeader(dsdvHeader);
938  }
939  NS_LOG_DEBUG("Forwarding the update for " << i->first);
940  NS_LOG_DEBUG("Forwarding details are, Destination: "
941  << dsdvHeader.GetDst() << ", SeqNo:" << dsdvHeader.GetDstSeqno()
942  << ", HopCount:" << dsdvHeader.GetHopCount()
943  << ", LifeTime: " << i->second.GetLifeTime().As(Time::S));
944  }
945  for (auto rmItr = removedAddresses.begin(); rmItr != removedAddresses.end(); ++rmItr)
946  {
947  DsdvHeader removedHeader;
948  removedHeader.SetDst(rmItr->second.GetDestination());
949  removedHeader.SetDstSeqno(rmItr->second.GetSeqNo() + 1);
950  removedHeader.SetHopCount(rmItr->second.GetHop() + 1);
951  packet->AddHeader(removedHeader);
952  NS_LOG_DEBUG("Update for removed record is: Destination: "
953  << removedHeader.GetDst() << " SeqNo:" << removedHeader.GetDstSeqno()
954  << " HopCount:" << removedHeader.GetHopCount());
955  }
956  socket->Send(packet);
957  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
958  Ipv4Address destination;
959  if (iface.GetMask() == Ipv4Mask::GetOnes())
960  {
961  destination = Ipv4Address("255.255.255.255");
962  }
963  else
964  {
965  destination = iface.GetBroadcast();
966  }
967  socket->SendTo(packet, 0, InetSocketAddress(destination, DSDV_PORT));
968  NS_LOG_FUNCTION("PeriodicUpdate Packet UID is : " << packet->GetUid());
969  }
972 }
973 
974 void
976 {
977  NS_ASSERT(ipv4);
978  NS_ASSERT(!m_ipv4);
979  m_ipv4 = ipv4;
980  // Create lo route. It is asserted that the only one interface up for now is loopback
981  NS_ASSERT(m_ipv4->GetNInterfaces() == 1 &&
982  m_ipv4->GetAddress(0, 0).GetLocal() == Ipv4Address("127.0.0.1"));
983  m_lo = m_ipv4->GetNetDevice(0);
984  NS_ASSERT(m_lo);
985  // Remember lo route
987  /*dev=*/m_lo,
988  /*dst=*/Ipv4Address::GetLoopback(),
989  /*seqNo=*/0,
990  /*iface=*/Ipv4InterfaceAddress(Ipv4Address::GetLoopback(), Ipv4Mask("255.0.0.0")),
991  /*hops=*/0,
992  /*nextHop=*/Ipv4Address::GetLoopback(),
993  /*lifetime=*/Simulator::GetMaximumSimulationTime());
994  rt.SetFlag(INVALID);
995  rt.SetEntriesChanged(false);
998 }
999 
1000 void
1002 {
1003  NS_LOG_FUNCTION(this << m_ipv4->GetAddress(i, 0).GetLocal() << " interface is up");
1004  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
1005  Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
1006  if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
1007  {
1008  return;
1009  }
1010  // Create a socket to listen only on this interface
1011  Ptr<Socket> socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
1012  NS_ASSERT(socket);
1014  socket->BindToNetDevice(l3->GetNetDevice(i));
1016  socket->SetAllowBroadcast(true);
1017  socket->SetAttribute("IpTtl", UintegerValue(1));
1018  m_socketAddresses.insert(std::make_pair(socket, iface));
1019  // Add local broadcast record to the routing table
1020  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
1021  RoutingTableEntry rt(/*dev=*/dev,
1022  /*dst=*/iface.GetBroadcast(),
1023  /*seqNo=*/0,
1024  /*iface=*/iface,
1025  /*hops=*/0,
1026  /*nextHop=*/iface.GetBroadcast(),
1027  /*lifetime=*/Simulator::GetMaximumSimulationTime());
1029  if (m_mainAddress == Ipv4Address())
1030  {
1031  m_mainAddress = iface.GetLocal();
1032  }
1034 }
1035 
1036 void
1038 {
1039  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
1040  Ptr<NetDevice> dev = l3->GetNetDevice(i);
1041  Ptr<Socket> socket = FindSocketWithInterfaceAddress(m_ipv4->GetAddress(i, 0));
1042  NS_ASSERT(socket);
1043  socket->Close();
1044  m_socketAddresses.erase(socket);
1045  if (m_socketAddresses.empty())
1046  {
1047  NS_LOG_LOGIC("No dsdv interfaces");
1049  return;
1050  }
1053 }
1054 
1055 void
1057 {
1058  NS_LOG_FUNCTION(this << " interface " << i << " address " << address);
1059  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
1060  if (!l3->IsUp(i))
1061  {
1062  return;
1063  }
1064  Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
1066  if (!socket)
1067  {
1068  if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
1069  {
1070  return;
1071  }
1072  Ptr<Socket> socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
1073  NS_ASSERT(socket);
1075  // Bind to any IP address so that broadcasts can be received
1076  socket->BindToNetDevice(l3->GetNetDevice(i));
1078  socket->SetAllowBroadcast(true);
1079  m_socketAddresses.insert(std::make_pair(socket, iface));
1080  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
1081  RoutingTableEntry rt(/*dev=*/dev,
1082  /*dst=*/iface.GetBroadcast(),
1083  /*seqNo=*/0,
1084  /*iface=*/iface,
1085  /*hops=*/0,
1086  /*nextHop=*/iface.GetBroadcast(),
1087  /*lifetime=*/Simulator::GetMaximumSimulationTime());
1089  }
1090 }
1091 
1092 void
1094 {
1096  if (socket)
1097  {
1098  m_socketAddresses.erase(socket);
1099  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
1100  if (l3->GetNAddresses(i))
1101  {
1102  Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
1103  // Create a socket to listen only on this interface
1104  Ptr<Socket> socket =
1105  Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
1106  NS_ASSERT(socket);
1108  // Bind to any IP address so that broadcasts can be received
1110  socket->SetAllowBroadcast(true);
1111  m_socketAddresses.insert(std::make_pair(socket, iface));
1112  }
1113  }
1114 }
1115 
1118 {
1119  for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
1120  {
1121  Ptr<Socket> socket = j->first;
1122  Ipv4InterfaceAddress iface = j->second;
1123  if (iface == addr)
1124  {
1125  return socket;
1126  }
1127  }
1128  Ptr<Socket> socket;
1129  return socket;
1130 }
1131 
1132 void
1134 {
1135  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
1136  NS_ASSERT(l3);
1137  Ptr<Packet> p = packet->Copy();
1138  l3->Send(p, route->GetSource(), header.GetDestination(), header.GetProtocol(), route);
1139 }
1140 
1141 void
1143 {
1144  NS_LOG_DEBUG(m_mainAddress << " drop packet " << packet->GetUid() << " to "
1145  << header.GetDestination() << " from queue. Error " << err);
1146 }
1147 
1148 void
1150 {
1151  NS_LOG_FUNCTION(this);
1152  Ptr<Ipv4Route> route;
1153  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1155  for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
1156  {
1157  RoutingTableEntry rt;
1158  rt = i->second;
1159  if (m_queue.Find(rt.GetDestination()))
1160  {
1161  if (rt.GetHop() == 1)
1162  {
1163  route = rt.GetRoute();
1164  NS_ASSERT(route);
1165  NS_LOG_LOGIC("A route exists from " << route->GetSource()
1166  << " to neighboring destination "
1167  << route->GetDestination());
1168  }
1169  else
1170  {
1171  RoutingTableEntry newrt;
1172  m_routingTable.LookupRoute(rt.GetNextHop(), newrt);
1173  route = newrt.GetRoute();
1174  NS_ASSERT(route);
1175  NS_LOG_LOGIC("A route exists from " << route->GetSource() << " to destination "
1176  << route->GetDestination() << " via "
1177  << rt.GetNextHop());
1178  }
1179  SendPacketFromQueue(rt.GetDestination(), route);
1180  }
1181  }
1182 }
1183 
1184 void
1186 {
1187  NS_LOG_DEBUG(m_mainAddress << " is sending a queued packet to destination " << dst);
1188  QueueEntry queueEntry;
1189  if (m_queue.Dequeue(dst, queueEntry))
1190  {
1192  Ptr<Packet> p = ConstCast<Packet>(queueEntry.GetPacket());
1193  if (p->RemovePacketTag(tag))
1194  {
1195  if (tag.oif != -1 && tag.oif != m_ipv4->GetInterfaceForDevice(route->GetOutputDevice()))
1196  {
1197  NS_LOG_DEBUG("Output device doesn't match. Dropped.");
1198  return;
1199  }
1200  }
1202  Ipv4Header header = queueEntry.GetIpv4Header();
1203  header.SetSource(route->GetSource());
1204  header.SetTtl(header.GetTtl() +
1205  1); // compensate extra TTL decrement by fake loopback routing
1206  ucb(route, p, header);
1207  if (m_queue.GetSize() != 0 && m_queue.Find(dst))
1208  {
1211  this,
1212  dst,
1213  route);
1214  }
1215  }
1216 }
1217 
1218 Time
1220 {
1221  NS_LOG_FUNCTION("Calculating the settling time for " << address);
1222  RoutingTableEntry mainrt;
1223  Time weightedTime;
1225  if (EnableWST)
1226  {
1227  if (mainrt.GetSettlingTime() == Seconds(0))
1228  {
1229  return Seconds(0);
1230  }
1231  else
1232  {
1233  NS_LOG_DEBUG("Route SettlingTime: " << mainrt.GetSettlingTime().As(Time::S)
1234  << " and LifeTime:"
1235  << mainrt.GetLifeTime().As(Time::S));
1236  weightedTime = m_weightedFactor * mainrt.GetSettlingTime() +
1237  (1.0 - m_weightedFactor) * mainrt.GetLifeTime();
1238  NS_LOG_DEBUG("Calculated weightedTime:" << weightedTime.As(Time::S));
1239  return weightedTime;
1240  }
1241  }
1242  return mainrt.GetSettlingTime();
1243 }
1244 
1245 void
1247 {
1249  "Merging advertised table changes with main table before sending out periodic update");
1250  std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1252  if (!allRoutes.empty())
1253  {
1254  for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
1255  {
1256  RoutingTableEntry advEntry = i->second;
1257  if (advEntry.GetEntriesChanged() &&
1259  {
1260  if (!(advEntry.GetSeqNo() % 2))
1261  {
1262  advEntry.SetFlag(VALID);
1263  advEntry.SetEntriesChanged(false);
1264  m_routingTable.Update(advEntry);
1265  NS_LOG_DEBUG("Merged update for " << advEntry.GetDestination()
1266  << " with main routing Table");
1267  }
1269  }
1270  else
1271  {
1272  NS_LOG_DEBUG("Event currently running. Cannot Merge Routing Tables");
1273  }
1274  }
1275  }
1276 }
1277 } // namespace dsdv
1278 } // namespace ns3
double f(double x, void *params)
Definition: 80211b.c:70
a polymophic address class
Definition: address.h:101
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
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:42
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:257
static Ipv4Mask GetOnes()
Abstract base class for IPv4 routing protocols.
virtual Address GetAddress() const =0
A network Node.
Definition: node.h:57
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
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:967
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:861
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:960
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:983
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:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static Time GetMaximumSimulationTime()
Get the maximum representable simulation time.
Definition: simulator.cc:311
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:128
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:327
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:415
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
@ S
second
Definition: nstime.h:116
A simple virtual Timer class.
Definition: timer.h:74
void SetFunction(FN fn)
Definition: timer.h:275
Time GetDelayLeft() const
Definition: timer.cc:90
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:162
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
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.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route input packet.
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.
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:319
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:125
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:334
bool Update(RoutingTableEntry &rt)
Updating the routing Table with routing table entry rt.
Definition: dsdv-rtable.cc:132
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:178
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table.
Definition: dsdv-rtable.cc:268
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: dsdv-rtable.cc:144
EventId GetEventId(Ipv4Address address)
Get the EventId associated with that address.
Definition: dsdv-rtable.cc:361
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:295
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:302
void Purge(std::map< Ipv4Address, RoutingTableEntry > &removedAddresses)
Delete all outdated entries if Lifetime is expired.
Definition: dsdv-rtable.cc:224
void GetListOfAllRoutes(std::map< Ipv4Address, RoutingTableEntry > &allRoutes)
Lookup list of all addresses in the routing table.
Definition: dsdv-rtable.cc:166
#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
#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:305
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
address
Definition: first.py:47
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:839
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
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:704
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
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.