A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
dsdv-routing-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Hemanth Narra, Yufei Cheng
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Hemanth Narra <hemanth@ittc.ku.com>
7 * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
8 *
9 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
10 * ResiliNets Research Group https://resilinets.org/
11 * Information and Telecommunication Technology Center (ITTC)
12 * and Department of Electrical Engineering and Computer Science
13 * The University of Kansas Lawrence, KS USA.
14 *
15 * Work supported in part by NSF FIND (Future Internet Design) Program
16 * under grant CNS-0626918 (Postmodern Internet Architecture),
17 * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
18 * US Department of Defense (DoD), and ITTC at The University of Kansas.
19 */
20
22
23#include "ns3/boolean.h"
24#include "ns3/double.h"
25#include "ns3/inet-socket-address.h"
26#include "ns3/log.h"
27#include "ns3/trace-source-accessor.h"
28#include "ns3/udp-socket-factory.h"
29#include "ns3/uinteger.h"
30
31namespace ns3
32{
33
34NS_LOG_COMPONENT_DEFINE("DsdvRoutingProtocol");
35
36namespace dsdv
37{
38
39NS_OBJECT_ENSURE_REGISTERED(RoutingProtocol);
40
41/// UDP Port for DSDV control traffic
43
44/// Tag used by DSDV implementation
46{
47 /// Positive if output device is fixed in RouteOutput
49
50 /**
51 * Constructor
52 *
53 * \param o outgoing interface (OIF)
54 */
56 : Tag(),
57 oif(o)
58 {
59 }
60
61 /**
62 * \brief Get the type ID.
63 * \return the object TypeId
64 */
66 {
67 static TypeId tid = TypeId("ns3::dsdv::DeferredRouteOutputTag")
68 .SetParent<Tag>()
69 .SetGroupName("Dsdv")
70 .AddConstructor<DeferredRouteOutputTag>();
71 return tid;
72 }
73
74 TypeId GetInstanceTypeId() const override
75 {
76 return GetTypeId();
77 }
78
79 uint32_t GetSerializedSize() const override
80 {
81 return sizeof(int32_t);
82 }
83
84 void Serialize(TagBuffer i) const override
85 {
86 i.WriteU32(oif);
87 }
88
89 void Deserialize(TagBuffer i) override
90 {
91 oif = i.ReadU32();
92 }
93
94 void Print(std::ostream& os) const override
95 {
96 os << "DeferredRouteOutputTag: output interface = " << oif;
97 }
98};
99
100TypeId
102{
103 static TypeId tid =
104 TypeId("ns3::dsdv::RoutingProtocol")
106 .SetGroupName("Dsdv")
107 .AddConstructor<RoutingProtocol>()
108 .AddAttribute("PeriodicUpdateInterval",
109 "Periodic interval between exchange of full routing tables among nodes.",
110 TimeValue(Seconds(15)),
113 .AddAttribute("SettlingTime",
114 "Minimum time an update is to be stored in adv table before sending out "
115 "in case of change in metric (in seconds)",
116 TimeValue(Seconds(5)),
119 .AddAttribute("MaxQueueLen",
120 "Maximum number of packets that we allow a routing protocol to buffer.",
121 UintegerValue(500 /*assuming maximum nodes in simulation is 100*/),
124 .AddAttribute("MaxQueuedPacketsPerDst",
125 "Maximum number of packets that we allow per destination to buffer.",
126 UintegerValue(5),
129 .AddAttribute("MaxQueueTime",
130 "Maximum time packets can be queued (in seconds)",
131 TimeValue(Seconds(30)),
134 .AddAttribute(
135 "EnableBuffering",
136 "Enables buffering of data packets if no route to destination is available",
137 BooleanValue(true),
141 .AddAttribute(
142 "EnableWST",
143 "Enables Weighted Settling Time for the updates before advertising",
144 BooleanValue(true),
147 .AddAttribute("Holdtimes",
148 "Times the forwarding Interval to purge the route.",
149 UintegerValue(3),
152 .AddAttribute(
153 "WeightedFactor",
154 "WeightedFactor for the settling time if Weighted Settling Time is enabled",
155 DoubleValue(0.875),
158 .AddAttribute("EnableRouteAggregation",
159 "Enables Weighted Settling Time for the updates before advertising",
160 BooleanValue(false),
164 .AddAttribute("RouteAggregationTime",
165 "Time to aggregate updates before sending them out (in seconds)",
166 TimeValue(Seconds(1)),
169 return tid;
170}
171
172void
177
178bool
183
184void
186{
187 EnableWST = f;
188}
189
190bool
192{
193 return EnableWST;
194}
195
196void
201
202bool
207
208int64_t
210{
211 NS_LOG_FUNCTION(this << stream);
212 m_uniformRandomVariable->SetStream(stream);
213 return 1;
214}
215
217 : m_routingTable(),
218 m_advRoutingTable(),
219 m_queue(),
220 m_periodicUpdateTimer(Timer::CANCEL_ON_DESTROY)
221{
223}
224
228
229void
231{
232 m_ipv4 = nullptr;
233 for (auto iter = m_socketAddresses.begin(); iter != m_socketAddresses.end(); iter++)
234 {
235 iter->first->Close();
236 }
237 m_socketAddresses.clear();
239}
240
241void
243{
244 *stream->GetStream() << "Node: " << m_ipv4->GetObject<Node>()->GetId()
245 << ", Time: " << Now().As(unit)
246 << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
247 << ", DSDV Routing table" << std::endl;
248
249 m_routingTable.Print(stream, unit);
250 *stream->GetStream() << std::endl;
251}
252
253void
266
269 const Ipv4Header& header,
270 Ptr<NetDevice> oif,
271 Socket::SocketErrno& sockerr)
272{
273 NS_LOG_FUNCTION(this << header << (oif ? oif->GetIfIndex() : 0));
274
275 if (!p)
276 {
277 return LoopbackRoute(header, oif);
278 }
279 if (m_socketAddresses.empty())
280 {
282 NS_LOG_LOGIC("No dsdv interfaces");
283 Ptr<Ipv4Route> route;
284 return route;
285 }
286 std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
287 sockerr = Socket::ERROR_NOTERROR;
288 Ptr<Ipv4Route> route;
289 Ipv4Address dst = header.GetDestination();
290 NS_LOG_DEBUG("Packet Size: " << p->GetSize() << ", Packet id: " << p->GetUid()
291 << ", Destination address in Packet: " << dst);
293 m_routingTable.Purge(removedAddresses);
294 for (auto rmItr = removedAddresses.begin(); rmItr != removedAddresses.end(); ++rmItr)
295 {
296 rmItr->second.SetEntriesChanged(true);
297 rmItr->second.SetSeqNo(rmItr->second.GetSeqNo() + 1);
298 m_advRoutingTable.AddRoute(rmItr->second);
299 }
300 if (!removedAddresses.empty())
301 {
304 this);
305 }
306 if (m_routingTable.LookupRoute(dst, rt))
307 {
308 if (EnableBuffering)
309 {
311 }
312 if (rt.GetHop() == 1)
313 {
314 route = rt.GetRoute();
315 NS_ASSERT(route);
316 NS_LOG_DEBUG("A route exists from " << route->GetSource()
317 << " to neighboring destination "
318 << route->GetDestination());
319 if (oif && route->GetOutputDevice() != oif)
320 {
321 NS_LOG_DEBUG("Output device doesn't match. Dropped.");
323 return Ptr<Ipv4Route>();
324 }
325 return route;
326 }
327 else
328 {
329 RoutingTableEntry newrt;
330 if (m_routingTable.LookupRoute(rt.GetNextHop(), newrt))
331 {
332 route = newrt.GetRoute();
333 NS_ASSERT(route);
334 NS_LOG_DEBUG("A route exists from " << route->GetSource() << " to destination "
335 << dst << " via " << rt.GetNextHop());
336 if (oif && route->GetOutputDevice() != oif)
337 {
338 NS_LOG_DEBUG("Output device doesn't match. Dropped.");
340 return Ptr<Ipv4Route>();
341 }
342 return route;
343 }
344 }
345 }
346
347 if (EnableBuffering)
348 {
349 uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice(oif) : -1);
350 DeferredRouteOutputTag tag(iif);
351 if (!p->PeekPacketTag(tag))
352 {
353 p->AddPacketTag(tag);
354 }
355 }
356 return LoopbackRoute(header, oif);
357}
358
359void
361 const Ipv4Header& header,
363 ErrorCallback ecb)
364{
365 NS_LOG_FUNCTION(this << p << header);
366 NS_ASSERT(p && p != Ptr<Packet>());
367 QueueEntry newEntry(p, header, ucb, ecb);
368 bool result = m_queue.Enqueue(newEntry);
369 if (result)
370 {
371 NS_LOG_DEBUG("Added packet " << p->GetUid() << " to queue.");
372 }
373}
374
375bool
377 const Ipv4Header& header,
379 const UnicastForwardCallback& ucb,
380 const MulticastForwardCallback& mcb,
381 const LocalDeliverCallback& lcb,
382 const ErrorCallback& ecb)
383{
384 NS_LOG_FUNCTION(m_mainAddress << " received packet " << p->GetUid() << " from "
385 << header.GetSource() << " on interface " << idev->GetAddress()
386 << " to destination " << header.GetDestination());
387 if (m_socketAddresses.empty())
388 {
389 NS_LOG_DEBUG("No dsdv interfaces");
390 return false;
391 }
393 // Check if input device supports IP
396
397 Ipv4Address dst = header.GetDestination();
398 Ipv4Address origin = header.GetSource();
399
400 // DSDV is not a multicast routing protocol
401 if (dst.IsMulticast())
402 {
403 return false;
404 }
405
406 // Deferred route request
407 if (EnableBuffering && idev == m_lo)
408 {
410 if (p->PeekPacketTag(tag))
411 {
412 DeferredRouteOutput(p, header, ucb, ecb);
413 return true;
414 }
415 }
416 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
417 {
418 Ipv4InterfaceAddress iface = j->second;
419 if (origin == iface.GetLocal())
420 {
421 return true;
422 }
423 }
424 // LOCAL DELIVARY TO DSDV INTERFACES
425 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
426 {
427 Ipv4InterfaceAddress iface = j->second;
428 if (m_ipv4->GetInterfaceForAddress(iface.GetLocal()) == iif)
429 {
430 if (dst == iface.GetBroadcast() || dst.IsBroadcast())
431 {
432 Ptr<Packet> packet = p->Copy();
433 if (!lcb.IsNull())
434 {
435 NS_LOG_LOGIC("Broadcast local delivery to " << iface.GetLocal());
436 lcb(p, header, iif);
437 // Fall through to additional processing
438 }
439 else
440 {
441 NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
442 << p->GetUid() << " from " << origin);
443 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
444 }
445 if (header.GetTtl() > 1)
446 {
447 NS_LOG_LOGIC("Forward broadcast. TTL " << (uint16_t)header.GetTtl());
448 RoutingTableEntry toBroadcast;
449 if (m_routingTable.LookupRoute(dst, toBroadcast, true))
450 {
451 Ptr<Ipv4Route> route = toBroadcast.GetRoute();
452 ucb(route, packet, header);
453 }
454 else
455 {
456 NS_LOG_DEBUG("No route to forward. Drop packet " << p->GetUid());
457 }
458 }
459 return true;
460 }
461 }
462 }
463
464 if (m_ipv4->IsDestinationAddress(dst, iif))
465 {
466 if (!lcb.IsNull())
467 {
468 NS_LOG_LOGIC("Unicast local delivery to " << dst);
469 lcb(p, header, iif);
470 }
471 else
472 {
473 NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
474 << p->GetUid() << " from " << origin);
475 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
476 }
477 return true;
478 }
479
480 // Check if input device supports IP forwarding
481 if (!m_ipv4->IsForwarding(iif))
482 {
483 NS_LOG_LOGIC("Forwarding disabled for this interface");
484 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
485 return true;
486 }
487
488 RoutingTableEntry toDst;
489 if (m_routingTable.LookupRoute(dst, toDst))
490 {
492 if (m_routingTable.LookupRoute(toDst.GetNextHop(), ne))
493 {
494 Ptr<Ipv4Route> route = ne.GetRoute();
495 NS_LOG_LOGIC(m_mainAddress << " is forwarding packet " << p->GetUid() << " to " << dst
496 << " from " << header.GetSource() << " via nexthop neighbor "
497 << toDst.GetNextHop());
498 ucb(route, p, header);
499 return true;
500 }
501 }
502 NS_LOG_LOGIC("Drop packet " << p->GetUid() << " as there is no route to forward it.");
503 return false;
504}
505
508{
511 rt->SetDestination(hdr.GetDestination());
512 // rt->SetSource (hdr.GetSource ());
513 //
514 // Source address selection here is tricky. The loopback route is
515 // returned when DSDV does not have a route; this causes the packet
516 // to be looped back and handled (cached) in RouteInput() method
517 // while a route is found. However, connection-oriented protocols
518 // like TCP need to create an endpoint four-tuple (src, src port,
519 // dst, dst port) and create a pseudo-header for checksumming. So,
520 // DSDV needs to guess correctly what the eventual source address
521 // will be.
522 //
523 // For single interface, single address nodes, this is not a problem.
524 // When there are possibly multiple outgoing interfaces, the policy
525 // implemented here is to pick the first available DSDV interface.
526 // If RouteOutput() caller specified an outgoing interface, that
527 // further constrains the selection of source address
528 //
529 auto j = m_socketAddresses.begin();
530 if (oif)
531 {
532 // Iterate to find an address on the oif device
533 for (j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
534 {
535 Ipv4Address addr = j->second.GetLocal();
536 int32_t interface = m_ipv4->GetInterfaceForAddress(addr);
537 if (oif == m_ipv4->GetNetDevice(static_cast<uint32_t>(interface)))
538 {
539 rt->SetSource(addr);
540 break;
541 }
542 }
543 }
544 else
545 {
546 rt->SetSource(j->second.GetLocal());
547 }
548 NS_ASSERT_MSG(rt->GetSource() != Ipv4Address(), "Valid DSDV source address not found");
549 rt->SetGateway(Ipv4Address("127.0.0.1"));
550 rt->SetOutputDevice(m_lo);
551 return rt;
552}
553
554void
556{
557 Address sourceAddress;
558 Ptr<Packet> advpacket = Create<Packet>();
559 Ptr<Packet> packet = socket->RecvFrom(sourceAddress);
560 InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom(sourceAddress);
561 Ipv4Address sender = inetSourceAddr.GetIpv4();
562 Ipv4Address receiver = m_socketAddresses[socket].GetLocal();
564 uint32_t packetSize = packet->GetSize();
565 NS_LOG_FUNCTION(m_mainAddress << " received dsdv packet of size: " << packetSize
566 << " and packet id: " << packet->GetUid());
567 uint32_t count = 0;
568 for (; packetSize > 0; packetSize = packetSize - 12)
569 {
570 count = 0;
571 DsdvHeader dsdvHeader;
572 DsdvHeader tempDsdvHeader;
573 packet->RemoveHeader(dsdvHeader);
574 NS_LOG_DEBUG("Processing new update for " << dsdvHeader.GetDst());
575 /*Verifying if the packets sent by me were returned back to me. If yes, discarding them!*/
576 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
577 {
578 Ipv4InterfaceAddress interface = j->second;
579 if (dsdvHeader.GetDst() == interface.GetLocal())
580 {
581 if (dsdvHeader.GetDstSeqno() % 2 == 1)
582 {
583 NS_LOG_DEBUG("Sent Dsdv update back to the same Destination, "
584 "with infinite metric. Time left to send fwd update: "
586 count++;
587 }
588 else
589 {
590 NS_LOG_DEBUG("Received update for my address. Discarding this.");
591 count++;
592 }
593 }
594 }
595 if (count > 0)
596 {
597 continue;
598 }
599 NS_LOG_DEBUG("Received a DSDV packet from "
600 << sender << " to " << receiver << ". Details are: Destination: "
601 << dsdvHeader.GetDst() << ", Seq No: " << dsdvHeader.GetDstSeqno()
602 << ", HopCount: " << dsdvHeader.GetHopCount());
603 RoutingTableEntry fwdTableEntry;
604 RoutingTableEntry advTableEntry;
605 EventId event;
606 bool permanentTableVerifier =
607 m_routingTable.LookupRoute(dsdvHeader.GetDst(), fwdTableEntry);
608 if (!permanentTableVerifier)
609 {
610 if (dsdvHeader.GetDstSeqno() % 2 != 1)
611 {
612 NS_LOG_DEBUG("Received New Route!");
613 RoutingTableEntry newEntry(
614 /*dev=*/dev,
615 /*dst=*/dsdvHeader.GetDst(),
616 /*seqNo=*/dsdvHeader.GetDstSeqno(),
617 /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
618 /*hops=*/dsdvHeader.GetHopCount(),
619 /*nextHop=*/sender,
620 /*lifetime=*/Simulator::Now(),
621 /*settlingTime=*/m_settlingTime,
622 /*changedEntries=*/true);
623 newEntry.SetFlag(VALID);
624 m_routingTable.AddRoute(newEntry);
625 NS_LOG_DEBUG("New Route added to both tables");
626 m_advRoutingTable.AddRoute(newEntry);
627 }
628 else
629 {
630 // received update not present in main routing table and also with infinite metric
631 NS_LOG_DEBUG("Discarding this update as this route is not present in "
632 "main routing table and received with infinite metric");
633 }
634 }
635 else
636 {
637 if (!m_advRoutingTable.LookupRoute(dsdvHeader.GetDst(), advTableEntry))
638 {
640 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
642 for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
643 {
644 NS_LOG_DEBUG("ADV table routes are:" << i->second.GetDestination());
645 }
646 // present in fwd table and not in advtable
647 m_advRoutingTable.AddRoute(fwdTableEntry);
648 m_advRoutingTable.LookupRoute(dsdvHeader.GetDst(), advTableEntry);
649 }
650 if (dsdvHeader.GetDstSeqno() % 2 != 1)
651 {
652 if (dsdvHeader.GetDstSeqno() > advTableEntry.GetSeqNo())
653 {
654 // Received update with better seq number. Clear any old events that are running
656 {
657 NS_LOG_DEBUG("Canceling the timer to update route with better seq number");
658 }
659 // if its a changed metric *nomatter* where the update came from, wait for WST
660 if (dsdvHeader.GetHopCount() != advTableEntry.GetHop())
661 {
662 advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
663 advTableEntry.SetLifeTime(Simulator::Now());
664 advTableEntry.SetFlag(VALID);
665 advTableEntry.SetEntriesChanged(true);
666 advTableEntry.SetNextHop(sender);
667 advTableEntry.SetHop(dsdvHeader.GetHopCount());
668 NS_LOG_DEBUG("Received update with better sequence number and changed "
669 "metric.Waiting for WST");
670 Time tempSettlingtime = GetSettlingTime(dsdvHeader.GetDst());
671 advTableEntry.SetSettlingTime(tempSettlingtime);
672 NS_LOG_DEBUG("Added Settling Time:"
673 << tempSettlingtime.As(Time::S)
674 << " as there is no event running for this route");
675 event = Simulator::Schedule(tempSettlingtime,
677 this);
678 m_advRoutingTable.AddIpv4Event(dsdvHeader.GetDst(), event);
679 NS_LOG_DEBUG("EventCreated EventUID: " << event.GetUid());
680 // if received changed metric, use it but adv it only after wst
681 m_routingTable.Update(advTableEntry);
682 m_advRoutingTable.Update(advTableEntry);
683 }
684 else
685 {
686 // Received update with better seq number and same metric.
687 advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
688 advTableEntry.SetLifeTime(Simulator::Now());
689 advTableEntry.SetFlag(VALID);
690 advTableEntry.SetEntriesChanged(true);
691 advTableEntry.SetNextHop(sender);
692 advTableEntry.SetHop(dsdvHeader.GetHopCount());
693 m_advRoutingTable.Update(advTableEntry);
694 NS_LOG_DEBUG("Route with better sequence number and same metric received. "
695 "Advertised without WST");
696 }
697 }
698 else if (dsdvHeader.GetDstSeqno() == advTableEntry.GetSeqNo())
699 {
700 if (dsdvHeader.GetHopCount() < advTableEntry.GetHop())
701 {
702 /*Received update with same seq number and better hop count.
703 * As the metric is changed, we will have to wait for WST before sending out
704 * this update.
705 */
706 NS_LOG_DEBUG("Canceling any existing timer to update route with same "
707 "sequence number "
708 "and better hop count");
710 advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
711 advTableEntry.SetLifeTime(Simulator::Now());
712 advTableEntry.SetFlag(VALID);
713 advTableEntry.SetEntriesChanged(true);
714 advTableEntry.SetNextHop(sender);
715 advTableEntry.SetHop(dsdvHeader.GetHopCount());
716 Time tempSettlingtime = GetSettlingTime(dsdvHeader.GetDst());
717 advTableEntry.SetSettlingTime(tempSettlingtime);
718 NS_LOG_DEBUG("Added Settling Time,"
719 << tempSettlingtime.As(Time::S)
720 << " as there is no current event running for this route");
721 event = Simulator::Schedule(tempSettlingtime,
723 this);
724 m_advRoutingTable.AddIpv4Event(dsdvHeader.GetDst(), event);
725 NS_LOG_DEBUG("EventCreated EventUID: " << event.GetUid());
726 // if received changed metric, use it but adv it only after wst
727 m_routingTable.Update(advTableEntry);
728 m_advRoutingTable.Update(advTableEntry);
729 }
730 else
731 {
732 /*Received update with same seq number but with same or greater hop count.
733 * Discard that update.
734 */
735 if (!m_advRoutingTable.AnyRunningEvent(dsdvHeader.GetDst()))
736 {
737 /*update the timer only if nexthop address matches thus discarding
738 * updates to that destination from other nodes.
739 */
740 if (advTableEntry.GetNextHop() == sender)
741 {
742 advTableEntry.SetLifeTime(Simulator::Now());
743 m_routingTable.Update(advTableEntry);
744 }
746 }
747 NS_LOG_DEBUG("Received update with same seq number and "
748 "same/worst metric for, "
749 << dsdvHeader.GetDst() << ". Discarding the update.");
750 }
751 }
752 else
753 {
754 // Received update with an old sequence number. Discard the update
755 if (!m_advRoutingTable.AnyRunningEvent(dsdvHeader.GetDst()))
756 {
758 }
760 dsdvHeader.GetDst()
761 << " : Received update with old seq number. Discarding the update.");
762 }
763 }
764 else
765 {
766 NS_LOG_DEBUG("Route with infinite metric received for " << dsdvHeader.GetDst()
767 << " from " << sender);
768 // Delete route only if update was received from my nexthop neighbor
769 if (sender == advTableEntry.GetNextHop())
770 {
771 NS_LOG_DEBUG("Triggering an update for this unreachable route:");
772 std::map<Ipv4Address, RoutingTableEntry> dstsWithNextHopSrc;
774 dstsWithNextHopSrc);
775 m_routingTable.DeleteRoute(dsdvHeader.GetDst());
776 advTableEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
777 advTableEntry.SetEntriesChanged(true);
778 m_advRoutingTable.Update(advTableEntry);
779 for (auto i = dstsWithNextHopSrc.begin(); i != dstsWithNextHopSrc.end(); ++i)
780 {
781 i->second.SetSeqNo(i->second.GetSeqNo() + 1);
782 i->second.SetEntriesChanged(true);
783 m_advRoutingTable.AddRoute(i->second);
784 m_routingTable.DeleteRoute(i->second.GetDestination());
785 }
786 }
787 else
788 {
789 if (!m_advRoutingTable.AnyRunningEvent(dsdvHeader.GetDst()))
790 {
792 }
793 NS_LOG_DEBUG(dsdvHeader.GetDst() << " : Discard this link break update as it "
794 "was received from a different neighbor "
795 "and I can reach the destination");
796 }
797 }
798 }
799 }
800 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
802 if (EnableRouteAggregation && !allRoutes.empty())
803 {
805 }
806 else
807 {
810 this);
811 }
812}
813
814void
816{
817 NS_LOG_FUNCTION(m_mainAddress << " is sending a triggered update");
818 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
820 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
821 {
822 DsdvHeader dsdvHeader;
823 Ptr<Socket> socket = j->first;
824 Ipv4InterfaceAddress iface = j->second;
825 Ptr<Packet> packet = Create<Packet>();
826 for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
827 {
828 NS_LOG_LOGIC("Destination: " << i->second.GetDestination()
829 << " SeqNo:" << i->second.GetSeqNo()
830 << " HopCount:" << i->second.GetHop() + 1);
831 RoutingTableEntry temp = i->second;
832 if (i->second.GetEntriesChanged() &&
834 {
835 dsdvHeader.SetDst(i->second.GetDestination());
836 dsdvHeader.SetDstSeqno(i->second.GetSeqNo());
837 dsdvHeader.SetHopCount(i->second.GetHop() + 1);
838 temp.SetFlag(VALID);
839 temp.SetEntriesChanged(false);
841 if (!(temp.GetSeqNo() % 2))
842 {
844 }
845 packet->AddHeader(dsdvHeader);
847 NS_LOG_DEBUG("Deleted this route from the advertised table");
848 }
849 else
850 {
852 NS_ASSERT(event.GetUid() != 0);
853 NS_LOG_DEBUG("EventID " << event.GetUid() << " associated with "
854 << temp.GetDestination()
855 << " has not expired, waiting in adv table");
856 }
857 }
858 if (packet->GetSize() >= 12)
859 {
860 RoutingTableEntry temp2;
862 dsdvHeader.SetDst(m_ipv4->GetAddress(1, 0).GetLocal());
863 dsdvHeader.SetDstSeqno(temp2.GetSeqNo());
864 dsdvHeader.SetHopCount(temp2.GetHop() + 1);
865 NS_LOG_DEBUG("Adding my update as well to the packet");
866 packet->AddHeader(dsdvHeader);
867 // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
868 Ipv4Address destination;
869 if (iface.GetMask() == Ipv4Mask::GetOnes())
870 {
871 destination = Ipv4Address("255.255.255.255");
872 }
873 else
874 {
875 destination = iface.GetBroadcast();
876 }
877 socket->SendTo(packet, 0, InetSocketAddress(destination, DSDV_PORT));
878 NS_LOG_FUNCTION("Sent Triggered Update from "
879 << dsdvHeader.GetDst() << " with packet id : " << packet->GetUid()
880 << " and packet Size: " << packet->GetSize());
881 }
882 else
883 {
884 NS_LOG_FUNCTION("Update not sent as there are no updates to be triggered");
885 }
886 }
887}
888
889void
891{
892 std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
893 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
894 m_routingTable.Purge(removedAddresses);
897 if (allRoutes.empty())
898 {
899 return;
900 }
901 NS_LOG_FUNCTION(m_mainAddress << " is sending out its periodic update");
902 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
903 {
904 Ptr<Socket> socket = j->first;
905 Ipv4InterfaceAddress iface = j->second;
906 Ptr<Packet> packet = Create<Packet>();
907 for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
908 {
909 DsdvHeader dsdvHeader;
910 if (i->second.GetHop() == 0)
911 {
912 RoutingTableEntry ownEntry;
913 dsdvHeader.SetDst(m_ipv4->GetAddress(1, 0).GetLocal());
914 dsdvHeader.SetDstSeqno(i->second.GetSeqNo() + 2);
915 dsdvHeader.SetHopCount(i->second.GetHop() + 1);
917 ownEntry.SetSeqNo(dsdvHeader.GetDstSeqno());
918 m_routingTable.Update(ownEntry);
919 packet->AddHeader(dsdvHeader);
920 }
921 else
922 {
923 dsdvHeader.SetDst(i->second.GetDestination());
924 dsdvHeader.SetDstSeqno(i->second.GetSeqNo());
925 dsdvHeader.SetHopCount(i->second.GetHop() + 1);
926 packet->AddHeader(dsdvHeader);
927 }
928 NS_LOG_DEBUG("Forwarding the update for " << i->first);
929 NS_LOG_DEBUG("Forwarding details are, Destination: "
930 << dsdvHeader.GetDst() << ", SeqNo:" << dsdvHeader.GetDstSeqno()
931 << ", HopCount:" << dsdvHeader.GetHopCount()
932 << ", LifeTime: " << i->second.GetLifeTime().As(Time::S));
933 }
934 for (auto rmItr = removedAddresses.begin(); rmItr != removedAddresses.end(); ++rmItr)
935 {
936 DsdvHeader removedHeader;
937 removedHeader.SetDst(rmItr->second.GetDestination());
938 removedHeader.SetDstSeqno(rmItr->second.GetSeqNo() + 1);
939 removedHeader.SetHopCount(rmItr->second.GetHop() + 1);
940 packet->AddHeader(removedHeader);
941 NS_LOG_DEBUG("Update for removed record is: Destination: "
942 << removedHeader.GetDst() << " SeqNo:" << removedHeader.GetDstSeqno()
943 << " HopCount:" << removedHeader.GetHopCount());
944 }
945 socket->Send(packet);
946 // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
947 Ipv4Address destination;
948 if (iface.GetMask() == Ipv4Mask::GetOnes())
949 {
950 destination = Ipv4Address("255.255.255.255");
951 }
952 else
953 {
954 destination = iface.GetBroadcast();
955 }
956 socket->SendTo(packet, 0, InetSocketAddress(destination, DSDV_PORT));
957 NS_LOG_FUNCTION("PeriodicUpdate Packet UID is : " << packet->GetUid());
958 }
960 MicroSeconds(25 * m_uniformRandomVariable->GetInteger(0, 1000)));
961}
962
963void
965{
966 NS_ASSERT(ipv4);
968 m_ipv4 = ipv4;
969 // Create lo route. It is asserted that the only one interface up for now is loopback
971 m_ipv4->GetAddress(0, 0).GetLocal() == Ipv4Address("127.0.0.1"));
974 // Remember lo route
976 /*dev=*/m_lo,
977 /*dst=*/Ipv4Address::GetLoopback(),
978 /*seqNo=*/0,
979 /*iface=*/Ipv4InterfaceAddress(Ipv4Address::GetLoopback(), Ipv4Mask("255.0.0.0")),
980 /*hops=*/0,
981 /*nextHop=*/Ipv4Address::GetLoopback(),
983 rt.SetFlag(INVALID);
984 rt.SetEntriesChanged(false);
987}
988
989void
991{
992 NS_LOG_FUNCTION(this << m_ipv4->GetAddress(i, 0).GetLocal() << " interface is up");
994 Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
995 if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
996 {
997 return;
998 }
999 // Create a socket to listen only on this interface
1001 NS_ASSERT(socket);
1002 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvDsdv, this));
1003 socket->BindToNetDevice(l3->GetNetDevice(i));
1005 socket->SetAllowBroadcast(true);
1006 socket->SetAttribute("IpTtl", UintegerValue(1));
1007 m_socketAddresses.insert(std::make_pair(socket, iface));
1008 // Add local broadcast record to the routing table
1010 RoutingTableEntry rt(/*dev=*/dev,
1011 /*dst=*/iface.GetBroadcast(),
1012 /*seqNo=*/0,
1013 /*iface=*/iface,
1014 /*hops=*/0,
1015 /*nextHop=*/iface.GetBroadcast(),
1018 if (m_mainAddress == Ipv4Address())
1019 {
1020 m_mainAddress = iface.GetLocal();
1021 }
1023}
1024
1025void
1027{
1029 Ptr<NetDevice> dev = l3->GetNetDevice(i);
1031 NS_ASSERT(socket);
1032 socket->Close();
1033 m_socketAddresses.erase(socket);
1034 if (m_socketAddresses.empty())
1035 {
1036 NS_LOG_LOGIC("No dsdv interfaces");
1038 return;
1039 }
1042}
1043
1044void
1046{
1047 NS_LOG_FUNCTION(this << " interface " << i << " address " << address);
1049 if (!l3->IsUp(i))
1050 {
1051 return;
1052 }
1053 Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
1055 if (!socket)
1056 {
1057 if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
1058 {
1059 return;
1060 }
1062 NS_ASSERT(socket);
1063 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvDsdv, this));
1064 // Bind to any IP address so that broadcasts can be received
1065 socket->BindToNetDevice(l3->GetNetDevice(i));
1067 socket->SetAllowBroadcast(true);
1068 m_socketAddresses.insert(std::make_pair(socket, iface));
1070 RoutingTableEntry rt(/*dev=*/dev,
1071 /*dst=*/iface.GetBroadcast(),
1072 /*seqNo=*/0,
1073 /*iface=*/iface,
1074 /*hops=*/0,
1075 /*nextHop=*/iface.GetBroadcast(),
1078 }
1079}
1080
1081void
1083{
1085 if (socket)
1086 {
1087 m_socketAddresses.erase(socket);
1089 if (l3->GetNAddresses(i))
1090 {
1091 Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
1092 // Create a socket to listen only on this interface
1093 Ptr<Socket> socket =
1095 NS_ASSERT(socket);
1096 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvDsdv, this));
1097 // Bind to any IP address so that broadcasts can be received
1099 socket->SetAllowBroadcast(true);
1100 m_socketAddresses.insert(std::make_pair(socket, iface));
1101 }
1102 }
1103}
1104
1107{
1108 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
1109 {
1110 Ptr<Socket> socket = j->first;
1111 Ipv4InterfaceAddress iface = j->second;
1112 if (iface == addr)
1113 {
1114 return socket;
1115 }
1116 }
1117 Ptr<Socket> socket;
1118 return socket;
1119}
1120
1121void
1123{
1125 NS_ASSERT(l3);
1126 Ptr<Packet> p = packet->Copy();
1127 l3->Send(p, route->GetSource(), header.GetDestination(), header.GetProtocol(), route);
1128}
1129
1130void
1132{
1133 NS_LOG_DEBUG(m_mainAddress << " drop packet " << packet->GetUid() << " to "
1134 << header.GetDestination() << " from queue. Error " << err);
1135}
1136
1137void
1139{
1140 NS_LOG_FUNCTION(this);
1141 Ptr<Ipv4Route> route;
1142 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1144 for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
1145 {
1147 rt = i->second;
1148 if (m_queue.Find(rt.GetDestination()))
1149 {
1150 if (rt.GetHop() == 1)
1151 {
1152 route = rt.GetRoute();
1153 NS_ASSERT(route);
1154 NS_LOG_LOGIC("A route exists from " << route->GetSource()
1155 << " to neighboring destination "
1156 << route->GetDestination());
1157 }
1158 else
1159 {
1160 RoutingTableEntry newrt;
1162 route = newrt.GetRoute();
1163 NS_ASSERT(route);
1164 NS_LOG_LOGIC("A route exists from " << route->GetSource() << " to destination "
1165 << route->GetDestination() << " via "
1166 << rt.GetNextHop());
1167 }
1169 }
1170 }
1171}
1172
1173void
1175{
1176 NS_LOG_DEBUG(m_mainAddress << " is sending a queued packet to destination " << dst);
1177 QueueEntry queueEntry;
1178 if (m_queue.Dequeue(dst, queueEntry))
1179 {
1181 Ptr<Packet> p = ConstCast<Packet>(queueEntry.GetPacket());
1182 if (p->RemovePacketTag(tag))
1183 {
1184 if (tag.oif != -1 && tag.oif != m_ipv4->GetInterfaceForDevice(route->GetOutputDevice()))
1185 {
1186 NS_LOG_DEBUG("Output device doesn't match. Dropped.");
1187 return;
1188 }
1189 }
1191 Ipv4Header header = queueEntry.GetIpv4Header();
1192 header.SetSource(route->GetSource());
1193 header.SetTtl(header.GetTtl() +
1194 1); // compensate extra TTL decrement by fake loopback routing
1195 ucb(route, p, header);
1196 if (m_queue.GetSize() != 0 && m_queue.Find(dst))
1197 {
1200 this,
1201 dst,
1202 route);
1203 }
1204 }
1205}
1206
1207Time
1209{
1210 NS_LOG_FUNCTION("Calculating the settling time for " << address);
1211 RoutingTableEntry mainrt;
1212 Time weightedTime;
1213 m_routingTable.LookupRoute(address, mainrt);
1214 if (EnableWST)
1215 {
1216 if (mainrt.GetSettlingTime() == Seconds(0))
1217 {
1218 return Seconds(0);
1219 }
1220 else
1221 {
1222 NS_LOG_DEBUG("Route SettlingTime: " << mainrt.GetSettlingTime().As(Time::S)
1223 << " and LifeTime:"
1224 << mainrt.GetLifeTime().As(Time::S));
1225 weightedTime = m_weightedFactor * mainrt.GetSettlingTime() +
1226 (1.0 - m_weightedFactor) * mainrt.GetLifeTime();
1227 NS_LOG_DEBUG("Calculated weightedTime:" << weightedTime.As(Time::S));
1228 return weightedTime;
1229 }
1230 }
1231 return mainrt.GetSettlingTime();
1232}
1233
1234void
1236{
1238 "Merging advertised table changes with main table before sending out periodic update");
1239 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1241 if (!allRoutes.empty())
1242 {
1243 for (auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
1244 {
1245 RoutingTableEntry advEntry = i->second;
1246 if (advEntry.GetEntriesChanged() &&
1248 {
1249 if (!(advEntry.GetSeqNo() % 2))
1250 {
1251 advEntry.SetFlag(VALID);
1252 advEntry.SetEntriesChanged(false);
1253 m_routingTable.Update(advEntry);
1254 NS_LOG_DEBUG("Merged update for " << advEntry.GetDestination()
1255 << " with main routing Table");
1256 }
1258 }
1259 else
1260 {
1261 NS_LOG_DEBUG("Event currently running. Cannot Merge Routing Tables");
1262 }
1263 }
1264 }
1265}
1266} // namespace dsdv
1267} // namespace ns3
a polymophic address class
Definition address.h:90
AttributeValue implementation for Boolean.
Definition boolean.h:26
bool IsNull() const
Check for null implementation.
Definition callback.h:555
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
An identifier for simulation events.
Definition event-id.h:45
uint32_t GetUid() const
Definition event-id.cc:99
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.
static Ipv4Address GetLoopback()
bool IsMulticast() const
bool IsBroadcast() const
static Ipv4Address GetAny()
Packet header for IPv4.
Definition ipv4-header.h:23
Ipv4Address GetSource() const
uint8_t GetProtocol() const
void SetTtl(uint8_t ttl)
Ipv4Address GetDestination() const
uint8_t GetTtl() const
void SetSource(Ipv4Address source)
virtual int32_t GetInterfaceForAddress(Ipv4Address address) const =0
Return the interface number of the interface that has been assigned the specified IP address.
virtual bool IsForwarding(uint32_t interface) const =0
virtual Ipv4InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
Because addresses can be removed, the addressIndex is not guaranteed to be static across calls to thi...
virtual Ptr< NetDevice > GetNetDevice(uint32_t interface)=0
virtual bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const =0
Determine whether address and interface corresponding to received packet can be accepted for local de...
virtual int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const =0
virtual uint32_t GetNInterfaces() const =0
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
static Ipv4Mask GetOnes()
Abstract base class for IPv4 routing protocols.
A network Node.
Definition node.h:46
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
static Time GetMaximumSimulationTime()
Get the maximum representable simulation time.
Definition simulator.cc:300
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:61
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition socket.h:73
@ ERROR_NOROUTETOHOST
Definition socket.h:84
@ ERROR_NOTERROR
Definition socket.h:74
read and write tag data
Definition tag-buffer.h:41
TAG_BUFFER_INLINE uint32_t ReadU32()
Definition tag-buffer.h:206
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition tag-buffer.h:176
tag a set of bytes in a packet
Definition tag.h:28
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
Unit
The unit to use to interpret a number representing time.
Definition nstime.h:100
@ S
second
Definition nstime.h:105
AttributeValue implementation for Time.
Definition nstime.h:1395
A simple virtual Timer class.
Definition timer.h:67
void SetFunction(FN fn)
Definition timer.h:268
Time GetDelayLeft() const
Definition timer.cc:79
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition timer.cc:151
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
static TypeId GetTypeId()
Get the type ID.
Hold an unsigned integer type.
Definition uinteger.h:34
DSDV Update Packet Format.
Definition dsdv-packet.h:50
Ipv4Address GetDst() const
Get destination address.
Definition dsdv-packet.h:85
void SetDstSeqno(uint32_t sequenceNumber)
Set destination sequence number.
uint32_t GetHopCount() const
Get hop count.
uint32_t GetDstSeqno() const
Get destination sequence number.
void SetDst(Ipv4Address destination)
Set destination address.
Definition dsdv-packet.h:76
void SetHopCount(uint32_t hopCount)
Set hop count.
Definition dsdv-packet.h:94
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:48
void SetHop(uint32_t hopCount)
Set hop.
void SetLifeTime(Time lifeTime)
Set lifetime.
bool GetEntriesChanged() const
Get entries changed.
void SetEntriesChanged(bool entriesChanged)
Set entries changed indicator.
Time GetSettlingTime() const
Get settling time.
Ipv4Address GetDestination() const
Get destination IP address.
Definition dsdv-rtable.h:79
void SetSettlingTime(Time settlingTime)
Set settling time.
Ptr< Ipv4Route > GetRoute() const
Get route.
Definition dsdv-rtable.h:88
void SetNextHop(Ipv4Address nextHop)
Set next hop.
uint32_t GetSeqNo() const
Get sequence number.
Time GetLifeTime() const
Get lifetime.
void SetFlag(RouteFlags flag)
Set route flags.
uint32_t GetHop() const
Get hop.
Ipv4Address GetNextHop() const
Get next hop.
void SetSeqNo(uint32_t sequenceNumber)
Set sequence number.
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
bool ForceDeleteIpv4Event(Ipv4Address address)
Force delete an update waiting for settling time to complete as a better update to same destination w...
void Clear()
Delete all entries from routing table.
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
void Setholddowntime(Time t)
Set hold down time (time until an invalid route may be deleted)
bool DeleteIpv4Event(Ipv4Address address)
Clear up the entry from the map after the event is completed.
bool Update(RoutingTableEntry &rt)
Updating the routing Table with routing table entry rt.
void GetListOfDestinationWithNextHop(Ipv4Address nxtHp, std::map< Ipv4Address, RoutingTableEntry > &dstList)
Lookup list of addresses for which nxtHp is the next Hop address.
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table.
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
EventId GetEventId(Ipv4Address address)
Get the EventId associated with that address.
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...
bool AnyRunningEvent(Ipv4Address address)
Force delete an update waiting for settling time to complete as a better update to same destination w...
void Purge(std::map< Ipv4Address, RoutingTableEntry > &removedAddresses)
Delete all outdated entries if Lifetime is expired.
void GetListOfAllRoutes(std::map< Ipv4Address, RoutingTableEntry > &allRoutes)
Lookup list of all addresses in the routing table.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition boolean.h:70
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
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:32
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:1396
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
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:35
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition simulator.cc:294
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
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:684
Ptr< T1 > ConstCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:573
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.