diff --git a/src/aodv/model/aodv-routing-protocol.cc b/src/aodv/model/aodv-routing-protocol.cc index ac1ab5d22..05f3b01d9 100644 --- a/src/aodv/model/aodv-routing-protocol.cc +++ b/src/aodv/model/aodv-routing-protocol.cc @@ -283,6 +283,12 @@ RoutingProtocol::DoDispose () iter->first->Close (); } m_socketAddresses.clear (); + for (std::map, Ipv4InterfaceAddress>::iterator iter = + m_socketSubnetBroadcastAddresses.begin (); iter != m_socketSubnetBroadcastAddresses.end (); iter++) + { + iter->first->Close (); + } + m_socketSubnetBroadcastAddresses.clear (); Ipv4RoutingProtocol::DoDispose (); } @@ -619,12 +625,28 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i) socket->SetAttribute ("IpTtl", UintegerValue (1)); m_socketAddresses.insert (std::make_pair (socket, iface)); + // create also a subnet broadcast socket + socket = Socket::CreateSocket (GetObject (), + UdpSocketFactory::GetTypeId ()); + NS_ASSERT (socket != 0); + socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); + socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); + socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); + m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface)); + // Add local broadcast record to the routing table Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ())); RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ()); m_routingTable.AddRoute (rt); + if (l3->GetInterface (i)->GetArpCache ()) + { + m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ()); + } + // Allow neighbor manager use this interface for layer 2 feedback if possible Ptr wifi = dev->GetObject (); if (wifi == 0) @@ -634,7 +656,6 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i) return; mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ()); - m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ()); } void @@ -662,6 +683,13 @@ RoutingProtocol::NotifyInterfaceDown (uint32_t i) NS_ASSERT (socket); socket->Close (); m_socketAddresses.erase (socket); + + // Close socket + socket = FindSubnetBroadcastSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0)); + NS_ASSERT (socket); + socket->Close (); + m_socketSubnetBroadcastAddresses.erase (socket); + if (m_socketAddresses.empty ()) { NS_LOG_LOGIC ("No aodv interfaces"); @@ -693,12 +721,22 @@ RoutingProtocol::NotifyAddAddress (uint32_t i, Ipv4InterfaceAddress address) UdpSocketFactory::GetTypeId ()); NS_ASSERT (socket != 0); socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv,this)); - // Bind to any IP address so that broadcasts can be received socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT)); socket->BindToNetDevice (l3->GetNetDevice (i)); socket->SetAllowBroadcast (true); m_socketAddresses.insert (std::make_pair (socket, iface)); + // create also a subnet directed broadcast socket + socket = Socket::CreateSocket (GetObject (), + UdpSocketFactory::GetTypeId ()); + NS_ASSERT (socket != 0); + socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); + socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); + socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); + m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface)); + // Add local broadcast record to the routing table Ptr dev = m_ipv4->GetNetDevice ( m_ipv4->GetInterfaceForAddress (iface.GetLocal ())); @@ -722,7 +760,16 @@ RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address) if (socket) { m_routingTable.DeleteAllRoutesFromInterface (address); + socket->Close (); m_socketAddresses.erase (socket); + + Ptr unicastSocket = FindSubnetBroadcastSocketWithInterfaceAddress (address); + if (unicastSocket) + { + unicastSocket->Close (); + m_socketAddresses.erase (unicastSocket); + } + Ptr l3 = m_ipv4->GetObject (); if (l3->GetNAddresses (i)) { @@ -733,10 +780,23 @@ RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address) NS_ASSERT (socket != 0); socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); // Bind to any IP address so that broadcasts can be received - socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), AODV_PORT)); + socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); m_socketAddresses.insert (std::make_pair (socket, iface)); + // create also a unicast socket + socket = Socket::CreateSocket (GetObject (), + UdpSocketFactory::GetTypeId ()); + NS_ASSERT (socket != 0); + socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); + socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); + socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); + m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface)); + // Add local broadcast record to the routing table Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ())); RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface, @@ -937,7 +997,20 @@ RoutingProtocol::RecvAodv (Ptr socket) Ptr packet = socket->RecvFrom (sourceAddress); InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress); Ipv4Address sender = inetSourceAddr.GetIpv4 (); - Ipv4Address receiver = m_socketAddresses[socket].GetLocal (); + Ipv4Address receiver; + + if (m_socketAddresses.find (socket) != m_socketAddresses.end ()) + { + receiver = m_socketAddresses[socket].GetLocal (); + } + else if(m_socketSubnetBroadcastAddresses.find (socket) != m_socketSubnetBroadcastAddresses.end ()) + { + receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal (); + } + else + { + NS_ASSERT_MSG (false, "Received a packet from an unknown socket"); + } NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver); UpdateRouteToNeighbor (sender, receiver); @@ -1838,5 +1911,21 @@ RoutingProtocol::FindSocketWithInterfaceAddress (Ipv4InterfaceAddress addr ) con return socket; } +Ptr +RoutingProtocol::FindSubnetBroadcastSocketWithInterfaceAddress (Ipv4InterfaceAddress addr ) const +{ + NS_LOG_FUNCTION (this << addr); + for (std::map, Ipv4InterfaceAddress>::const_iterator j = + m_socketSubnetBroadcastAddresses.begin (); j != m_socketSubnetBroadcastAddresses.end (); ++j) + { + Ptr socket = j->first; + Ipv4InterfaceAddress iface = j->second; + if (iface == addr) + return socket; + } + Ptr socket; + return socket; +} + } } diff --git a/src/aodv/model/aodv-routing-protocol.h b/src/aodv/model/aodv-routing-protocol.h index e447eae89..49c2fdf58 100644 --- a/src/aodv/model/aodv-routing-protocol.h +++ b/src/aodv/model/aodv-routing-protocol.h @@ -140,8 +140,10 @@ private: /// IP protocol Ptr m_ipv4; - /// Raw socket per each IP interface, map socket -> iface address (IP + mask) + /// Raw unicast socket per each IP interface, map socket -> iface address (IP + mask) std::map< Ptr, Ipv4InterfaceAddress > m_socketAddresses; + /// Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP + mask) + std::map< Ptr, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses; /// Loopback device used to defer RREQ until packet will be fully formed Ptr m_lo; @@ -191,8 +193,10 @@ private: void UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver); /// Check that packet is send from own interface bool IsMyOwnAddress (Ipv4Address src); - /// Find socket with local interface address iface + /// Find unicast socket with local interface address iface Ptr FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const; + /// Find subnet directed broadcast socket with local interface address iface + Ptr FindSubnetBroadcastSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const; /// Process hello message void ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr); /// Create loopback route for given header