Fix a regression in handling of broadcast packets and UDP sockets (closes bug #51).
This commit is contained in:
@@ -85,6 +85,7 @@ Ipv4EndPointDemux::Allocate (void)
|
||||
}
|
||||
Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port);
|
||||
m_endPoints.push_back (endPoint);
|
||||
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ Ipv4EndPoint *
|
||||
Ipv4EndPointDemux::Allocate (Ipv4Address address)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << address << ")");
|
||||
NS_LOG_PARAM ("(" << this << ", " << address << ")");
|
||||
uint16_t port = AllocateEphemeralPort ();
|
||||
if (port == 0)
|
||||
{
|
||||
@@ -101,6 +102,7 @@ Ipv4EndPointDemux::Allocate (Ipv4Address address)
|
||||
}
|
||||
Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
|
||||
m_endPoints.push_back (endPoint);
|
||||
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
@@ -115,7 +117,7 @@ Ipv4EndPoint *
|
||||
Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << address << ", " << port << ")");
|
||||
NS_LOG_PARAM ("(" << this << ", " << address << ", " << port << ")");
|
||||
if (LookupLocal (address, port))
|
||||
{
|
||||
NS_LOG_WARN ("Duplicate address/port; failing.");
|
||||
@@ -123,6 +125,7 @@ Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
|
||||
}
|
||||
Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
|
||||
m_endPoints.push_back (endPoint);
|
||||
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
@@ -150,6 +153,9 @@ Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
|
||||
Ipv4EndPoint *endPoint = new Ipv4EndPoint (localAddress, localPort);
|
||||
endPoint->SetPeer (peerAddress, peerPort);
|
||||
m_endPoints.push_back (endPoint);
|
||||
|
||||
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
|
||||
|
||||
return endPoint;
|
||||
}
|
||||
|
||||
@@ -175,7 +181,8 @@ Ipv4EndPointDemux::DeAllocate (Ipv4EndPoint *endPoint)
|
||||
*/
|
||||
Ipv4EndPointDemux::EndPoints
|
||||
Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport,
|
||||
Ipv4Address saddr, uint16_t sport)
|
||||
Ipv4Address saddr, uint16_t sport,
|
||||
Ptr<Ipv4Interface> incomingInterface)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
uint32_t genericity = 3;
|
||||
@@ -187,19 +194,32 @@ Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport,
|
||||
|
||||
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
|
||||
{
|
||||
NS_LOG_DEBUG ("Looking at endpoint dport=" << (*i)->GetLocalPort ()
|
||||
<< " daddr=" << (*i)->GetLocalAddress ()
|
||||
<< " sport=" << (*i)->GetPeerPort ()
|
||||
<< " saddr=" << (*i)->GetPeerAddress ());
|
||||
if ((*i)->GetLocalPort () != dport)
|
||||
{
|
||||
NS_LOG_LOGIC ("Skipping endpoint " << &(*i)
|
||||
<< " because endpoint dport "
|
||||
<< (*i)->GetLocalPort ()
|
||||
<< " does not match packet dport " << dport);
|
||||
continue;
|
||||
}
|
||||
bool isBroadcast =
|
||||
(daddr.IsBroadcast () ||
|
||||
daddr.IsSubnetDirectedBroadcast (incomingInterface->GetNetworkMask ()));
|
||||
NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
|
||||
|
||||
NS_LOG_LOGIC ("Local address matches: " <<
|
||||
bool ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ()));
|
||||
bool ((*i)->GetLocalAddress () == daddr || isBroadcast));
|
||||
NS_LOG_LOGIC ("Peer port matches: " <<
|
||||
bool ((*i)->GetPeerPort () == sport || sport == 0));
|
||||
bool ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0));
|
||||
NS_LOG_LOGIC ("Peer address matches: " <<
|
||||
bool ((*i)->GetPeerAddress () == saddr ||
|
||||
(*i)->GetPeerAddress () == Ipv4Address::GetAny ()));
|
||||
|
||||
if ( ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ())
|
||||
if ( ((*i)->GetLocalAddress () == daddr || isBroadcast)
|
||||
&& ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0)
|
||||
&& ((*i)->GetPeerAddress () == saddr || (*i)->GetPeerAddress () == Ipv4Address::GetAny ()))
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ipv4-interface.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -43,7 +44,8 @@ public:
|
||||
EndPoints Lookup (Ipv4Address daddr,
|
||||
uint16_t dport,
|
||||
Ipv4Address saddr,
|
||||
uint16_t sport);
|
||||
uint16_t sport,
|
||||
Ptr<Ipv4Interface> incomingInterface);
|
||||
|
||||
Ipv4EndPoint *Allocate (void);
|
||||
Ipv4EndPoint *Allocate (Ipv4Address address);
|
||||
|
||||
@@ -546,11 +546,13 @@ Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protoc
|
||||
NS_LOG_LOGIC ("Packet from " << from);
|
||||
|
||||
uint32_t index = 0;
|
||||
Ptr<Ipv4Interface> ipv4Interface;
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
||||
i != m_interfaces.end ();
|
||||
i++)
|
||||
{
|
||||
if ((*i)->GetDevice () == device)
|
||||
ipv4Interface = *i;
|
||||
if (ipv4Interface->GetDevice () == device)
|
||||
{
|
||||
m_rxTrace (p, index);
|
||||
break;
|
||||
@@ -572,7 +574,7 @@ Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protoc
|
||||
}
|
||||
|
||||
NS_LOG_LOGIC ("Forward up");
|
||||
ForwardUp (packet, ipHeader);
|
||||
ForwardUp (packet, ipHeader, ipv4Interface);
|
||||
}
|
||||
|
||||
|
||||
@@ -745,14 +747,15 @@ Ipv4L3Protocol::Forwarding (
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip)
|
||||
Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip,
|
||||
Ptr<Ipv4Interface> incomingInterface)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << &p << ", " << &ip << ")");
|
||||
|
||||
Ptr<Ipv4L4Demux> demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
|
||||
Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
|
||||
protocol->Receive (p, ip.GetSource (), ip.GetDestination ());
|
||||
protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -227,7 +227,7 @@ private:
|
||||
Packet const &packet,
|
||||
Ipv4Header &ipHeader,
|
||||
Ptr<NetDevice> device);
|
||||
void ForwardUp (Packet p, Ipv4Header const&ip);
|
||||
void ForwardUp (Packet p, Ipv4Header const&ip, Ptr<Ipv4Interface> incomingInterface);
|
||||
uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
|
||||
void SetupLoopback (void);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define IPV4_L4_PROTOCOL_H
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ipv4-interface.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -59,13 +60,15 @@ public:
|
||||
* \param p packet to forward up
|
||||
* \param source source address of packet received
|
||||
* \param destination address of packet received
|
||||
* \param incomingInterface the Ipv4Interface on which the packet arrived
|
||||
*
|
||||
* Called from lower-level layers to send the packet up
|
||||
* in the stack.
|
||||
*/
|
||||
virtual void Receive(Packet& p,
|
||||
Ipv4Address const &source,
|
||||
Ipv4Address const &destination) = 0;
|
||||
Ipv4Address const &destination,
|
||||
Ptr<Ipv4Interface> incomingInterface) = 0;
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
private:
|
||||
|
||||
@@ -123,8 +123,9 @@ UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
|
||||
|
||||
void
|
||||
UdpL4Protocol::Receive(Packet& packet,
|
||||
Ipv4Address const &source,
|
||||
Ipv4Address const &destination)
|
||||
Ipv4Address const &source,
|
||||
Ipv4Address const &destination,
|
||||
Ptr<Ipv4Interface> interface)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << &packet << ", " << source << ", " << destination <<
|
||||
@@ -134,7 +135,7 @@ UdpL4Protocol::Receive(Packet& packet,
|
||||
packet.RemoveHeader (udpHeader);
|
||||
Ipv4EndPointDemux::EndPoints endPoints =
|
||||
m_endPoints->Lookup (destination, udpHeader.GetDestination (),
|
||||
source, udpHeader.GetSource ());
|
||||
source, udpHeader.GetSource (), interface);
|
||||
for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
|
||||
endPoint != endPoints.end (); endPoint++)
|
||||
{
|
||||
|
||||
@@ -85,7 +85,8 @@ public:
|
||||
// inherited from Ipv4L4Protocol
|
||||
virtual void Receive(Packet& p,
|
||||
Ipv4Address const &source,
|
||||
Ipv4Address const &destination);
|
||||
Ipv4Address const &destination,
|
||||
Ptr<Ipv4Interface> interface);
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
private:
|
||||
|
||||
@@ -410,13 +410,13 @@ UdpSocketTest::RunTests (void)
|
||||
|
||||
|
||||
// Create the UDP sockets
|
||||
Ptr<SocketFactory> socketFactory = rxNode->QueryInterface<SocketFactory> (Udp::iid);
|
||||
Ptr<Socket> rxSocket = socketFactory->CreateSocket ();
|
||||
NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (1234)), 0);
|
||||
Ptr<SocketFactory> rxSocketFactory = rxNode->QueryInterface<SocketFactory> (Udp::iid);
|
||||
Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
|
||||
NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.2"), 1234)), 0);
|
||||
rxSocket->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket, this));
|
||||
|
||||
socketFactory = txNode->QueryInterface<SocketFactory> (Udp::iid);
|
||||
Ptr<Socket> txSocket = socketFactory->CreateSocket ();
|
||||
Ptr<SocketFactory> txSocketFactory = txNode->QueryInterface<SocketFactory> (Udp::iid);
|
||||
Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
|
||||
|
||||
// ------ Now the tests ------------
|
||||
|
||||
@@ -440,9 +440,9 @@ UdpSocketTest::RunTests (void)
|
||||
|
||||
// When receiving broadcast packets, all sockets sockets bound to
|
||||
// the address/port should receive a copy of the same packet.
|
||||
Ptr<Socket> rxSocket2 = socketFactory->CreateSocket ();
|
||||
Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
|
||||
rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket2, this));
|
||||
NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("10.0.0.1"), 1234)), 0);
|
||||
NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0);
|
||||
|
||||
m_receivedPacket = Packet ();
|
||||
m_receivedPacket2 = Packet ();
|
||||
|
||||
Reference in New Issue
Block a user