35 #include "ns3/inet-socket-address.h"
36 #include "ns3/trace-source-accessor.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/wifi-net-device.h"
39 #include "ns3/boolean.h"
40 #include "ns3/double.h"
41 #include "ns3/uinteger.h"
80 return sizeof(int32_t);
98 os <<
"DeferredRouteOutputTag: output interface = " <<
oif;
105 static TypeId tid =
TypeId (
"ns3::dsdv::RoutingProtocol")
107 .AddConstructor<RoutingProtocol> ()
108 .AddAttribute (
"PeriodicUpdateInterval",
"Periodic interval between exchange of full routing tables among nodes. ",
112 .AddAttribute (
"SettlingTime",
"Minimum time an update is to be stored in adv table before sending out"
113 "in case of change in metric (in seconds)",
117 .AddAttribute (
"MaxQueueLen",
"Maximum number of packets that we allow a routing protocol to buffer.",
120 MakeUintegerChecker<uint32_t> ())
121 .AddAttribute (
"MaxQueuedPacketsPerDst",
"Maximum number of packets that we allow per destination to buffer.",
124 MakeUintegerChecker<uint32_t> ())
125 .AddAttribute (
"MaxQueueTime",
"Maximum time packets can be queued (in seconds)",
129 .AddAttribute (
"EnableBuffering",
"Enables buffering of data packets if no route to destination is available",
133 MakeBooleanChecker ())
134 .AddAttribute (
"EnableWST",
"Enables Weighted Settling Time for the updates before advertising",
138 MakeBooleanChecker ())
139 .AddAttribute (
"Holdtimes",
"Times the forwarding Interval to purge the route.",
142 MakeUintegerChecker<uint32_t> ())
143 .AddAttribute (
"WeightedFactor",
"WeightedFactor for the settling time if Weighted Settling Time is enabled",
146 MakeDoubleChecker<double> ())
147 .AddAttribute (
"EnableRouteAggregation",
"Enables Weighted Settling Time for the updates before advertising",
151 MakeBooleanChecker ())
152 .AddAttribute (
"RouteAggregationTime",
"Time to aggregate updates before sending them out (in seconds)",
200 m_advRoutingTable (),
202 m_periodicUpdateTimer (
Timer::CANCEL_ON_DESTROY)
218 iter->first->Close ();
264 std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
269 <<
", Packet id: " << p->
GetUid () <<
", Destination address in Packet: " << dst);
272 for (std::map<Ipv4Address, RoutingTableEntry>::iterator rmItr = removedAddresses.begin ();
273 rmItr != removedAddresses.end (); ++rmItr)
275 rmItr->second.SetEntriesChanged (
true);
276 rmItr->second.SetSeqNo (rmItr->second.GetSeqNo () + 1);
279 if (!removedAddresses.empty ())
289 if (rt.GetHop () == 1)
291 route = rt.GetRoute ();
294 <<
" to neighboring destination "
312 <<
" to destination " << dst <<
" via "
313 << rt.GetNextHop ());
327 uint32_t iif = (oif ?
m_ipv4->GetInterfaceForDevice (oif) : -1);
340 UnicastForwardCallback ucb,
357 UnicastForwardCallback ucb,
364 <<
" on interface " << idev->GetAddress ()
374 int32_t iif =
m_ipv4->GetInterfaceForDevice (idev);
414 if (lcb.
IsNull () ==
false)
417 lcb (p, header, iif);
422 NS_LOG_ERROR (
"Unable to deliver packet locally due to null callback " << p->
GetUid () <<
" from " << origin);
432 ucb (route,packet,header);
444 if (
m_ipv4->IsDestinationAddress (dst, iif))
446 if (lcb.
IsNull () ==
false)
449 lcb (p, header, iif);
453 NS_LOG_ERROR (
"Unable to deliver packet locally due to null callback " << p->
GetUid () <<
" from " << origin);
468 <<
" via nexthop neighbor " << toDst.
GetNextHop ());
469 ucb (route,p,header);
474 <<
" as there is no route to forward it.");
508 int32_t
interface =
m_ipv4->GetInterfaceForAddress (addr);
509 if (oif ==
m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
536 uint32_t packetSize = packet->GetSize ();
538 <<
" and packet id: " << packet->GetUid ());
540 for (; packetSize > 0; packetSize = packetSize - 12)
544 packet->RemoveHeader (dsdvHeader);
551 if (dsdvHeader.
GetDst () == interface.GetLocal ())
555 NS_LOG_DEBUG (
"Sent Dsdv update back to the same Destination, "
556 "with infinite metric. Time left to send fwd update: "
562 NS_LOG_DEBUG (
"Received update for my address. Discarding this.");
572 << sender <<
" to " << receiver <<
". Details are: Destination: " << dsdvHeader.
GetDst () <<
", Seq No: "
577 if (permanentTableVerifier ==
false)
586 m_ipv4->GetAddress (
m_ipv4->GetInterfaceForAddress (receiver), 0),
600 NS_LOG_DEBUG (
"Discarding this update as this route is not present in "
601 "main routing table and received with infinite metric");
609 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
611 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
613 NS_LOG_DEBUG (
"ADV table routes are:" << i->second.GetDestination ());
621 if (dsdvHeader.
GetDstSeqno () > advTableEntry.GetSeqNo ())
626 NS_LOG_DEBUG (
"Canceling the timer to update route with better seq number");
629 if (dsdvHeader.
GetHopCount () != advTableEntry.GetHop ())
631 advTableEntry.SetSeqNo (dsdvHeader.
GetDstSeqno ());
633 advTableEntry.SetFlag (
VALID);
634 advTableEntry.SetEntriesChanged (
true);
635 advTableEntry.SetNextHop (sender);
637 NS_LOG_DEBUG (
"Received update with better sequence number and changed metric.Waiting for WST");
639 advTableEntry.SetSettlingTime (tempSettlingtime);
641 <<
"s as there is no event running for this route");
652 advTableEntry.SetSeqNo (dsdvHeader.
GetDstSeqno ());
654 advTableEntry.SetFlag (
VALID);
655 advTableEntry.SetEntriesChanged (
true);
656 advTableEntry.SetNextHop (sender);
659 NS_LOG_DEBUG (
"Route with better sequence number and same metric received. Advertised without WST");
662 else if (dsdvHeader.
GetDstSeqno () == advTableEntry.GetSeqNo ())
664 if (dsdvHeader.
GetHopCount () < advTableEntry.GetHop ())
669 NS_LOG_DEBUG (
"Canceling any existing timer to update route with same sequence number "
670 "and better hop count");
672 advTableEntry.SetSeqNo (dsdvHeader.
GetDstSeqno ());
674 advTableEntry.SetFlag (
VALID);
675 advTableEntry.SetEntriesChanged (
true);
676 advTableEntry.SetNextHop (sender);
679 advTableEntry.SetSettlingTime (tempSettlingtime);
681 <<
" as there is no current event running for this route");
699 if (advTableEntry.GetNextHop () == sender)
707 NS_LOG_DEBUG (
"Received update with same seq number and "
708 "same/worst metric for, " << dsdvHeader.
GetDst () <<
". Discarding the update.");
718 NS_LOG_DEBUG (dsdvHeader.
GetDst () <<
" : Received update with old seq number. Discarding the update.");
723 NS_LOG_DEBUG (
"Route with infinite metric received for "
724 << dsdvHeader.
GetDst () <<
" from " << sender);
726 if (sender == advTableEntry.GetNextHop ())
728 NS_LOG_DEBUG (
"Triggering an update for this unreachable route:");
729 std::map<Ipv4Address, RoutingTableEntry> dstsWithNextHopSrc;
732 advTableEntry.SetSeqNo (dsdvHeader.
GetDstSeqno ());
733 advTableEntry.SetEntriesChanged (
true);
735 for (std::map<Ipv4Address, RoutingTableEntry>::iterator i = dstsWithNextHopSrc.begin (); i
736 != dstsWithNextHopSrc.end (); ++i)
738 i->second.SetSeqNo (i->second.GetSeqNo () + 1);
739 i->second.SetEntriesChanged (
true);
751 " : Discard this link break update as it was received from a different neighbor "
752 "and I can reach the destination");
757 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
774 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
783 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
785 NS_LOG_LOGIC (
"Destination: " << i->second.GetDestination ()
786 <<
" SeqNo:" << i->second.GetSeqNo () <<
" HopCount:"
787 << i->second.GetHop () + 1);
791 dsdvHeader.
SetDst (i->second.GetDestination ());
794 temp.SetFlag (
VALID);
795 temp.SetEntriesChanged (
false);
797 if (!(temp.GetSeqNo () % 2))
803 NS_LOG_DEBUG (
"Deleted this route from the advertised table");
809 NS_LOG_DEBUG (
"EventID " << event.GetUid () <<
" associated with "
810 << temp.GetDestination () <<
" has not expired, waiting in adv table");
817 dsdvHeader.
SetDst (
m_ipv4->GetAddress (1, 0).GetLocal ());
820 NS_LOG_DEBUG (
"Adding my update as well to the packet");
835 <<
" with packet id : " << packet->
GetUid () <<
" and packet Size: " << packet->
GetSize ());
839 NS_LOG_FUNCTION (
"Update not sent as there are no updates to be triggered");
847 std::map<Ipv4Address, RoutingTableEntry> removedAddresses, allRoutes;
851 if (allRoutes.empty ())
862 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
865 if (i->second.GetHop () == 0)
868 dsdvHeader.
SetDst (
m_ipv4->GetAddress (1,0).GetLocal ());
869 dsdvHeader.
SetDstSeqno (i->second.GetSeqNo () + 2);
878 dsdvHeader.
SetDst (i->second.GetDestination ());
883 NS_LOG_DEBUG (
"Forwarding the update for " << i->first);
887 <<
", LifeTime: " << i->second.GetLifeTime ().GetSeconds ());
889 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator rmItr = removedAddresses.begin (); rmItr
890 != removedAddresses.end (); ++rmItr)
893 removedHeader.
SetDst (rmItr->second.GetDestination ());
894 removedHeader.
SetDstSeqno (rmItr->second.GetSeqNo () + 1);
895 removedHeader.
SetHopCount (rmItr->second.GetHop () + 1);
897 NS_LOG_DEBUG (
"Update for removed record is: Destination: " << removedHeader.
GetDst ()
901 socket->
Send (packet);
947 <<
" interface is up");
950 if (iface.GetLocal () ==
Ipv4Address (
"127.0.0.1"))
998 NS_LOG_FUNCTION (
this <<
" interface " << i <<
" address " << address);
1036 if (l3->GetNAddresses (i))
1093 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1095 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1105 <<
" to neighboring destination "
1138 NS_LOG_DEBUG (
"Output device doesn't match. Dropped.");
1146 ucb (route,p,header);
1174 NS_LOG_DEBUG (
"Calculated weightedTime:" << weightedTime.GetSeconds ());
1175 return weightedTime;
1184 NS_LOG_FUNCTION (
"Merging advertised table changes with main table before sending out periodic update");
1185 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1187 if (allRoutes.size () > 0)
1189 for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = allRoutes.begin (); i != allRoutes.end (); ++i)
1205 NS_LOG_DEBUG (
"Event currently running. Cannot Merge Routing Tables");
void Start()
Start protocol operation.
static TypeId GetTypeId(void)
static const uint32_t DSDV_PORT
UDP Port for DSDV control traffic.
static Ipv4Mask GetOnes(void)
keep track of time values and allow control of global simulation resolution
int64_t AssignStreams(int64_t stream)
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
void SetEntriesChanged(bool entriesChanged)
#define NS_LOG_FUNCTION(parameters)
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw socket per each IP interface, map socket -> iface address (IP + mask)
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
Ipv4Mask GetMask(void) const
Ipv4Address GetNextHop() const
bool EnableRouteAggregation
void MergeTriggerPeriodicUpdates()
Time m_periodicUpdateInterval
bool EnableBuffering
Flag that is used to enable or disable buffering.
bool AnyRunningEvent(Ipv4Address address)
Ipv4Header GetIpv4Header() const
Ipv4Address GetLocal(void) const
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
ErrorCallback m_ecb
Error callback for own packets.
a class to represent an Ipv4 address mask
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
void AddPacketTag(const Tag &tag) const
static TypeId GetTypeId()
uint64_t GetUid(void) const
EventId GetEventId(Ipv4Address address)
uint32_t GetSerializedSize() const
bool EnableWST
Flag that is used to enable or disable Weighted Settling Time.
TypeId GetInstanceTypeId() const
#define NS_ASSERT(condition)
void SetFlag(RouteFlags flag)
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSeqNo() const
void SetMaxPacketsPerDst(uint32_t len)
uint32_t GetSize(void) const
bool IsMulticast(void) const
virtual void NotifyInterfaceDown(uint32_t interface)
virtual void DoDispose(void)
void GetListOfAllRoutes(std::map< Ipv4Address, RoutingTableEntry > &allRoutes)
double m_weightedFactor
This is the wighted factor to determine the weighted settling time.
TAG_BUFFER_INLINE uint32_t ReadU32(void)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route)
NS_OBJECT_ENSURE_REGISTERED(DsdvHeader)
int32_t oif
Positive if output device is fixed in RouteOutput.
bool Update(RoutingTableEntry &rt)
Ptr< Ipv4Route > GetRoute() const
a polymophic address class
void SendPeriodicUpdate()
Broadcasts the entire routing table for every PeriodicUpdateInterval.
bool GetEnableRAFlag() const
void SetSource(Ipv4Address src)
Ptr< NetDevice > GetOutputDevice(void) const
bool ForceDeleteIpv4Event(Ipv4Address address)
double GetSeconds(void) const
bool PeekPacketTag(Tag &tag) const
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find socket with local interface address iface.
hold objects of type ns3::Time
void SetGateway(Ipv4Address gw)
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
Hold an unsigned integer type.
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
void SetSeqNo(uint32_t sequenceNumber)
void Purge(std::map< Ipv4Address, RoutingTableEntry > &removedAddresses)
Delete all outdated entries if Lifetime is expired.
bool IsBroadcast(void) const
uint32_t m_maxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
void Deserialize(TagBuffer i)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
uint32_t GetUid(void) const
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Ipv4Address GetSource(void) const
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
static TypeId GetTypeId(void)
#define NS_LOG_LOGIC(msg)
Time GetSettlingTime() const
void SetMaxQueueLen(uint32_t len)
UnicastForwardCallback m_scb
Unicast callback for own packets.
Ptr< Packet > Copy(void) const
tag a set of bytes in a packet
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.
virtual ~RoutingProtocol()
Implement the Ipv4 layer.
Time GetSettlingTime(Ipv4Address dst)
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet untill we find a route.
void LookForQueuedPackets(void)
Look for any queued packets to send them out.
Time m_routeAggregationTime
Parameter that holds the route aggregation time interval.
static InetSocketAddress ConvertFrom(const Address &address)
bool Dequeue(Ipv4Address dst, QueueEntry &entry)
Return first found (the earliest) entry for given destination.
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 DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
UnicastForwardCallback GetUnicastForwardCallback() const
Time m_maxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
bool AddRoute(RoutingTableEntry &r)
void RecvDsdv(Ptr< Socket > socket)
Receive and process dsdv control packet.
void SetQueueTimeout(Time t)
bool GetEnableBufferFlag() const
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Ipv4Address m_mainAddress
Nodes IP address.
void SetOutputDevice(Ptr< NetDevice > outputDevice)
static Ipv4Address GetLoopback(void)
void SendTriggeredUpdate()
Sends trigger update from a node.
uint32_t m_maxQueuedPacketsPerDst
The maximum number of packets that we allow per destination to buffer.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
void Serialize(TagBuffer i) const
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
#define NS_ASSERT_MSG(condition, message)
void GetListOfDestinationWithNextHop(Ipv4Address nxtHp, std::map< Ipv4Address, RoutingTableEntry > &dstList)
bool DeleteIpv4Event(Ipv4Address address)
Ipv4Address GetDestination(void) const
void Send(Ptr< Ipv4Route >, Ptr< const Packet >, const Ipv4Header &)
Ipv4 addresses are stored in host order in this class.
Ipv4Address GetBroadcast(void) const
bool DeleteRoute(Ipv4Address dst)
a class to store IPv4 address information on an interface
void SetEnableRAFlag(bool f)
an identifier for simulation events.
Ptr< NetDevice > m_lo
Loopback device used to defer route requests until a route is found.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
bool RemovePacketTag(Tag &tag)
#define NS_LOG_DEBUG(msg)
bool GetEntriesChanged() const
Ptr< const Packet > GetPacket() const
Tag used by DSDV implementation.
void SetEnableBufferFlag(bool f)
Abstract base class for IPv4 routing protocols.
Ipv4Address GetDestination() const
void Clear()
Delete all entries from routing table.
DeferredRouteOutputTag(int32_t o=-1)
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
Ptr< Ipv4 > m_ipv4
IP protocol.
void Setholddowntime(Time t)
RoutingTable m_advRoutingTable
Advertised Routing table for the node.
#define NS_LOG_ERROR(msg)
virtual void NotifyInterfaceUp(uint32_t interface)
void Print(std::ostream &os) const
bool AddIpv4Event(Ipv4Address address, EventId id)
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
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.
Timer m_periodicUpdateTimer
Timer to trigger periodic updates from a node.
uint32_t GetSize()
Number of entries.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual int Close(void)=0
Close a socket.
RoutingTable m_routingTable
Main Routing table for the node.
void Drop(Ptr< const Packet >, const Ipv4Header &, Socket::SocketErrno)
Notify that packet is dropped for some reason.
Time GetDelayLeft(void) const
Hold an floating point type.
void SetAttribute(std::string name, const AttributeValue &value)
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
static Time GetMaximumSimulationTime(void)
std::ostream * GetStream(void)
void AddHeader(const Header &header)
bool Find(Ipv4Address dst)
Finds whether a packet with destination dst exists in the queue.
void SetDestination(Ipv4Address dest)
Callback< void, Ptr< Ipv4Route >, Ptr< const Packet >, const Ipv4Header & > UnicastForwardCallback
bool Enqueue(QueueEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue...