diff --git a/src/internet-node/ipv4-end-point-demux.cc b/src/internet-node/ipv4-end-point-demux.cc index 20dc0d271..8ad8c6a3f 100644 --- a/src/internet-node/ipv4-end-point-demux.cc +++ b/src/internet-node/ipv4-end-point-demux.cc @@ -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 incomingInterface) { NS_LOG_FUNCTION; uint32_t genericity = 3; @@ -187,28 +194,32 @@ Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport, for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) { - NS_LOG_LOGIC ("Ipv4EndPointDemux::Lookup against " << - (*i)->GetLocalAddress () - << ":" << - (*i)->GetLocalPort () - << " " << - (*i)->GetPeerAddress () - << ":" - << (*i)->GetPeerPort ()); - + 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 ())) { diff --git a/src/internet-node/ipv4-end-point-demux.h b/src/internet-node/ipv4-end-point-demux.h index e45a6267b..5ffff86bd 100644 --- a/src/internet-node/ipv4-end-point-demux.h +++ b/src/internet-node/ipv4-end-point-demux.h @@ -25,6 +25,7 @@ #include #include #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 incomingInterface); Ipv4EndPoint *Allocate (void); Ipv4EndPoint *Allocate (Ipv4Address address); diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 50fd2e39a..4691b977a 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -546,11 +546,13 @@ Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protoc NS_LOG_LOGIC ("Packet from " << from); uint32_t index = 0; + Ptr 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 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 incomingInterface) { NS_LOG_FUNCTION; NS_LOG_PARAM ("(" << &p << ", " << &ip << ")"); Ptr demux = m_node->QueryInterface (Ipv4L4Demux::iid); Ptr protocol = demux->GetProtocol (ip.GetProtocol ()); - protocol->Receive (p, ip.GetSource (), ip.GetDestination ()); + protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface); } void diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index 001852571..bea82707e 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -227,7 +227,7 @@ private: Packet const &packet, Ipv4Header &ipHeader, Ptr device); - void ForwardUp (Packet p, Ipv4Header const&ip); + void ForwardUp (Packet p, Ipv4Header const&ip, Ptr incomingInterface); uint32_t AddIpv4Interface (Ptr interface); void SetupLoopback (void); diff --git a/src/internet-node/ipv4-l4-protocol.h b/src/internet-node/ipv4-l4-protocol.h index e54dfcc97..6f1dad714 100644 --- a/src/internet-node/ipv4-l4-protocol.h +++ b/src/internet-node/ipv4-l4-protocol.h @@ -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 incomingInterface) = 0; protected: virtual void DoDispose (void); private: diff --git a/src/internet-node/udp-l4-protocol.cc b/src/internet-node/udp-l4-protocol.cc index 8d7bd395f..cbf8cbf52 100644 --- a/src/internet-node/udp-l4-protocol.cc +++ b/src/internet-node/udp-l4-protocol.cc @@ -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 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++) { diff --git a/src/internet-node/udp-l4-protocol.h b/src/internet-node/udp-l4-protocol.h index 46fe62761..10502e10c 100644 --- a/src/internet-node/udp-l4-protocol.h +++ b/src/internet-node/udp-l4-protocol.h @@ -85,7 +85,8 @@ public: // inherited from Ipv4L4Protocol virtual void Receive(Packet& p, Ipv4Address const &source, - Ipv4Address const &destination); + Ipv4Address const &destination, + Ptr interface); protected: virtual void DoDispose (void); private: diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 9f4f6744d..e890f87ec 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -332,3 +332,132 @@ UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port) } } //namespace ns3 + + +#ifdef RUN_SELF_TESTS + +#include "ns3/test.h" +#include "ns3/internet-node.h" +#include "ns3/socket-factory.h" +#include "ns3/udp.h" +#include "ns3/simulator.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/drop-tail-queue.h" +#include + +namespace ns3 { + +class UdpSocketTest: public Test +{ + Packet m_receivedPacket; + Packet m_receivedPacket2; + +public: + virtual bool RunTests (void); + UdpSocketTest (); + + void ReceivePacket (Ptr socket, const Packet &packet, const Address &from); + void ReceivePacket2 (Ptr socket, const Packet &packet, const Address &from); +}; + + +UdpSocketTest::UdpSocketTest () + : Test ("UdpSocket") {} + + +void UdpSocketTest::ReceivePacket (Ptr socket, const Packet &packet, const Address &from) +{ + m_receivedPacket = packet; +} + +void UdpSocketTest::ReceivePacket2 (Ptr socket, const Packet &packet, const Address &from) +{ + m_receivedPacket2 = packet; +} + +bool +UdpSocketTest::RunTests (void) +{ + bool result = true; + + // Create topology + + // Receiver Node + Ptr rxNode = Create (); + Ptr rxDev = Create (rxNode); + rxDev->AddQueue(Create ()); + Ptr ipv4 = rxNode->QueryInterface (Ipv4::iid); + 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); + + // Sender Node + Ptr txNode = Create (); + Ptr txDev = Create (txNode); + txDev->AddQueue(Create ()); + ipv4 = txNode->QueryInterface (Ipv4::iid); + 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 channel = Create (); + rxDev->Attach (channel); + txDev->Attach (channel); + + + // Create the UDP sockets + Ptr rxSocketFactory = rxNode->QueryInterface (Udp::iid); + Ptr rxSocket = rxSocketFactory->CreateSocket (); + NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.2"), 1234)), 0); + rxSocket->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket, this)); + + Ptr txSocketFactory = txNode->QueryInterface (Udp::iid); + Ptr txSocket = txSocketFactory->CreateSocket (); + + // ------ Now the tests ------------ + + // Unicast test + m_receivedPacket = Packet (); + NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("10.0.0.1"), 1234), + Packet (123)), 0); + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_receivedPacket.GetSize (), 123); + + + // Simple broadcast test + + m_receivedPacket = Packet (); + NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234), + Packet (123)), 0); + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_receivedPacket.GetSize (), 123); + + // 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 rxSocket2 = rxSocketFactory->CreateSocket (); + rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket2, this)); + NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0); + + m_receivedPacket = Packet (); + m_receivedPacket2 = Packet (); + NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234), + Packet (123)), 0); + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_receivedPacket.GetSize (), 123); + NS_TEST_ASSERT_EQUAL (m_receivedPacket2.GetSize (), 123); + + return result; +} + + +static UdpSocketTest gUdpSocketTest; + +}; // namespace ns3 + +#endif /* RUN_SELF_TESTS */ diff --git a/src/simulator/simulator.cc b/src/simulator/simulator.cc index 6ee0340fd..e00f548b5 100644 --- a/src/simulator/simulator.cc +++ b/src/simulator/simulator.cc @@ -762,7 +762,7 @@ SimulatorTests::cbaz5c (const int &, const int &, const int &, const int &, cons bool SimulatorTests::RunOneTest (void) { - bool ok = true; + bool result = true; m_a = true; m_b = false; m_c = true; @@ -772,26 +772,16 @@ SimulatorTests::RunOneTest (void) Simulator::Schedule (MicroSeconds (11), &SimulatorTests::B, this, 2); m_idC = Simulator::Schedule (MicroSeconds (12), &SimulatorTests::C, this, 3); - if (m_idC.IsExpired ()) - { - ok = false; - } - if (a.IsExpired ()) - { - ok = false; - } + NS_TEST_ASSERT (!m_idC.IsExpired ()); + NS_TEST_ASSERT (!a.IsExpired ()); Simulator::Cancel (a); - if (!a.IsExpired ()) - { - ok = false; - } + NS_TEST_ASSERT (a.IsExpired ()); Simulator::Run (); - - if (!m_a || !m_b || !m_c || !m_d) - { - ok = false; - } - return ok; + NS_TEST_ASSERT (m_a); + NS_TEST_ASSERT (m_b); + NS_TEST_ASSERT (m_c); + NS_TEST_ASSERT (m_d); + return result; } void SimulatorTests::RunTestsConst (void) const @@ -870,24 +860,25 @@ SimulatorTests::RunTestsConst (void) const bool SimulatorTests::RunTests (void) { - bool ok = true; + bool result = true; + Simulator::Destroy (); Simulator::SetLinkedList (); if (!RunOneTest ()) { - ok = false; + result = false; } Simulator::Destroy (); Simulator::SetBinaryHeap (); if (!RunOneTest ()) { - ok = false; + result = false; } Simulator::Destroy (); Simulator::SetStdMap (); if (!RunOneTest ()) { - ok = false; + result = false; } Simulator::Destroy (); @@ -1018,36 +1009,26 @@ SimulatorTests::RunTests (void) EventId nowId = Simulator::ScheduleNow (&foo0); m_destroyId = Simulator::ScheduleDestroy (&SimulatorTests::destroy, this); - if (m_destroyId.IsExpired ()) - { - ok = false; - } + NS_TEST_ASSERT (!m_destroyId.IsExpired ()); Simulator::Run (); m_destroy = false; Simulator::Destroy (); - if (!m_destroy) - { - ok = false; - } + NS_TEST_ASSERT (m_destroy); EventId anId = Simulator::ScheduleNow (&foo0); EventId anotherId = anId; - if (anId.IsExpired () || anotherId.IsExpired ()) - { - ok = false; - } + NS_TEST_ASSERT (!(anId.IsExpired () || anotherId.IsExpired ())); + Simulator::Remove (anId); - if (!anId.IsExpired () || !anotherId.IsExpired ()) - { - ok = false; - } + NS_TEST_ASSERT (anId.IsExpired ()); + NS_TEST_ASSERT (anotherId.IsExpired ()); Simulator::Run (); Simulator::Destroy (); - return ok; + return result; } SimulatorTests gSimulatorTests;