Bug 879 - source address selection for AODV using DeferredRouteRequest
authorTom Henderson <tomh@tomh.org>
Tue, 10 Aug 2010 13:02:38 -0400
changeset 6547 6804b85fe140
parent 6546 44bb46a4a35f
child 6548 3d7b53f6702b
Bug 879 - source address selection for AODV using DeferredRouteRequest
src/routing/aodv/aodv-routing-protocol.cc
src/routing/aodv/aodv-routing-protocol.h
src/routing/aodv/test/tcp-chain-test-0-0.pcap
src/routing/aodv/test/tcp-chain-test-9-0.pcap
--- a/src/routing/aodv/aodv-routing-protocol.cc	Tue Aug 10 12:11:56 2010 -0400
+++ b/src/routing/aodv/aodv-routing-protocol.cc	Tue Aug 10 13:02:38 2010 -0400
@@ -265,7 +265,7 @@
   NS_LOG_FUNCTION (this << header << (oif? oif->GetIfIndex () : 0));
   if (! p)
     {
-      return LoopbackRoute (header); // later
+      return LoopbackRoute (header, oif); // later
     }
   if (m_socketAddresses.empty ())
     {
@@ -303,7 +303,7 @@
     {
       p->AddPacketTag (tag);
     }
-  return LoopbackRoute (header);
+  return LoopbackRoute (header, oif);
 }
 
 void
@@ -689,13 +689,48 @@
 }
 
 Ptr<Ipv4Route> 
-RoutingProtocol::LoopbackRoute (const Ipv4Header & hdr) const
+RoutingProtocol::LoopbackRoute (const Ipv4Header & hdr, Ptr<NetDevice> oif) const
 {
   NS_LOG_FUNCTION (this << hdr);
   NS_ASSERT (m_lo != 0);
   Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
   rt->SetDestination (hdr.GetDestination ());
-  rt->SetSource (Ipv4Address ("127.0.0.1"));
+  //
+  // Source address selection here is tricky.  The loopback route is
+  // returned when AODV does not have a route; this causes the packet
+  // to be looped back and handled (cached) in RouteInput() method
+  // while a route is found. However, connection-oriented protocols
+  // like TCP need to create an endpoint four-tuple (src, src port,
+  // dst, dst port) and create a pseudo-header for checksumming.  So,
+  // AODV needs to guess correctly what the eventual source address
+  // will be.
+  //
+  // For single interface, single address nodes, this is not a problem.
+  // When there are possibly multiple outgoing interfaces, the policy
+  // implemented here is to pick the first available AODV interface.
+  // If RouteOutput() caller specified an outgoing interface, that 
+  // further constrains the selection of source address
+  //
+  std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
+  if (oif)
+    {
+      // Iterate to find an address on the oif device
+      for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
+        {
+          Ipv4Address addr = j->second.GetLocal ();
+          int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
+          if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
+            {
+              rt->SetSource (addr);
+              break;
+            }
+        }
+    }
+  else
+    {
+      rt->SetSource (j->second.GetLocal ());
+    }
+  NS_ASSERT_MSG (rt->GetSource() != Ipv4Address (), "Valid AODV source address not found");
   rt->SetGateway (Ipv4Address ("127.0.0.1"));
   rt->SetOutputDevice (m_lo);
   return rt;
--- a/src/routing/aodv/aodv-routing-protocol.h	Tue Aug 10 12:11:56 2010 -0400
+++ b/src/routing/aodv/aodv-routing-protocol.h	Tue Aug 10 13:02:38 2010 -0400
@@ -180,7 +180,7 @@
   /// Process hello message
   void ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr);
   /// Create loopback route for given header
-  Ptr<Ipv4Route> LoopbackRoute (const Ipv4Header & header) const;
+  Ptr<Ipv4Route> LoopbackRoute (const Ipv4Header & header, Ptr<NetDevice> oif) const;
   
   ///\name Receive control packets
   //\{
Binary file src/routing/aodv/test/tcp-chain-test-0-0.pcap has changed
Binary file src/routing/aodv/test/tcp-chain-test-9-0.pcap has changed