|
265 |
NS_LOG_FUNCTION (this << header << (oif? oif->GetIfIndex () : 0)); |
265 |
NS_LOG_FUNCTION (this << header << (oif? oif->GetIfIndex () : 0)); |
266 |
if (! p) |
266 |
if (! p) |
267 |
{ |
267 |
{ |
268 |
return LoopbackRoute (header); // later |
268 |
return LoopbackRoute (header, oif); // later |
269 |
} |
269 |
} |
270 |
if (m_socketAddresses.empty ()) |
270 |
if (m_socketAddresses.empty ()) |
271 |
{ |
271 |
{ |
|
303 |
{ |
303 |
{ |
304 |
p->AddPacketTag (tag); |
304 |
p->AddPacketTag (tag); |
305 |
} |
305 |
} |
306 |
return LoopbackRoute (header); |
306 |
return LoopbackRoute (header, oif); |
307 |
} |
307 |
} |
308 |
|
308 |
|
309 |
void |
309 |
void |
|
689 |
} |
689 |
} |
690 |
|
690 |
|
691 |
Ptr<Ipv4Route> |
691 |
Ptr<Ipv4Route> |
692 |
RoutingProtocol::LoopbackRoute (const Ipv4Header & hdr) const |
692 |
RoutingProtocol::LoopbackRoute (const Ipv4Header & hdr, Ptr<NetDevice> oif) const |
693 |
{ |
693 |
{ |
694 |
NS_LOG_FUNCTION (this << hdr); |
694 |
NS_LOG_FUNCTION (this << hdr); |
695 |
NS_ASSERT (m_lo != 0); |
695 |
NS_ASSERT (m_lo != 0); |
696 |
Ptr<Ipv4Route> rt = Create<Ipv4Route> (); |
696 |
Ptr<Ipv4Route> rt = Create<Ipv4Route> (); |
697 |
rt->SetDestination (hdr.GetDestination ()); |
697 |
rt->SetDestination (hdr.GetDestination ()); |
698 |
rt->SetSource (Ipv4Address ("127.0.0.1")); |
698 |
// |
|
|
699 |
// Source address selection here is tricky. The loopback route is |
700 |
// returned when AODV does not have a route; this causes the packet |
701 |
// to be looped back and handled (cached) in RouteInput() method |
702 |
// while a route is found. However, connection-oriented protocols |
703 |
// like TCP need to create an endpoint four-tuple (src, src port, |
704 |
// dst, dst port) and create a pseudo-header for checksumming. So, |
705 |
// AODV needs to guess correctly what the eventual source address |
706 |
// will be. |
707 |
// |
708 |
// For single interface, single address nodes, this is not a problem. |
709 |
// When there are possibly multiple outgoing interfaces, the policy |
710 |
// implemented here is to pick the first available AODV interface. |
711 |
// If RouteOutput() caller specified an outgoing interface, that |
712 |
// further constrains the selection of source address |
713 |
// |
714 |
std::map<Ptr<Socket> , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); |
715 |
if (oif) |
716 |
{ |
717 |
// Iterate to find an address on the oif device |
718 |
for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) |
719 |
{ |
720 |
Ipv4Address addr = j->second.GetLocal (); |
721 |
int32_t interface = m_ipv4->GetInterfaceForAddress (addr); |
722 |
if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface))) |
723 |
{ |
724 |
rt->SetSource (addr); |
725 |
break; |
726 |
} |
727 |
} |
728 |
} |
729 |
else |
730 |
{ |
731 |
rt->SetSource (j->second.GetLocal ()); |
732 |
} |
733 |
NS_ASSERT_MSG (rt->GetSource() != Ipv4Address (), "Valid AODV source address not found"); |
699 |
rt->SetGateway (Ipv4Address ("127.0.0.1")); |
734 |
rt->SetGateway (Ipv4Address ("127.0.0.1")); |
700 |
rt->SetOutputDevice (m_lo); |
735 |
rt->SetOutputDevice (m_lo); |
701 |
return rt; |
736 |
return rt; |