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 * 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
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
42namespace ns3
43{
44
45NS_LOG_COMPONENT_DEFINE("DsdvRoutingProtocol");
46
47namespace dsdv
48{
49
50NS_OBJECT_ENSURE_REGISTERED(RoutingProtocol);
51
52/// UDP Port for DSDV control traffic
54
55/// Tag used by DSDV implementation
57{
58 /// Positive if output device is fixed in RouteOutput
60
61 /**
62 * Constructor
63 *
64 * \param o outgoing interface (OIF)
65 */
67 : Tag(),
68 oif(o)
69 {
70 }
71
72 /**
73 * \brief Get the type ID.
74 * \return the object TypeId
75 */
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
111TypeId
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)),
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)),
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)),
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)),
180 return tid;
181}
182
183void
185{
186 EnableBuffering = f;
187}
188
189bool
191{
192 return EnableBuffering;
193}
194
195void
197{
198 EnableWST = f;
199}
200
201bool
203{
204 return EnableWST;
205}
206
207void
209{
211}
212
213bool
215{
217}
218
219int64_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
240void
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
252void
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
264void
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 {
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.");
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.");
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
370void
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
386bool
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 }
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{
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
565void
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 }
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 {
769 }
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 {
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
825void
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 {
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
900void
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
974void
976{
977 NS_ASSERT(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);
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(),
994 rt.SetFlag(INVALID);
995 rt.SetEntriesChanged(false);
998}
999
1000void
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);
1013 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvDsdv, this));
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(),
1029 if (m_mainAddress == Ipv4Address())
1030 {
1031 m_mainAddress = iface.GetLocal();
1032 }
1034}
1035
1036void
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
1055void
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);
1074 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvDsdv, this));
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(),
1089 }
1090}
1091
1092void
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 =
1106 NS_ASSERT(socket);
1107 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvDsdv, this));
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
1132void
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
1141void
1143{
1144 NS_LOG_DEBUG(m_mainAddress << " drop packet " << packet->GetUid() << " to "
1145 << header.GetDestination() << " from queue. Error " << err);
1146}
1147
1148void
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 {
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;
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 }
1180 }
1181 }
1182}
1183
1184void
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
1218Time
1220{
1221 NS_LOG_FUNCTION("Calculating the settling time for " << address);
1222 RoutingTableEntry mainrt;
1223 Time weightedTime;
1224 m_routingTable.LookupRoute(address, mainrt);
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
1245void
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
a polymophic address class
Definition: address.h:101
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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.
A network Node.
Definition: node.h:57
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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
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
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
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
AttributeValue implementation for Time.
Definition: nstime.h:1413
A simple virtual Timer class.
Definition: timer.h:78
void SetFunction(FN fn)
Definition: timer.h:279
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:932
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
void SetSettlingTime(Time settlingTime)
Set settling time.
Definition: dsdv-rtable.h:225
Ptr< Ipv4Route > GetRoute() const
Get route.
Definition: dsdv-rtable.h:99
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1434
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc: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
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:704
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.