olsr: (fixes #2760) do not use unicast-bound sockets to receive broadcasts
This commit is contained in:
@@ -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
|
||||
------------
|
||||
|
||||
@@ -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 ())
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user