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