Implement IPTTL socket option for UDP
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
@@ -486,6 +487,35 @@ Ipv4L3Protocol::Send (Ptr<Packet> packet,
|
||||
|
||||
m_identification ++;
|
||||
|
||||
// Set TTL to 1 if it is a broadcast packet of any type. Otherwise,
|
||||
// possibly override the default TTL if the packet is tagged
|
||||
SocketIpTtlTag tag;
|
||||
bool found = packet->PeekTag (tag);
|
||||
uint8_t socketTtl = tag.GetTtl ();
|
||||
packet->RemoveTag (tag);
|
||||
|
||||
if (destination.IsBroadcast ())
|
||||
{
|
||||
ipHeader.SetTtl (1);
|
||||
}
|
||||
else if (found)
|
||||
{
|
||||
ipHeader.SetTtl (socketTtl);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ifaceIndex = 0;
|
||||
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
|
||||
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
|
||||
{
|
||||
Ptr<Ipv4Interface> outInterface = *ifaceIter;
|
||||
if (destination.IsSubnetDirectedBroadcast (
|
||||
outInterface->GetNetworkMask ()))
|
||||
{
|
||||
ipHeader.SetTtl (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (destination.IsBroadcast ())
|
||||
{
|
||||
uint32_t ifaceIndex = 0;
|
||||
|
||||
@@ -52,24 +52,14 @@ UdpSocket::GetTypeId (void)
|
||||
UintegerValue (0xffffffffl),
|
||||
MakeUintegerAccessor (&UdpSocket::m_rcvBufSize),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("DontRoute",
|
||||
"Bypass normal routing; destination must be local",
|
||||
BooleanValue (false),
|
||||
MakeBooleanAccessor (&UdpSocket::m_dontRoute),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("AcceptConn",
|
||||
"Whether a socket is enabled for listening (read-only)",
|
||||
BooleanValue (false),
|
||||
MakeBooleanAccessor (&UdpSocket::m_acceptConn),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("IpTtl",
|
||||
"Time-to-live for unicast IP packets",
|
||||
UintegerValue (64),
|
||||
"socket-specific TTL for unicast IP packets (if non-zero)",
|
||||
UintegerValue (0),
|
||||
MakeUintegerAccessor (&UdpSocket::m_ipTtl),
|
||||
MakeUintegerChecker<uint8_t> ())
|
||||
.AddAttribute ("IpMulticastTtl",
|
||||
"Time-to-live for multicast IP packets",
|
||||
UintegerValue (64),
|
||||
"socket-specific TTL for multicast IP packets (if non-zero)",
|
||||
UintegerValue (0),
|
||||
MakeUintegerAccessor (&UdpSocket::m_ipMulticastTtl),
|
||||
MakeUintegerChecker<uint8_t> ())
|
||||
;
|
||||
@@ -232,7 +222,6 @@ int
|
||||
UdpSocket::Connect(const Address & address)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << address);
|
||||
Ipv4Route routeToDest;
|
||||
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
|
||||
m_defaultAddress = transport.GetIpv4 ();
|
||||
m_defaultPort = transport.GetPort ();
|
||||
@@ -303,8 +292,6 @@ UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << p << dest << port);
|
||||
|
||||
Ipv4Route routeToDest;
|
||||
|
||||
if (m_endPoint == 0)
|
||||
{
|
||||
if (Bind () == -1)
|
||||
@@ -329,6 +316,26 @@ UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
|
||||
uint32_t localIfIndex;
|
||||
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
|
||||
|
||||
// Locally override the IP TTL for this socket
|
||||
// We cannot directly modify the TTL at this stage, so we set a Packet tag
|
||||
// The destination can be either multicast, unicast/anycast, or
|
||||
// either all-hosts broadcast or limited (subnet-directed) broadcast.
|
||||
// For the latter two broadcast types, the TTL will later be set to one
|
||||
// irrespective of what is set in these socket options. So, this tagging
|
||||
// may end up setting the TTL of a limited broadcast packet to be
|
||||
// the same as a unicast, but it will be fixed further down the stack
|
||||
if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
|
||||
{
|
||||
SocketIpTtlTag tag;
|
||||
tag.SetTtl (m_ipMulticastTtl);
|
||||
p->AddTag (tag);
|
||||
}
|
||||
else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
|
||||
{
|
||||
SocketIpTtlTag tag;
|
||||
tag.SetTtl (m_ipTtl);
|
||||
p->AddTag (tag);
|
||||
}
|
||||
//
|
||||
// If dest is sent to the limited broadcast address (all ones),
|
||||
// convert it to send a copy of the packet out of every interface
|
||||
|
||||
@@ -92,8 +92,6 @@ private:
|
||||
|
||||
// Socket options (UdpSocket attributes)
|
||||
uint32_t m_rcvBufSize;
|
||||
bool m_dontRoute;
|
||||
bool m_acceptConn;
|
||||
uint8_t m_ipTtl;
|
||||
uint8_t m_ipMulticastTtl;
|
||||
|
||||
|
||||
@@ -301,4 +301,52 @@ SocketRxAddressTag::GetAddress (void) const
|
||||
return m_address;
|
||||
}
|
||||
|
||||
SocketIpTtlTag::SocketIpTtlTag ()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SocketIpTtlTag::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = ns3::Tag::AllocateUid<SocketIpTtlTag> ("SocketIpTtlTag.ns3");
|
||||
return uid;
|
||||
}
|
||||
|
||||
void
|
||||
SocketIpTtlTag::Print (std::ostream &os) const
|
||||
{
|
||||
os << "ttl="<< m_ttl;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SocketIpTtlTag::GetSerializedSize (void) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SocketIpTtlTag::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
// for local use in stack only
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SocketIpTtlTag::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
// for local use in stack only
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SocketIpTtlTag::SetTtl (uint8_t ttl)
|
||||
{
|
||||
m_ttl = ttl;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SocketIpTtlTag::GetTtl (void) const
|
||||
{
|
||||
return m_ttl;
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
@@ -378,6 +378,26 @@ private:
|
||||
Address m_address;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief This class implements a tag that carries the socket-specific
|
||||
* TTL of a packet to the IP layer
|
||||
*/
|
||||
class SocketIpTtlTag : public Tag
|
||||
{
|
||||
public:
|
||||
SocketIpTtlTag ();
|
||||
static uint32_t GetUid (void);
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator i) const;
|
||||
uint32_t Deserialize (Buffer::Iterator i);
|
||||
|
||||
void SetTtl (uint8_t ttl);
|
||||
uint8_t GetTtl (void) const;
|
||||
private:
|
||||
uint8_t m_ttl;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* SOCKET_H */
|
||||
|
||||
Reference in New Issue
Block a user