Bug 733: OLSR MPR Computation give incorrect result
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Sun, 01 Nov 2009 22:47:04 +0000
changeset 5471 61831e265e20
parent 5470 d3aabb63dd12
child 5472 5800fd778af9
Bug 733: OLSR MPR Computation give incorrect result
src/routing/olsr/olsr-routing-protocol.cc
--- a/src/routing/olsr/olsr-routing-protocol.cc	Fri Oct 30 10:23:40 2009 -0700
+++ b/src/routing/olsr/olsr-routing-protocol.cc	Sun Nov 01 22:47:04 2009 +0000
@@ -552,7 +552,23 @@
         }
     }
 
-  NS_LOG_DEBUG ("Size of N2: " << N2.size ());  
+#ifdef NS3_LOG_ENABLE
+  {
+    std::ostringstream os;
+    os << "[";
+    for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
+         iter != N2.end (); iter++)
+      {
+        TwoHopNeighborSet::const_iterator next = iter;
+        next++;
+        os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
+        if (next != N2.end ())
+          os << ", ";
+      }
+    os << "]";
+    NS_LOG_DEBUG ("N2: " << os.str ());
+  }
+#endif  //NS3_LOG_ENABLE
 
   // 1. Start with an MPR set made of all members of N with
   // N_willingness equal to WILL_ALWAYS
@@ -584,31 +600,38 @@
   // 3. Add to the MPR set those nodes in N, which are the *only*
   // nodes to provide reachability to a node in N2.
   std::set<Ipv4Address> coveredTwoHopNeighbors;
-  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
+  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
     {
-      NeighborSet::const_iterator onlyNeighbor = N.end ();
-      
-      for (NeighborSet::const_iterator neighbor = N.begin ();
-           neighbor != N.end (); neighbor++)
+      bool onlyOne = true;
+      // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
+      for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
         {
-          if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr)
+          if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
+              && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
             {
-              if (onlyNeighbor == N.end ())
+              onlyOne = false;
+              break;
+            }
+        }
+      if (onlyOne)
+        {
+          NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
+                        << " is the only that can reach 2-hop neigh. "
+                        << twoHopNeigh->twoHopNeighborAddr
+                        << " => select as MPR.");
+
+          mprSet.insert (twoHopNeigh->neighborMainAddr);
+
+          // take note of all the 2-hop neighbors reachable by the newly elected MPR
+          for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
+               otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
+            {
+              if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
                 {
-                  onlyNeighbor = neighbor;
-                }
-              else
-                {
-                  onlyNeighbor = N.end ();
-                  break;
+                  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
                 }
             }
         }
-      if (onlyNeighbor != N.end ())
-        {
-          mprSet.insert (onlyNeighbor->neighborMainAddr);
-          coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr);
-        }
     }
   // Remove the nodes from N2 which are now covered by a node in the MPR set.
   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
@@ -616,6 +639,7 @@
     {
       if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
         {
+          NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
           twoHopNeigh = N2.erase (twoHopNeigh);
         }
       else
@@ -628,6 +652,26 @@
   // least one node in the MPR set:
   while (N2.begin () != N2.end ())
     {
+
+#ifdef NS3_LOG_ENABLE
+      {
+        std::ostringstream os;
+        os << "[";
+        for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
+             iter != N2.end (); iter++)
+          {
+            TwoHopNeighborSet::const_iterator next = iter;
+            next++;
+            os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
+            if (next != N2.end ())
+              os << ", ";
+          }
+        os << "]";
+        NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
+      }
+#endif  //NS3_LOG_ENABLE
+
+
       // 4.1. For each node in N, calculate the reachability, i.e., the
       // number of nodes in N2 which are not yet covered by at
       // least one node in the MPR set, and which are reachable