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