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