olsr: (fixes #2760) do not use unicast-bound sockets to receive broadcasts

This commit is contained in:
Tommaso Pecorella
2017-06-26 19:53:09 +02:00
parent acb364c299
commit 11f470b1ff
3 changed files with 62 additions and 11 deletions

View File

@@ -107,6 +107,7 @@ Bugs fixed
- Bug 2744 - 802.11n/ac with RTS/CTS is crashing for a large number of nodes
- Bug 2758 - IPv4 sockets bound to unicast receive also subnet-directed broadcasts
- Bug 2759 - Packets sent to broadcast address are converted to subnet-directed broadcast
- Bug 2760 - OLSR uses unicast-bound sockets to receive broadcasts
Known issues
------------

View File

@@ -47,6 +47,7 @@
#include "ns3/enum.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/ipv4-header.h"
#include "ns3/ipv4-packet-info-tag.h"
/********** Useful macros **********/
@@ -240,12 +241,17 @@ void RoutingProtocol::DoDispose ()
m_hnaRoutingTable = 0;
m_routingTableAssociation = 0;
for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_socketAddresses.begin ();
iter != m_socketAddresses.end (); iter++)
if (m_recvSocket)
{
m_recvSocket->Close ();
}
for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_sendSockets.begin ();
iter != m_sendSockets.end (); iter++)
{
iter->first->Close ();
}
m_socketAddresses.clear ();
m_sendSockets.clear ();
Ipv4RoutingProtocol::DoDispose ();
}
@@ -340,7 +346,23 @@ void RoutingProtocol::DoInitialize ()
continue;
}
// Create a socket to listen only on this interface
// Create a socket to listen on all the interfaces
if (m_recvSocket == 0)
{
m_recvSocket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId ());
m_recvSocket->SetAllowBroadcast (true);
InetSocketAddress inetAddr (Ipv4Address::GetAny (), OLSR_PORT_NUMBER);
m_recvSocket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvOlsr, this));
if (m_recvSocket->Bind (inetAddr))
{
NS_FATAL_ERROR ("Failed to bind() OLSR socket");
}
m_recvSocket->SetRecvPktInfo (true);
m_recvSocket->ShutdownSend ();
}
// Create a socket to send packets from this specific interfaces
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId ());
socket->SetAllowBroadcast (true);
@@ -351,7 +373,8 @@ void RoutingProtocol::DoInitialize ()
NS_FATAL_ERROR ("Failed to bind() OLSR socket");
}
socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
m_socketAddresses[socket] = m_ipv4->GetAddress (i, 0);
socket->SetRecvPktInfo (true);
m_sendSockets[socket] = m_ipv4->GetAddress (i, 0);
canRunOlsr = true;
}
@@ -386,9 +409,33 @@ RoutingProtocol::RecvOlsr (Ptr<Socket> socket)
Address sourceAddress;
receivedPacket = socket->RecvFrom (sourceAddress);
Ipv4PacketInfoTag interfaceInfo;
if (!receivedPacket->RemovePacketTag (interfaceInfo))
{
NS_ABORT_MSG ("No incoming interface on OLSR message, aborting.");
}
uint32_t incomingIf = interfaceInfo.GetRecvIf ();
Ptr<Node> node = this->GetObject<Node> ();
Ptr<NetDevice> dev = node->GetDevice (incomingIf);
uint32_t recvInterfaceIndex = m_ipv4->GetInterfaceForDevice (dev);
if (m_interfaceExclusions.find (recvInterfaceIndex) != m_interfaceExclusions.end ())
{
return;
}
InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
Ipv4Address receiverIfaceAddr = m_socketAddresses[socket].GetLocal ();
int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress (senderIfaceAddr);
if (interfaceForAddress != -1)
{
NS_LOG_LOGIC ("Ignoring a packet sent by myself.");
return;
}
Ipv4Address receiverIfaceAddr = m_ipv4->GetAddress (recvInterfaceIndex, 0).GetLocal ();
NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
<< senderIfaceAddr << " to " << receiverIfaceAddr);
@@ -1588,10 +1635,11 @@ RoutingProtocol::SendPacket (Ptr<Packet> packet,
// Send it
for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
m_socketAddresses.begin (); i != m_socketAddresses.end (); i++)
m_sendSockets.begin (); i != m_sendSockets.end (); i++)
{
Ptr<Packet> pkt = packet->Copy ();
Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
i->first->SendTo (packet, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
i->first->SendTo (pkt, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
}
}
@@ -3082,8 +3130,8 @@ RoutingProtocol::AssignStreams (int64_t stream)
bool
RoutingProtocol::IsMyOwnAddress (const Ipv4Address & a) const
{
for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j;
for (j = m_sendSockets.begin (); j != m_sendSockets.end (); ++j)
{
Ipv4InterfaceAddress iface = j->second;
if (a == iface.GetLocal ())

View File

@@ -764,7 +764,9 @@ private:
// One socket per interface, each bound to that interface's address
// (reason: for OLSR Link Sensing we need to know on which interface
// HELLO messages arrive)
std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_socketAddresses; //!< Container of sockets and the interfaces they are opened onto.
std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_sendSockets; //!< Container of sockets and the interfaces they are opened onto.
Ptr<Socket> m_recvSocket; //!< Receiving socket.
/// Rx packet trace.
TracedCallback <const PacketHeader &, const MessageList &> m_rxPacketTrace;