Fix a couple of OLSR bugs (#415)
- Added a lot more logging messages;
- When "link sensing" tries to update a link tuple for a neighbor that has been removed, just re-add the neighbor, rather than silently failing;
- The optimization of not recomputing the routing table if we think no state has changed has been removed: it turned out to be just too buggy and the code base makes it difficult to catch all places where a state mofication is done. Instead now we just recompute the table for any message processed, like the RFC says.
--- a/src/routing/olsr/olsr-agent-impl.cc Tue Dec 02 07:42:33 2008 -0800
+++ b/src/routing/olsr/olsr-agent-impl.cc Tue Dec 02 18:42:24 2008 +0000
@@ -29,6 +29,10 @@
/// implemented here.
///
+#define NS_LOG_APPEND_CONTEXT \
+ if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
+
+
#include "olsr-agent-impl.h"
#include "ns3/socket-factory.h"
#include "ns3/udp-socket-factory.h"
@@ -343,8 +347,6 @@
m_rxPacketTrace (olsrPacketHeader, messages);
- m_state.SetModified (false);
-
for (MessageList::const_iterator messageIter = messages.begin ();
messageIter != messages.end (); messageIter++)
{
@@ -441,11 +443,7 @@
}
// After processing all OLSR messages, we must recompute the routing table
- if (m_state.GetModified ())
- {
- RoutingTableComputation ();
- m_state.SetModified (false);
- }
+ RoutingTableComputation ();
}
///
@@ -464,7 +462,7 @@
TwoHopNeighborTuple const &nb2hop_tuple = *it;
if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
{
- NeighborTuple *nb_tuple =
+ const NeighborTuple *nb_tuple =
m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr);
if (nb_tuple == NULL)
degree++;
@@ -479,6 +477,8 @@
void
AgentImpl::MprComputation()
{
+ NS_LOG_FUNCTION (this);
+
// MPR computation should be done for each interface. See section 8.3.1
// (RFC 3626) for details.
MprSet mprSet;
@@ -557,6 +557,8 @@
}
}
+ NS_LOG_DEBUG ("Size of N2: " << N2.size ());
+
// 1. Start with an MPR set made of all members of N with
// N_willingness equal to WILL_ALWAYS
for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
@@ -714,8 +716,25 @@
}
}
+#ifdef NS3_LOG_ENABLE
+ {
+ std::ostringstream os;
+ os << "[";
+ for (MprSet::const_iterator iter = mprSet.begin ();
+ iter != mprSet.end (); iter++)
+ {
+ MprSet::const_iterator next = iter;
+ next++;
+ os << *iter;
+ if (next != mprSet.end ())
+ os << ", ";
+ }
+ os << "]";
+ NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
+ }
+#endif
+
m_state.SetMprSet (mprSet);
-
}
///
@@ -1056,7 +1075,7 @@
// 1. If the sender interface of this message is not in the symmetric
// 1-hop neighborhood of this node, the message MUST be discarded.
- LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
+ const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
if (link_tuple == NULL)
return;
@@ -1065,7 +1084,7 @@
// T_seq > ANSN,
// then further processing of this TC message MUST NOT be
// performed.
- TopologyTuple *topologyTuple =
+ const TopologyTuple *topologyTuple =
m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
if (topologyTuple != NULL)
return;
@@ -1152,7 +1171,7 @@
NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
// 1. If the sender interface of this message is not in the symmetric
// 1-hop neighborhood of this node, the message MUST be discarded.
- LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
+ const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
if (linkTuple == NULL)
{
NS_LOG_LOGIC ("Node " << m_mainAddress <<
@@ -1234,7 +1253,7 @@
// If the sender interface address is not in the symmetric
// 1-hop neighborhood the message must not be forwarded
- LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
+ const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
if (linkTuple == NULL)
return;
@@ -1253,7 +1272,7 @@
bool retransmitted = false;
if (olsrMessage.GetTimeToLive () > 1)
{
- MprSelectorTuple *mprselTuple =
+ const MprSelectorTuple *mprselTuple =
m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
if (mprselTuple != NULL)
{
@@ -1378,6 +1397,8 @@
void
AgentImpl::SendHello ()
{
+ NS_LOG_FUNCTION (this);
+
olsr::MessageHeader msg;
Time now = Simulator::Now ();
@@ -1423,6 +1444,8 @@
if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
{
nb_type = OLSR_MPR_NEIGH;
+ NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
+ << " to be MPR_NEIGH.");
}
else
{
@@ -1435,11 +1458,15 @@
{
if (nb_tuple->status == NeighborTuple::STATUS_SYM)
{
+ NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
+ << " to be SYM_NEIGH.");
nb_type = OLSR_SYM_NEIGH;
}
else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
{
nb_type = OLSR_NOT_NEIGH;
+ NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
+ << " to be NOT_NEIGH.");
}
else
{
@@ -1451,6 +1478,7 @@
}
if (!ok)
{
+ NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
continue;
}
}
@@ -1480,6 +1508,8 @@
void
AgentImpl::SendTc ()
{
+ NS_LOG_FUNCTION (this);
+
olsr::MessageHeader msg;
msg.SetVTime (OLSR_TOP_HOLD_TIME);
@@ -1662,7 +1692,7 @@
if (updated)
{
- LinkTupleUpdated (*link_tuple);
+ LinkTupleUpdated (*link_tuple, hello.willingness);
}
// Schedules link tuple deletion
@@ -1686,7 +1716,9 @@
{
NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ());
if (nb_tuple != NULL)
- nb_tuple->willingness = hello.willingness;
+ {
+ nb_tuple->willingness = hello.willingness;
+ }
}
@@ -1809,6 +1841,8 @@
AgentImpl::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
const olsr::MessageHeader::Hello &hello)
{
+ NS_LOG_FUNCTION (this);
+
Time now = Simulator::Now ();
typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
@@ -1819,6 +1853,8 @@
int nt = linkMessage->linkCode >> 2;
if (nt == OLSR_MPR_NEIGH)
{
+ NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
+
for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
linkMessage->neighborInterfaceAddresses.begin ();
nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
@@ -1826,6 +1862,8 @@
{
if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
{
+ NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
+
// We must create a new entry into the mpr selector set
MprSelectorTuple *existing_mprsel_tuple =
m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ());
@@ -1851,6 +1889,7 @@
}
}
}
+ NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
}
@@ -1904,7 +1943,7 @@
NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
<< "s: OLSR Node " << m_mainAddress
<< " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
- LinkTupleUpdated (tuple);
+ LinkTupleUpdated (tuple, OLSR_WILL_DEFAULT);
m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr));
m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr));
@@ -1988,7 +2027,7 @@
/// \param tuple the link tuple which has been updated.
///
void
-AgentImpl::LinkTupleUpdated (const LinkTuple &tuple)
+AgentImpl::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
{
// Each time a link tuple changes, the associated neighbor tuple must be recomputed
@@ -1998,6 +2037,12 @@
NeighborTuple *nb_tuple =
m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
+
+ if (nb_tuple == NULL)
+ {
+ LinkTupleAdded (tuple, willingness);
+ nb_tuple = m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
+ }
if (nb_tuple != NULL)
{
@@ -2017,6 +2062,10 @@
<< int (statusBefore != nb_tuple->status));
}
}
+ else
+ {
+ NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
+ }
}
///
@@ -2240,6 +2289,10 @@
{
SendTc ();
}
+ else
+ {
+ NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
+ }
m_tcTimer.Schedule (m_tcInterval);
}
--- a/src/routing/olsr/olsr-agent-impl.h Tue Dec 02 07:42:33 2008 -0800
+++ b/src/routing/olsr/olsr-agent-impl.h Tue Dec 02 18:42:24 2008 +0000
@@ -144,7 +144,7 @@
void RemoveDuplicateTuple (const DuplicateTuple &tuple);
void LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness);
void RemoveLinkTuple (const LinkTuple &tuple);
- void LinkTupleUpdated (const LinkTuple &tuple);
+ void LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness);
void AddNeighborTuple (const NeighborTuple &tuple);
void RemoveNeighborTuple (const NeighborTuple &tuple);
void AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
--- a/src/routing/olsr/olsr-state.cc Tue Dec 02 07:42:33 2008 -0800
+++ b/src/routing/olsr/olsr-state.cc Tue Dec 02 18:42:24 2008 +0000
@@ -83,6 +83,25 @@
m_mprSelectorSet.push_back (tuple);
}
+std::string
+OlsrState::PrintMprSelectorSet () const
+{
+ std::ostringstream os;
+ os << "[";
+ for (MprSelectorSet::const_iterator iter = m_mprSelectorSet.begin ();
+ iter != m_mprSelectorSet.end (); iter++)
+ {
+ MprSelectorSet::const_iterator next = iter;
+ next++;
+ os << iter->mainAddr;
+ if (next != m_mprSelectorSet.end ())
+ os << ", ";
+ }
+ os << "]";
+ return os.str ();
+}
+
+
/********** Neighbor Set Manipulation **********/
NeighborTuple*
@@ -130,7 +149,6 @@
if (*it == tuple)
{
m_neighborSet.erase (it);
- m_modified = true;
break;
}
}
@@ -145,7 +163,6 @@
if (it->neighborMainAddr == mainAddr)
{
it = m_neighborSet.erase (it);
- m_modified = true;
break;
}
}
@@ -161,7 +178,6 @@
{
// Update it
*it = tuple;
- m_modified = true;
return;
}
}
@@ -195,7 +211,6 @@
if (*it == tuple)
{
m_twoHopNeighborSet.erase(it);
- m_modified = true;
break;
}
}
@@ -212,7 +227,6 @@
&& it->twoHopNeighborAddr == twoHopNeighborAddr)
{
it = m_twoHopNeighborSet.erase (it);
- m_modified = true;
}
else
{
@@ -230,7 +244,6 @@
if (it->neighborMainAddr == neighborMainAddr)
{
it = m_twoHopNeighborSet.erase (it);
- m_modified = true;
}
else
{
@@ -243,7 +256,6 @@
OlsrState::InsertTwoHopNeighborTuple (TwoHopNeighborTuple const &tuple)
{
m_twoHopNeighborSet.push_back (tuple);
- m_modified = true;
}
/********** MPR Set Manipulation **********/
@@ -335,7 +347,6 @@
if (*it == tuple)
{
m_linkSet.erase (it);
- m_modified = true;
break;
}
}
@@ -345,7 +356,6 @@
OlsrState::InsertLinkTuple (LinkTuple const &tuple)
{
m_linkSet.push_back (tuple);
- m_modified = true;
return m_linkSet.back ();
}
@@ -385,7 +395,6 @@
if (*it == tuple)
{
m_topologySet.erase (it);
- m_modified = true;
break;
}
}
@@ -400,7 +409,6 @@
if (it->lastAddr == lastAddr && it->sequenceNumber < ansn)
{
it = m_topologySet.erase (it);
- m_modified = true;
}
else
{
@@ -413,7 +421,6 @@
OlsrState::InsertTopologyTuple (TopologyTuple const &tuple)
{
m_topologySet.push_back (tuple);
- m_modified = true;
}
/********** Interface Association Set Manipulation **********/
@@ -451,7 +458,6 @@
if (*it == tuple)
{
m_ifaceAssocSet.erase (it);
- m_modified = true;
break;
}
}
@@ -461,7 +467,6 @@
OlsrState::InsertIfaceAssocTuple (const IfaceAssocTuple &tuple)
{
m_ifaceAssocSet.push_back (tuple);
- m_modified = true;
}
std::vector<Ipv4Address>
--- a/src/routing/olsr/olsr-state.h Tue Dec 02 07:42:33 2008 -0800
+++ b/src/routing/olsr/olsr-state.h Tue Dec 02 18:42:24 2008 +0000
@@ -46,29 +46,11 @@
DuplicateSet m_duplicateSet; ///< Duplicate Set (RFC 3626, section 3.4).
IfaceAssocSet m_ifaceAssocSet; ///< Interface Association Set (RFC 3626, section 4.1).
-// m_modified is set to true when any of the following databases is modified:
-// - the link set,
-// - the neighbor set,
-// - the 2-hop neighbor set,
-// - the topology set,
-// - the Multiple Interface Association Information Base,
- bool m_modified;
-
public:
OlsrState ()
- : m_modified (false)
{}
- bool GetModified () const
- {
- return m_modified;
- }
- void SetModified (bool modified)
- {
- m_modified = modified;
- }
-
// MPR selector
const MprSelectorSet & GetMprSelectors () const
{
@@ -78,6 +60,7 @@
void EraseMprSelectorTuple (const MprSelectorTuple &tuple);
void EraseMprSelectorTuples (const Ipv4Address &mainAddr);
void InsertMprSelectorTuple (const MprSelectorTuple &tuple);
+ std::string PrintMprSelectorSet () const;
// Neighbor
const NeighborSet & GetNeighbors () const