Fix a regression in handling of broadcast packets and UDP sockets (closes bug #51).

This commit is contained in:
Gustavo J. A. M. Carneiro
2007-09-24 11:00:08 +01:00
parent 75c461c8f9
commit bd51ec2c87
8 changed files with 54 additions and 24 deletions

View File

@@ -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 ()))
{

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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:

View File

@@ -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++)
{

View File

@@ -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:

View File

@@ -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 ();