socket update broke multicast
authorCraig Dowell <craigdo@ee.washington.edu>
Tue, 11 Sep 2007 18:29:26 -0700
changeset 1452 973c456d3684
parent 1451 e421081dd580
child 1453 5e9a0b9f30a9
socket update broke multicast
examples/csma-multicast.cc
src/internet-node/ipv4-impl.cc
src/internet-node/ipv4-impl.h
src/internet-node/udp-socket.cc
src/node/ipv4.cc
src/node/ipv4.h
src/routing/global-routing/global-route-manager-impl.cc
--- a/examples/csma-multicast.cc	Tue Sep 11 12:20:09 2007 -0700
+++ b/examples/csma-multicast.cc	Tue Sep 11 18:29:26 2007 -0700
@@ -85,19 +85,6 @@
   DebugComponentEnable("Ipv4LoopbackInterface");
 #endif
 
-  DebugComponentEnable("Channel");
-  DebugComponentEnable("CsmaChannel");
-  DebugComponentEnable("CsmaMulticast");
-  DebugComponentEnable("CsmaNetDevice");
-  DebugComponentEnable("OnOffApplication");
-  DebugComponentEnable("PacketSocket");
-  DebugComponentEnable("UdpSocket");
-  DebugComponentEnable("UdpL4Protocol");
-  DebugComponentEnable("Ipv4L3Protocol");
-  DebugComponentEnable("Ipv4StaticRouting");
-  DebugComponentEnable("Ipv4Interface");
-  DebugComponentEnable("ArpIpv4Interface");
-  DebugComponentEnable("Ipv4LoopbackInterface");
 //
 // Set up default values for the simulation.  Use the DefaultValue::Bind()
 // technique to tell the system what subclass of Queue to use.  The Bind
--- a/src/internet-node/ipv4-impl.cc	Tue Sep 11 12:20:09 2007 -0700
+++ b/src/internet-node/ipv4-impl.cc	Tue Sep 11 18:29:26 2007 -0700
@@ -201,6 +201,12 @@
   return m_ipv4->GetAddress (i);
 }
 
+bool
+Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const
+{
+  return m_ipv4->GetIfIndexForDestination (dest, ifIndex);
+}
+
 Ipv4Address 
 Ipv4Impl::GetSourceAddress (Ipv4Address destination) const
 {
--- a/src/internet-node/ipv4-impl.h	Tue Sep 11 12:20:09 2007 -0700
+++ b/src/internet-node/ipv4-impl.h	Tue Sep 11 18:29:26 2007 -0700
@@ -89,6 +89,8 @@
   virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
   virtual Ipv4Address GetAddress (uint32_t i) const;
   virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const;
+  virtual bool GetIfIndexForDestination (Ipv4Address dest, 
+    uint32_t &ifIndex) const;
 
   virtual uint16_t GetMtu (uint32_t i) const;
   virtual bool IsUp (uint32_t i) const;
--- a/src/internet-node/udp-socket.cc	Tue Sep 11 12:20:09 2007 -0700
+++ b/src/internet-node/udp-socket.cc	Tue Sep 11 18:29:26 2007 -0700
@@ -186,11 +186,13 @@
 
   NS_DEBUG ("UdpSocket::Connect (): Updating local address");
 
-  if (GetIpv4RouteToDestination (m_node, routeToDest, m_defaultAddress) )
+  uint32_t localIfIndex;
+
+  Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+  
+  if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex))
     {
-      uint32_t localIfIndex = routeToDest.GetInterface ();
-      Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
-      m_endPoint->SetLocalAddress (ipv4->GetAddress(localIfIndex) );
+      m_endPoint->SetLocalAddress (ipv4->GetAddress(localIfIndex));
     }
 
   NS_DEBUG ("UdpSocket::Connect (): Local address is " << 
@@ -240,6 +242,7 @@
 
   if (!m_connected)
     {
+      NS_DEBUG("UdpSocket::DoSendTo (): Not connected");
       InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
       Ipv4Address ipv4 = transport.GetIpv4 ();
       uint16_t port = transport.GetPort ();
@@ -248,6 +251,7 @@
   else
     {
       // connected UDP socket must use default addresses
+      NS_DEBUG("UdpSocket::DoSendTo (): Connected");
       return DoSendTo (p, m_defaultAddress, m_defaultPort);
     }
 }
@@ -274,13 +278,17 @@
       m_errno = ERROR_SHUTDOWN;
       return -1;
     }
+
+  uint32_t localIfIndex;
+  Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+
   //
   // If dest is sent to the limited broadcast address (all ones),
   // convert it to send a copy of the packet out of every interface
   //
   if (dest.IsBroadcast ())
     {
-      Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+      NS_DEBUG("UdpSocket::DoSendTo (): Limited broadcast");
       for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
         {
           Ipv4Address addri = ipv4->GetAddress (i);
@@ -290,10 +298,9 @@
           NotifyDataSent (p.GetSize ());
         }
     }
-  else if (GetIpv4RouteToDestination (m_node, routeToDest, dest) )
+  else if (ipv4->GetIfIndexForDestination(dest, localIfIndex))
     {
-      uint32_t localIfIndex = routeToDest.GetInterface ();
-      Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+      NS_DEBUG("UdpSocket::DoSendTo (): Route exists");
       m_udp->Send (p, ipv4->GetAddress (localIfIndex), dest,
 		   m_endPoint->GetLocalPort (), port);
       NotifyDataSent (p.GetSize ());
@@ -301,6 +308,7 @@
     }
   else
    {
+      NS_DEBUG("UdpSocket::DoSendTo (): ERROR_NOROUTETOHOST");
       m_errno = ERROR_NOROUTETOHOST;
       return -1;
    }
--- a/src/node/ipv4.cc	Tue Sep 11 12:20:09 2007 -0700
+++ b/src/node/ipv4.cc	Tue Sep 11 18:29:26 2007 -0700
@@ -36,10 +36,10 @@
 {}
 
 uint32_t 
-GetIfIndexByIpv4Address (Ptr<Node> node, Ipv4Address a, Ipv4Mask amask)
+Ipv4::GetIfIndexByAddress (Ptr<Node> node, Ipv4Address a, Ipv4Mask amask)
 {
   Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
-  NS_ASSERT_MSG (ipv4, "GetIfIndexByIpv4Address:  No Ipv4 interface");
+  NS_ASSERT_MSG (ipv4, "Ipv4::GetIfIndexByAddress:  No Ipv4 interface");
   for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
     {
       if (ipv4->GetAddress (i).CombineMask(amask) == a.CombineMask(amask) )
@@ -48,17 +48,26 @@
         }
     }
   // Mapping not found
-  NS_ASSERT_MSG (false, "GetIfIndexByIpv4Address failed");
+  NS_ASSERT_MSG (false, "Ipv4::GetIfIndexByAddress failed");
   return 0;
 }
 
+//
+// XXX BUGBUG I don't think this is really the right approach here.  The call
+// to GetRoute () filters down into Ipv4L3Protocol where it translates into
+// a call into the Ipv4 static routing package.  This bypasses any other
+// routing packages.  At a minimum, the name is misleading.
+//
 bool 
-GetIpv4RouteToDestination (Ptr<Node> node, Ipv4Route& route, 
-                           Ipv4Address a, Ipv4Mask amask)
+Ipv4::GetRouteToDestination (
+  Ptr<Node> node, 
+  Ipv4Route& route, 
+  Ipv4Address a, 
+  Ipv4Mask amask)
 {
   Ipv4Route tempRoute;
   Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
-  NS_ASSERT_MSG (ipv4, "GetIpv4RouteToDestination:  No Ipv4 interface");
+  NS_ASSERT_MSG (ipv4, "Ipv4::GetRouteToDestination:  No Ipv4 interface");
   for (uint32_t i = 0; i < ipv4->GetNRoutes (); i++) 
     {
       tempRoute = ipv4->GetRoute (i);
@@ -83,5 +92,4 @@
   return false;
 }
 
-
 } // namespace ns3
--- a/src/node/ipv4.h	Tue Sep 11 12:20:09 2007 -0700
+++ b/src/node/ipv4.h	Tue Sep 11 18:29:26 2007 -0700
@@ -105,6 +105,7 @@
                              const Ipv4Header &ipHeader,
                              Packet packet,
                              RouteReplyCallback routeReply) = 0;
+
 /**
  * \brief Synchronously check to see if we can determine the interface index 
  * that will be used if a packet is sent to this destination.
@@ -396,6 +397,15 @@
   virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0;
 
   /**
+   * \param destination The IP address of a hypothetical destination.
+   * \param ifIndex filled in with the interface index that will be used to
+   *        send a packet to the hypothetical destination.
+   * \returns True if a single interface can be identified, false otherwise.
+   */
+  virtual bool GetIfIndexForDestination (Ipv4Address dest,
+    uint32_t &ifIndex) const = 0;
+
+  /**
    * \param i index of ipv4 interface
    * \returns the Maximum Transmission Unit (in bytes) associated
    *          to the underlying ipv4 interface
@@ -424,20 +434,18 @@
    * ignored during ipv4 forwarding.
    */
   virtual void SetDown (uint32_t i) = 0;
-};
 
 /**
  * Convenience functions (Doxygen still needed)
  *
  * Return the ifIndex corresponding to the Ipv4Address provided.
  */
-uint32_t GetIfIndexByIpv4Address (Ptr<Node> node, 
-                                  Ipv4Address a, 
-                                  Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
+  static uint32_t GetIfIndexByAddress (Ptr<Node> node, Ipv4Address a, 
+    Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
 
-bool GetIpv4RouteToDestination (Ptr<Node> node, Ipv4Route& route, 
-                                Ipv4Address a, 
-                                Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
+  static bool GetRouteToDestination (Ptr<Node> node, Ipv4Route& route, 
+    Ipv4Address a, Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
+};
 
 } // namespace ns3 
 
--- a/src/routing/global-routing/global-route-manager-impl.cc	Tue Sep 11 12:20:09 2007 -0700
+++ b/src/routing/global-routing/global-route-manager-impl.cc	Tue Sep 11 18:29:26 2007 -0700
@@ -1143,7 +1143,7 @@
 // we're looking for.  If we find one, return the corresponding interface
 // index.
 //
-          return (GetIfIndexByIpv4Address (node, a, amask) );
+          return (Ipv4::GetIfIndexByAddress (node, a, amask) );
         }
     }
 //