--- a/src/internet-node/ipv4-end-point-demux.cc Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/ipv4-end-point-demux.cc Wed Feb 13 17:37:43 2008 +0000
@@ -83,14 +83,14 @@
NS_LOG_WARN ("Ephemeral port allocation failed.");
return 0;
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port);
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port, Ipv4Address::GetAny ());
m_endPoints.push_back (endPoint);
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
return endPoint;
}
Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address address)
+Ipv4EndPointDemux::Allocate (Ipv4Address address, Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address);
@@ -100,7 +100,7 @@
NS_LOG_WARN ("Ephemeral port allocation failed.");
return 0;
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port, localInterface);
m_endPoints.push_back (endPoint);
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
return endPoint;
@@ -110,20 +110,22 @@
Ipv4EndPointDemux::Allocate (uint16_t port)
{
NS_LOG_FUNCTION;
- return Allocate (Ipv4Address::GetAny (), port);
+ NS_LOG_PARAMS (this << port);
+
+ return Allocate (Ipv4Address::GetAny (), port, Ipv4Address::GetAny ());
}
Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
+Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
- NS_LOG_PARAMS (this << address << port);
+ NS_LOG_PARAMS (this << address << port << localInterface);
if (LookupLocal (address, port))
{
NS_LOG_WARN ("Duplicate address/port; failing.");
return 0;
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port, localInterface);
m_endPoints.push_back (endPoint);
NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
return endPoint;
@@ -131,7 +133,8 @@
Ipv4EndPoint *
Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort)
+ Ipv4Address peerAddress, uint16_t peerPort,
+ Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
@@ -147,7 +150,7 @@
return 0;
}
}
- Ipv4EndPoint *endPoint = new Ipv4EndPoint (localAddress, localPort);
+ Ipv4EndPoint *endPoint = new Ipv4EndPoint (localAddress, localPort, localInterface);
endPoint->SetPeer (peerAddress, peerPort);
m_endPoints.push_back (endPoint);
@@ -213,17 +216,34 @@
bool isBroadcast =
(daddr.IsBroadcast () ||
daddr.IsSubnetDirectedBroadcast (incomingInterface->GetNetworkMask ()));
- NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
+ Ipv4Address incomingInterfaceAddr = incomingInterface->GetAddress ();
- NS_LOG_LOGIC ("Local address matches: " <<
- bool ((*i)->GetLocalAddress () == daddr || isBroadcast));
+ NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast
+ << " localInterface="<< (*i)->GetLocalInterface ());
+ bool localAddressMatches;
+ if (isBroadcast)
+ {
+ if ((*i)->GetLocalInterface () == Ipv4Address::GetAny ())
+ {
+ localAddressMatches = true;
+ }
+ else
+ {
+ localAddressMatches = ((*i)->GetLocalInterface () == incomingInterfaceAddr);
+ }
+ }
+ else
+ {
+ localAddressMatches = ((*i)->GetLocalAddress () == daddr);
+ }
+ NS_LOG_LOGIC ("Local address matches: " << localAddressMatches);
NS_LOG_LOGIC ("Peer port matches: " <<
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 || isBroadcast)
+ if ( localAddressMatches
&& ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0)
&& ((*i)->GetPeerAddress () == saddr || (*i)->GetPeerAddress () == Ipv4Address::GetAny ()))
{
--- a/src/internet-node/ipv4-end-point-demux.h Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/ipv4-end-point-demux.h Wed Feb 13 17:37:43 2008 +0000
@@ -48,13 +48,13 @@
Ptr<Ipv4Interface> incomingInterface);
Ipv4EndPoint *Allocate (void);
- Ipv4EndPoint *Allocate (Ipv4Address address);
+ Ipv4EndPoint *Allocate (Ipv4Address address, Ipv4Address localInterface);
Ipv4EndPoint *Allocate (uint16_t port);
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
+ Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface);
Ipv4EndPoint *Allocate (Ipv4Address localAddress,
uint16_t localPort,
Ipv4Address peerAddress,
- uint16_t peerPort);
+ uint16_t peerPort, Ipv4Address localInterface);
void DeAllocate (Ipv4EndPoint *endPoint);
--- a/src/internet-node/ipv4-end-point.cc Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/ipv4-end-point.cc Wed Feb 13 17:37:43 2008 +0000
@@ -24,11 +24,12 @@
namespace ns3 {
-Ipv4EndPoint::Ipv4EndPoint (Ipv4Address address, uint16_t port)
+Ipv4EndPoint::Ipv4EndPoint (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
: m_localAddr (address),
m_localPort (port),
m_peerAddr (Ipv4Address::GetAny ()),
- m_peerPort (0)
+ m_peerPort (0),
+ m_localInterface (localInterface)
{}
Ipv4EndPoint::~Ipv4EndPoint ()
{
@@ -50,6 +51,17 @@
m_localAddr = address;
}
+Ipv4Address Ipv4EndPoint::GetLocalInterface (void) const
+{
+ return m_localInterface;
+}
+
+void
+Ipv4EndPoint::SetLocalInterface (Ipv4Address localInterface)
+{
+ m_localInterface = localInterface;
+}
+
uint16_t
Ipv4EndPoint::GetLocalPort (void)
{
--- a/src/internet-node/ipv4-end-point.h Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/ipv4-end-point.h Wed Feb 13 17:37:43 2008 +0000
@@ -33,7 +33,7 @@
class Ipv4EndPoint {
public:
- Ipv4EndPoint (Ipv4Address address, uint16_t port);
+ Ipv4EndPoint (Ipv4Address address, uint16_t port, Ipv4Address localInterface);
~Ipv4EndPoint ();
Ipv4Address GetLocalAddress (void);
@@ -41,6 +41,8 @@
uint16_t GetLocalPort (void);
Ipv4Address GetPeerAddress (void);
uint16_t GetPeerPort (void);
+ Ipv4Address GetLocalInterface (void) const;
+ void SetLocalInterface (Ipv4Address localInterface);
void SetPeer (Ipv4Address address, uint16_t port);
@@ -56,6 +58,11 @@
uint16_t m_peerPort;
Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
Callback<void> m_destroyCallback;
+
+ // If the corresponding socket is bound to a specific local
+ // interface, m_localInterface contains that interface's ipv4
+ // address, else it contains the value Ipv4Address::GetAny ().
+ Ipv4Address m_localInterface;
};
}; // namespace ns3
--- a/src/internet-node/ipv4-l3-protocol.cc Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/ipv4-l3-protocol.cc Wed Feb 13 17:37:43 2008 +0000
@@ -497,8 +497,8 @@
}
}
- NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
- "Interface not found for IP address");
+ NS_FATAL_ERROR ("Ipv4L3Protocol::FindInterfaceForAddr (): "
+ "Interface not found for IP address " << addr);
return 0;
}
--- a/src/internet-node/tcp-l4-protocol.cc Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/tcp-l4-protocol.cc Wed Feb 13 17:37:43 2008 +0000
@@ -353,11 +353,11 @@
}
Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address address)
+TcpL4Protocol::Allocate (Ipv4Address address, Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address);
- return m_endPoints->Allocate (address);
+ return m_endPoints->Allocate (address, localInterface);
}
Ipv4EndPoint *
@@ -369,21 +369,23 @@
}
Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
+TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address << port);
- return m_endPoints->Allocate (address, port);
+ return m_endPoints->Allocate (address, port, localInterface);
}
Ipv4EndPoint *
TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort)
+ Ipv4Address peerAddress, uint16_t peerPort,
+ Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
return m_endPoints->Allocate (localAddress, localPort,
- peerAddress, peerPort);
+ peerAddress, peerPort,
+ localInterface);
}
void
--- a/src/internet-node/tcp-l4-protocol.h Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/tcp-l4-protocol.h Wed Feb 13 17:37:43 2008 +0000
@@ -60,11 +60,12 @@
Ptr<Socket> CreateSocket (void);
Ipv4EndPoint *Allocate (void);
- Ipv4EndPoint *Allocate (Ipv4Address address);
+ Ipv4EndPoint *Allocate (Ipv4Address address, Ipv4Address localInterface);
Ipv4EndPoint *Allocate (uint16_t port);
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
+ Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface);
Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort);
+ Ipv4Address peerAddress, uint16_t peerPort,
+ Ipv4Address localInterface);
void DeAllocate (Ipv4EndPoint *endPoint);
--- a/src/internet-node/tcp-socket.cc Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/tcp-socket.cc Wed Feb 13 17:37:43 2008 +0000
@@ -155,6 +155,14 @@
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
+ Ipv4Address localInterface = Ipv4Address::GetAny ();
+ if (ipv4 != Ipv4Address::GetAny ())
+ {
+ Ptr<Ipv4> ipv4_api = m_node->GetObject<Ipv4> ();
+ // Assert that the given address matches an existing local interface
+ NS_ASSERT (ipv4_api->FindInterfaceForAddr (ipv4) != 0);
+ localInterface = ipv4;
+ }
if (ipv4 == Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_tcp->Allocate ();
@@ -167,12 +175,12 @@
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
- m_endPoint = m_tcp->Allocate (ipv4);
+ m_endPoint = m_tcp->Allocate (ipv4, localInterface);
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_tcp->Allocate (ipv4, port);
+ m_endPoint = m_tcp->Allocate (ipv4, port, localInterface);
NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
}
--- a/src/internet-node/udp-l4-protocol.cc Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/udp-l4-protocol.cc Wed Feb 13 17:37:43 2008 +0000
@@ -80,11 +80,11 @@
}
Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address address)
+UdpL4Protocol::Allocate (Ipv4Address address, Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address);
- return m_endPoints->Allocate (address);
+ return m_endPoints->Allocate (address, localInterface);
}
Ipv4EndPoint *
@@ -96,20 +96,21 @@
}
Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
+UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port, Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << address << port);
- return m_endPoints->Allocate (address, port);
+ return m_endPoints->Allocate (address, port, localInterface);
}
Ipv4EndPoint *
UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort)
+ Ipv4Address peerAddress, uint16_t peerPort,
+ Ipv4Address localInterface)
{
NS_LOG_FUNCTION;
NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
return m_endPoints->Allocate (localAddress, localPort,
- peerAddress, peerPort);
+ peerAddress, peerPort, localInterface);
}
void
--- a/src/internet-node/udp-l4-protocol.h Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/udp-l4-protocol.h Wed Feb 13 17:37:43 2008 +0000
@@ -56,11 +56,13 @@
Ptr<Socket> CreateSocket (void);
Ipv4EndPoint *Allocate (void);
- Ipv4EndPoint *Allocate (Ipv4Address address);
+ Ipv4EndPoint *Allocate (Ipv4Address address, Ipv4Address localInterface);
Ipv4EndPoint *Allocate (uint16_t port);
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
+ Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port,
+ Ipv4Address localInterface);
Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
- Ipv4Address peerAddress, uint16_t peerPort);
+ Ipv4Address peerAddress, uint16_t peerPort,
+ Ipv4Address localInterface);
void DeAllocate (Ipv4EndPoint *endPoint);
--- a/src/internet-node/udp-socket.cc Mon Feb 11 14:46:44 2008 +0000
+++ b/src/internet-node/udp-socket.cc Wed Feb 13 17:37:43 2008 +0000
@@ -127,6 +127,16 @@
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
+
+ Ipv4Address localInterface = Ipv4Address::GetAny ();
+ if (ipv4 != Ipv4Address::GetAny ())
+ {
+ Ptr<Ipv4> ipv4_api = m_node->GetObject<Ipv4> ();
+ // Assert that the given address matches an existing local interface
+ NS_ASSERT (ipv4_api->FindInterfaceForAddr (ipv4) != 0);
+ localInterface = ipv4;
+ }
+
if (ipv4 == Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_udp->Allocate ();
@@ -137,11 +147,11 @@
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
- m_endPoint = m_udp->Allocate (ipv4);
+ m_endPoint = m_udp->Allocate (ipv4, localInterface);
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_udp->Allocate (ipv4, port);
+ m_endPoint = m_udp->Allocate (ipv4, port, localInterface);
}
return FinishBind ();
@@ -388,36 +398,56 @@
// Receiver Node
Ptr<Node> rxNode = CreateObject<InternetNode> ();
- Ptr<PointToPointNetDevice> rxDev = CreateObject<PointToPointNetDevice> (rxNode);
- rxDev->AddQueue(CreateObject<DropTailQueue> ());
- Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
- uint32_t netdev_idx = ipv4->AddInterface (rxDev);
- ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.1"));
- ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
- ipv4->SetUp (netdev_idx);
+ Ptr<PointToPointNetDevice> rxDev1, rxDev2;
+ { // first interface
+ rxDev1 = CreateObject<PointToPointNetDevice> (rxNode);
+ rxDev1->AddQueue(CreateObject<DropTailQueue> ());
+ Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
+ uint32_t netdev_idx = ipv4->AddInterface (rxDev1);
+ ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.1"));
+ ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+ ipv4->SetUp (netdev_idx);
+ }
+ { // second interface
+ rxDev2 = CreateObject<PointToPointNetDevice> (rxNode);
+ rxDev2->AddQueue(CreateObject<DropTailQueue> ());
+ Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
+ uint32_t netdev_idx = ipv4->AddInterface (rxDev2);
+ ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.1.1"));
+ ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+ ipv4->SetUp (netdev_idx);
+ }
+
// Sender Node
Ptr<Node> txNode = CreateObject<InternetNode> ();
- Ptr<PointToPointNetDevice> txDev = CreateObject<PointToPointNetDevice> (txNode);
- txDev->AddQueue(CreateObject<DropTailQueue> ());
- ipv4 = txNode->GetObject<Ipv4> ();
- netdev_idx = ipv4->AddInterface (txDev);
- ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.2"));
- ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
- ipv4->SetUp (netdev_idx);
+ Ptr<PointToPointNetDevice> txDev;
+ {
+ txDev = CreateObject<PointToPointNetDevice> (txNode);
+ txDev->AddQueue(CreateObject<DropTailQueue> ());
+ Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
+ uint32_t netdev_idx = ipv4->AddInterface (txDev);
+ ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.2"));
+ ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+ ipv4->SetUp (netdev_idx);
+ }
// link the two nodes
Ptr<PointToPointChannel> channel = CreateObject<PointToPointChannel> ();
- rxDev->Attach (channel);
+ rxDev1->Attach (channel);
txDev->Attach (channel);
// Create the UDP sockets
Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<Udp> ();
Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
- NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.2"), 1234)), 0);
+ NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.1"), 1234)), 0);
rxSocket->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket, this));
+ Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
+ rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket2, this));
+ NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("10.0.1.1"), 1234)), 0);
+
Ptr<SocketFactory> txSocketFactory = txNode->GetObject<Udp> ();
Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
@@ -425,26 +455,33 @@
// Unicast test
m_receivedPacket = Create<Packet> ();
+ m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("10.0.0.1"), 1234),
Create<Packet> (123)), 0);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
+ NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0); // second interface should receive it
// Simple broadcast test
m_receivedPacket = Create<Packet> ();
+ m_receivedPacket2 = Create<Packet> ();
NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234),
Create<Packet> (123)), 0);
Simulator::Run ();
NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
+ // second socket should not receive it (it is bound specifically to the second interface's address
+ NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0);
// Broadcast test with multiple receiving sockets
// When receiving broadcast packets, all sockets sockets bound to
- // the address/port should receive a copy of the same packet.
- Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
+ // the address/port should receive a copy of the same packet -- if
+ // the socket address matches.
+ rxSocket2->Dispose ();
+ rxSocket2 = rxSocketFactory->CreateSocket ();
rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket2, this));
NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0);