34 #include "ns3/boolean.h"
35 #include "ns3/double.h"
36 #include "ns3/inet-socket-address.h"
38 #include "ns3/trace-source-accessor.h"
39 #include "ns3/udp-socket-factory.h"
40 #include "ns3/uinteger.h"
78 static TypeId tid =
TypeId(
"ns3::dsdv::DeferredRouteOutputTag")
92 return sizeof(int32_t);
105 void Print(std::ostream& os)
const override
107 os <<
"DeferredRouteOutputTag: output interface = " <<
oif;
115 TypeId(
"ns3::dsdv::RoutingProtocol")
117 .SetGroupName(
"Dsdv")
119 .AddAttribute(
"PeriodicUpdateInterval",
120 "Periodic interval between exchange of full routing tables among nodes.",
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)",
130 .AddAttribute(
"MaxQueueLen",
131 "Maximum number of packets that we allow a routing protocol to buffer.",
134 MakeUintegerChecker<uint32_t>())
135 .AddAttribute(
"MaxQueuedPacketsPerDst",
136 "Maximum number of packets that we allow per destination to buffer.",
139 MakeUintegerChecker<uint32_t>())
140 .AddAttribute(
"MaxQueueTime",
141 "Maximum time packets can be queued (in seconds)",
147 "Enables buffering of data packets if no route to destination is available",
154 "Enables Weighted Settling Time for the updates before advertising",
158 .AddAttribute(
"Holdtimes",
159 "Times the forwarding Interval to purge the route.",
162 MakeUintegerChecker<uint32_t>())
165 "WeightedFactor for the settling time if Weighted Settling Time is enabled",
168 MakeDoubleChecker<double>())
169 .AddAttribute(
"EnableRouteAggregation",
170 "Enables Weighted Settling Time for the updates before advertising",
175 .AddAttribute(
"RouteAggregationTime",
176 "Time to aggregate updates before sending them out (in seconds)",
231 m_periodicUpdateTimer(
Timer::CANCEL_ON_DESTROY)
246 iter->first->Close();
256 <<
", Time: " <<
Now().
As(unit)
257 <<
", Local time: " <<
m_ipv4->GetObject<
Node>()->GetLocalTime().As(unit)
258 <<
", DSDV Routing table" << std::endl;
297 std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
302 <<
", Destination address in Packet: " << dst);
305 for (
auto rmItr = removedAddresses.begin(); rmItr != removedAddresses.end(); ++rmItr)
307 rmItr->second.SetEntriesChanged(
true);
308 rmItr->second.SetSeqNo(rmItr->second.GetSeqNo() + 1);
311 if (!removedAddresses.empty())
327 NS_LOG_DEBUG(
"A route exists from " << route->GetSource()
328 <<
" to neighboring destination "
329 << route->GetDestination());
330 if (oif && route->GetOutputDevice() != oif)
345 NS_LOG_DEBUG(
"A route exists from " << route->GetSource() <<
" to destination "
347 if (oif && route->GetOutputDevice() != oif)
360 uint32_t iif = (oif ?
m_ipv4->GetInterfaceForDevice(oif) : -1);
406 int32_t iif =
m_ipv4->GetInterfaceForDevice(idev);
452 NS_LOG_ERROR(
"Unable to deliver packet locally due to null callback "
453 << p->
GetUid() <<
" from " << origin);
463 ucb(route, packet, header);
475 if (
m_ipv4->IsDestinationAddress(dst, iif))
484 NS_LOG_ERROR(
"Unable to deliver packet locally due to null callback "
485 << p->
GetUid() <<
" from " << origin);
492 if (!
m_ipv4->IsForwarding(iif))
507 <<
" from " << header.
GetSource() <<
" via nexthop neighbor "
509 ucb(route, p, header);
513 NS_LOG_LOGIC(
"Drop packet " << p->
GetUid() <<
" as there is no route to forward it.");
547 int32_t
interface =
m_ipv4->GetInterfaceForAddress(addr);
548 if (oif ==
m_ipv4->GetNetDevice(
static_cast<uint32_t
>(interface)))
557 rt->SetSource(j->second.GetLocal());
561 rt->SetOutputDevice(
m_lo);
577 <<
" and packet id: " << packet->
GetUid());
590 if (dsdvHeader.
GetDst() == interface.GetLocal())
594 NS_LOG_DEBUG(
"Sent Dsdv update back to the same Destination, "
595 "with infinite metric. Time left to send fwd update: "
601 NS_LOG_DEBUG(
"Received update for my address. Discarding this.");
611 << sender <<
" to " << receiver <<
". Details are: Destination: "
617 bool permanentTableVerifier =
619 if (!permanentTableVerifier)
628 m_ipv4->GetAddress(
m_ipv4->GetInterfaceForAddress(receiver), 0),
642 NS_LOG_DEBUG(
"Discarding this update as this route is not present in "
643 "main routing table and received with infinite metric");
651 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
653 for (
auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
655 NS_LOG_DEBUG(
"ADV table routes are:" << i->second.GetDestination());
668 NS_LOG_DEBUG(
"Canceling the timer to update route with better seq number");
679 NS_LOG_DEBUG(
"Received update with better sequence number and changed "
680 "metric.Waiting for WST");
685 <<
" as there is no event running for this route");
705 NS_LOG_DEBUG(
"Route with better sequence number and same metric received. "
706 "Advertised without WST");
717 NS_LOG_DEBUG(
"Canceling any existing timer to update route with same "
719 "and better hop count");
731 <<
" as there is no current event running for this route");
758 NS_LOG_DEBUG(
"Received update with same seq number and "
759 "same/worst metric for, "
760 << dsdvHeader.
GetDst() <<
". Discarding the update.");
772 <<
" : Received update with old seq number. Discarding the update.");
778 <<
" from " << sender);
782 NS_LOG_DEBUG(
"Triggering an update for this unreachable route:");
783 std::map<Ipv4Address, RoutingTableEntry> dstsWithNextHopSrc;
790 for (
auto i = dstsWithNextHopSrc.begin(); i != dstsWithNextHopSrc.end(); ++i)
792 i->second.SetSeqNo(i->second.GetSeqNo() + 1);
793 i->second.SetEntriesChanged(
true);
805 "was received from a different neighbor "
806 "and I can reach the destination");
811 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
829 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
837 for (
auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
839 NS_LOG_LOGIC(
"Destination: " << i->second.GetDestination()
840 <<
" SeqNo:" << i->second.GetSeqNo()
841 <<
" HopCount:" << i->second.GetHop() + 1);
843 if (i->second.GetEntriesChanged() &&
846 dsdvHeader.
SetDst(i->second.GetDestination());
858 NS_LOG_DEBUG(
"Deleted this route from the advertised table");
864 NS_LOG_DEBUG(
"EventID " << event.GetUid() <<
" associated with "
866 <<
" has not expired, waiting in adv table");
890 << dsdvHeader.
GetDst() <<
" with packet id : " << packet->
GetUid()
891 <<
" and packet Size: " << packet->
GetSize());
895 NS_LOG_FUNCTION(
"Update not sent as there are no updates to be triggered");
903 std::map<Ipv4Address, RoutingTableEntry> removedAddresses;
904 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
908 if (allRoutes.empty())
918 for (
auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
921 if (i->second.GetHop() == 0)
934 dsdvHeader.
SetDst(i->second.GetDestination());
943 <<
", LifeTime: " << i->second.GetLifeTime().As(
Time::S));
945 for (
auto rmItr = removedAddresses.begin(); rmItr != removedAddresses.end(); ++rmItr)
948 removedHeader.
SetDst(rmItr->second.GetDestination());
949 removedHeader.
SetDstSeqno(rmItr->second.GetSeqNo() + 1);
950 removedHeader.
SetHopCount(rmItr->second.GetHop() + 1);
952 NS_LOG_DEBUG(
"Update for removed record is: Destination: "
956 socket->
Send(packet);
1022 iface.GetBroadcast(),
1026 iface.GetBroadcast(),
1100 if (l3->GetNAddresses(i))
1153 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1155 for (
auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
1165 NS_LOG_LOGIC(
"A route exists from " << route->GetSource()
1166 <<
" to neighboring destination "
1167 << route->GetDestination());
1175 NS_LOG_LOGIC(
"A route exists from " << route->GetSource() <<
" to destination "
1176 << route->GetDestination() <<
" via "
1195 if (tag.
oif != -1 && tag.
oif !=
m_ipv4->GetInterfaceForDevice(route->GetOutputDevice()))
1206 ucb(route, p, header);
1239 return weightedTime;
1249 "Merging advertised table changes with main table before sending out periodic update");
1250 std::map<Ipv4Address, RoutingTableEntry> allRoutes;
1252 if (!allRoutes.empty())
1254 for (
auto i = allRoutes.begin(); i != allRoutes.end(); ++i)
1266 <<
" with main routing Table");
1272 NS_LOG_DEBUG(
"Event currently running. Cannot Merge Routing Tables");
double f(double x, void *params)
a polymophic address class
bool IsNull() const
Check for null implementation.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
An identifier for simulation events.
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetLoopback()
static Ipv4Address GetAny()
a class to store IPv4 address information on an interface
Ipv4Mask GetMask() const
Get the network mask.
Ipv4Address GetLocal() const
Get the local address.
Ipv4Address GetBroadcast() const
Get the broadcast address.
Implement the IPv4 layer.
a class to represent an Ipv4 address mask
static Ipv4Mask GetOnes()
Abstract base class for IPv4 routing protocols.
virtual Address GetAddress() const =0
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
virtual void DoDispose()
Destructor implementation.
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
void AddHeader(const Header &header)
Add header to this packet.
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Ptr< Packet > Copy() const
performs a COW copy of the packet.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
uint64_t GetUid() const
Returns the packet's Uid.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
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.
static Time Now()
Return the current simulation virtual time.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
static Time GetMaximumSimulationTime()
Get the maximum representable simulation time.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
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...
virtual int Close()=0
Close a socket.
SocketErrno
Enumeration of the possible errors returned by a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
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 int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
TAG_BUFFER_INLINE uint32_t ReadU32()
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
tag a set of bytes in a packet
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Unit
The unit to use to interpret a number representing time.
A simple virtual Timer class.
Time GetDelayLeft() const
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
static TypeId GetTypeId()
Get the type ID.
Hold an unsigned integer type.
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.
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.
~RoutingProtocol() override
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.
void SetHop(uint32_t hopCount)
Set hop.
void SetLifeTime(Time lifeTime)
Set lifetime.
bool GetEntriesChanged() const
Get entries changed.
void SetEntriesChanged(bool entriesChanged)
Set entries changed indicator.
Time GetSettlingTime() const
Get settling time.
Ipv4Address GetDestination() const
Get destination IP address.
Ptr< Ipv4Route > GetRoute() const
Get route.
void SetSettlingTime(Time settlingTime)
Set settling time.
void SetNextHop(Ipv4Address nextHop)
Set next hop.
uint32_t GetSeqNo() const
Get sequence number.
Time GetLifeTime() const
Get lifetime.
void SetFlag(RouteFlags flag)
Set route flags.
uint32_t GetHop() const
Get hop.
Ipv4Address GetNextHop() const
Get next hop.
void SetSeqNo(uint32_t sequenceNumber)
Set sequence number.
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
bool ForceDeleteIpv4Event(Ipv4Address address)
Force delete an update waiting for settling time to complete as a better update to same destination w...
void Clear()
Delete all entries from routing table.
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
void Setholddowntime(Time t)
Set hold down time (time until an invalid route may be deleted)
bool DeleteIpv4Event(Ipv4Address address)
Clear up the entry from the map after the event is completed.
bool Update(RoutingTableEntry &rt)
Updating the routing Table with routing table entry rt.
void GetListOfDestinationWithNextHop(Ipv4Address nxtHp, std::map< Ipv4Address, RoutingTableEntry > &dstList)
Lookup list of addresses for which nxtHp is the next Hop address.
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table.
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
EventId GetEventId(Ipv4Address address)
Get the EventId associated with that address.
bool AddIpv4Event(Ipv4Address address, EventId id)
Add an event for a destination address so that the update to for that destination is sent after the e...
bool AnyRunningEvent(Ipv4Address address)
Force delete an update waiting for settling time to complete as a better update to same destination w...
void Purge(std::map< Ipv4Address, RoutingTableEntry > &removedAddresses)
Delete all outdated entries if Lifetime is expired.
void GetListOfAllRoutes(std::map< Ipv4Address, RoutingTableEntry > &allRoutes)
Lookup list of all addresses in the routing table.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#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.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
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...
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
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.