src/routing/olsr/olsr-state.cc
author Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
Tue Dec 02 18:42:24 2008 +0000 (2008-12-02)
changeset 3970 8658841e4782
parent 2916 5d4ff983595b
child 5509 33d52e78605a
permissions -rw-r--r--
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.
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2004 Francisco J. Ros 
     4  * Copyright (c) 2007 INESC Porto
     5  *
     6  * This program is free software; you can redistribute it and/or modify
     7  * it under the terms of the GNU General Public License version 2 as
     8  * published by the Free Software Foundation;
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program; if not, write to the Free Software
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18  *
    19  * Authors: Francisco J. Ros  <fjrm@dif.um.es>
    20  *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
    21  */
    22 
    23 ///
    24 /// \file	OlsrState.cc
    25 /// \brief	Implementation of all functions needed for manipulating the internal
    26 ///		state of an OLSR node.
    27 ///
    28 
    29 #include "olsr-state.h"
    30 
    31 
    32 namespace ns3 {
    33 
    34 
    35 /********** MPR Selector Set Manipulation **********/
    36 
    37 MprSelectorTuple*
    38 OlsrState::FindMprSelectorTuple (Ipv4Address const &mainAddr)
    39 {
    40   for (MprSelectorSet::iterator it = m_mprSelectorSet.begin ();
    41        it != m_mprSelectorSet.end (); it++)
    42     {
    43       if (it->mainAddr == mainAddr)
    44         return &(*it);
    45     }
    46   return NULL;
    47 }
    48 
    49 void
    50 OlsrState::EraseMprSelectorTuple (const MprSelectorTuple &tuple)
    51 {
    52   for (MprSelectorSet::iterator it = m_mprSelectorSet.begin ();
    53        it != m_mprSelectorSet.end (); it++)
    54     {
    55       if (*it == tuple)
    56         {
    57           m_mprSelectorSet.erase (it);
    58           break;
    59         }
    60     }
    61 }
    62 
    63 void
    64 OlsrState::EraseMprSelectorTuples (const Ipv4Address &mainAddr)
    65 {
    66   for (MprSelectorSet::iterator it = m_mprSelectorSet.begin ();
    67        it != m_mprSelectorSet.end ();)
    68     {
    69       if (it->mainAddr == mainAddr)
    70         {
    71           it = m_mprSelectorSet.erase (it);
    72         }
    73       else
    74         {
    75           it++;
    76         }
    77     }
    78 }
    79 
    80 void
    81 OlsrState::InsertMprSelectorTuple (MprSelectorTuple const &tuple)
    82 {
    83   m_mprSelectorSet.push_back (tuple);
    84 }
    85 
    86 std::string
    87 OlsrState::PrintMprSelectorSet () const
    88 {
    89   std::ostringstream os;
    90   os << "[";
    91   for (MprSelectorSet::const_iterator iter = m_mprSelectorSet.begin ();
    92        iter != m_mprSelectorSet.end (); iter++)
    93     {
    94       MprSelectorSet::const_iterator next = iter;
    95       next++;
    96       os << iter->mainAddr;
    97       if (next != m_mprSelectorSet.end ())
    98         os << ", ";
    99     }
   100   os << "]";
   101   return os.str ();
   102 }
   103   
   104 
   105 /********** Neighbor Set Manipulation **********/
   106 
   107 NeighborTuple*
   108 OlsrState::FindNeighborTuple (Ipv4Address const &mainAddr)
   109 {
   110   for (NeighborSet::iterator it = m_neighborSet.begin ();
   111        it != m_neighborSet.end (); it++)
   112     {
   113       if (it->neighborMainAddr == mainAddr)
   114         return &(*it);
   115     }
   116   return NULL;
   117 }
   118 
   119 const NeighborTuple*
   120 OlsrState::FindSymNeighborTuple (Ipv4Address const &mainAddr) const
   121 {
   122   for (NeighborSet::const_iterator it = m_neighborSet.begin ();
   123        it != m_neighborSet.end (); it++)
   124     {
   125       if (it->neighborMainAddr == mainAddr && it->status == NeighborTuple::STATUS_SYM)
   126         return &(*it);
   127     }
   128   return NULL;
   129 }
   130 
   131 NeighborTuple*
   132 OlsrState::FindNeighborTuple (Ipv4Address const &mainAddr, uint8_t willingness)
   133 {
   134   for (NeighborSet::iterator it = m_neighborSet.begin ();
   135        it != m_neighborSet.end (); it++)
   136     {
   137       if (it->neighborMainAddr == mainAddr && it->willingness == willingness)
   138         return &(*it);
   139     }
   140   return NULL;
   141 }
   142 
   143 void
   144 OlsrState::EraseNeighborTuple (const NeighborTuple &tuple)
   145 {
   146   for (NeighborSet::iterator it = m_neighborSet.begin ();
   147        it != m_neighborSet.end (); it++)
   148     {
   149       if (*it == tuple)
   150         {
   151           m_neighborSet.erase (it);
   152           break;
   153         }
   154     }
   155 }
   156 
   157 void
   158 OlsrState::EraseNeighborTuple (const Ipv4Address &mainAddr)
   159 {
   160   for (NeighborSet::iterator it = m_neighborSet.begin ();
   161        it != m_neighborSet.end (); it++)
   162     {
   163       if (it->neighborMainAddr == mainAddr)
   164         {
   165           it = m_neighborSet.erase (it);
   166           break;
   167         }
   168     }
   169 }
   170 
   171 void
   172 OlsrState::InsertNeighborTuple (NeighborTuple const &tuple)
   173 {
   174   for (NeighborSet::iterator it = m_neighborSet.begin ();
   175        it != m_neighborSet.end (); it++)
   176     {
   177       if (it->neighborMainAddr == tuple.neighborMainAddr)
   178         {
   179           // Update it
   180           *it = tuple;
   181           return;
   182         }
   183     }
   184   m_neighborSet.push_back (tuple);
   185 }
   186 
   187 /********** Neighbor 2 Hop Set Manipulation **********/
   188 
   189 TwoHopNeighborTuple*
   190 OlsrState::FindTwoHopNeighborTuple (Ipv4Address const &neighborMainAddr,
   191                                     Ipv4Address const &twoHopNeighborAddr)
   192 {
   193   for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
   194        it != m_twoHopNeighborSet.end (); it++)
   195     {
   196       if (it->neighborMainAddr == neighborMainAddr
   197           && it->twoHopNeighborAddr == twoHopNeighborAddr)
   198         {
   199           return &(*it);
   200         }
   201   }
   202   return NULL;
   203 }
   204 
   205 void
   206 OlsrState::EraseTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
   207 {
   208   for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
   209        it != m_twoHopNeighborSet.end (); it++)
   210     {
   211       if (*it == tuple)
   212         {
   213           m_twoHopNeighborSet.erase(it);
   214           break;
   215         }
   216     }
   217 }
   218 
   219 void
   220 OlsrState::EraseTwoHopNeighborTuples (const Ipv4Address &neighborMainAddr,
   221                                       const Ipv4Address &twoHopNeighborAddr)
   222 {
   223   for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
   224        it != m_twoHopNeighborSet.end ();)
   225     {
   226       if (it->neighborMainAddr == neighborMainAddr
   227           && it->twoHopNeighborAddr == twoHopNeighborAddr)
   228         {
   229           it = m_twoHopNeighborSet.erase (it);
   230         }
   231       else
   232         {
   233           it++;
   234         }
   235     }
   236 }
   237 
   238 void
   239 OlsrState::EraseTwoHopNeighborTuples (const Ipv4Address &neighborMainAddr)
   240 {
   241   for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
   242        it != m_twoHopNeighborSet.end ();)
   243     {
   244       if (it->neighborMainAddr == neighborMainAddr)
   245         {
   246           it = m_twoHopNeighborSet.erase (it);
   247         }
   248       else
   249         {
   250           it++;
   251         }
   252     }
   253 }
   254 
   255 void
   256 OlsrState::InsertTwoHopNeighborTuple (TwoHopNeighborTuple const &tuple)
   257 {
   258   m_twoHopNeighborSet.push_back (tuple);
   259 }
   260 
   261 /********** MPR Set Manipulation **********/
   262 
   263 bool
   264 OlsrState::FindMprAddress (Ipv4Address const &addr)
   265 {
   266   MprSet::iterator it = m_mprSet.find (addr);
   267   return (it != m_mprSet.end ());
   268 }
   269 
   270 void
   271 OlsrState::SetMprSet (MprSet mprSet)
   272 {
   273   m_mprSet = mprSet;
   274 }
   275 
   276 /********** Duplicate Set Manipulation **********/
   277 
   278 DuplicateTuple*
   279 OlsrState::FindDuplicateTuple (Ipv4Address const &addr, uint16_t sequenceNumber)
   280 {
   281   for (DuplicateSet::iterator it = m_duplicateSet.begin ();
   282        it != m_duplicateSet.end(); it++)
   283     {
   284       if (it->address == addr && it->sequenceNumber == sequenceNumber)
   285         return &(*it);
   286     }
   287   return NULL;
   288 }
   289 
   290 void
   291 OlsrState::EraseDuplicateTuple (const DuplicateTuple &tuple)
   292 {
   293   for (DuplicateSet::iterator it = m_duplicateSet.begin ();
   294        it != m_duplicateSet.end (); it++)
   295     {
   296       if (*it == tuple)
   297         {
   298           m_duplicateSet.erase (it);
   299           break;
   300         }
   301     }
   302 }
   303 
   304 void
   305 OlsrState::InsertDuplicateTuple (DuplicateTuple const &tuple)
   306 {
   307   m_duplicateSet.push_back (tuple);
   308 }
   309 
   310 /********** Link Set Manipulation **********/
   311 
   312 LinkTuple*
   313 OlsrState::FindLinkTuple (Ipv4Address const & ifaceAddr)
   314 {
   315   for (LinkSet::iterator it = m_linkSet.begin ();
   316        it != m_linkSet.end (); it++)
   317     {
   318       if (it->neighborIfaceAddr == ifaceAddr)
   319         return &(*it);
   320     }
   321   return NULL;
   322 }
   323 
   324 LinkTuple*
   325 OlsrState::FindSymLinkTuple (Ipv4Address const &ifaceAddr, Time now)
   326 {
   327   for (LinkSet::iterator it = m_linkSet.begin ();
   328        it != m_linkSet.end (); it++)
   329     {
   330       if (it->neighborIfaceAddr == ifaceAddr)
   331         {
   332           if (it->symTime > now)
   333             return &(*it);
   334           else
   335             break;
   336         }
   337     }
   338   return NULL;
   339 }
   340 
   341 void
   342 OlsrState::EraseLinkTuple (const LinkTuple &tuple)
   343 {
   344   for (LinkSet::iterator it = m_linkSet.begin ();
   345        it != m_linkSet.end (); it++)
   346     {
   347       if (*it == tuple)
   348         {
   349           m_linkSet.erase (it);
   350           break;
   351         }
   352     }
   353 }
   354 
   355 LinkTuple&
   356 OlsrState::InsertLinkTuple (LinkTuple const &tuple)
   357 {
   358   m_linkSet.push_back (tuple);
   359   return m_linkSet.back ();
   360 }
   361 
   362 /********** Topology Set Manipulation **********/
   363 
   364 TopologyTuple*
   365 OlsrState::FindTopologyTuple (Ipv4Address const &destAddr,
   366                               Ipv4Address const &lastAddr)
   367 {
   368   for (TopologySet::iterator it = m_topologySet.begin ();
   369        it != m_topologySet.end (); it++)
   370     {
   371       if (it->destAddr == destAddr && it->lastAddr == lastAddr)
   372         return &(*it);
   373     }
   374   return NULL;
   375 }
   376 
   377 TopologyTuple*
   378 OlsrState::FindNewerTopologyTuple (Ipv4Address const & lastAddr, uint16_t ansn)
   379 {
   380   for (TopologySet::iterator it = m_topologySet.begin ();
   381        it != m_topologySet.end (); it++)
   382     {
   383       if (it->lastAddr == lastAddr && it->sequenceNumber > ansn)
   384         return &(*it);
   385     }
   386   return NULL;
   387 }
   388 
   389 void
   390 OlsrState::EraseTopologyTuple(const TopologyTuple &tuple)
   391 {
   392   for (TopologySet::iterator it = m_topologySet.begin ();
   393        it != m_topologySet.end (); it++)
   394     {
   395       if (*it == tuple)
   396         {
   397           m_topologySet.erase (it);
   398           break;
   399         }
   400     }
   401 }
   402 
   403 void
   404 OlsrState::EraseOlderTopologyTuples (const Ipv4Address &lastAddr, uint16_t ansn)
   405 {
   406   for (TopologySet::iterator it = m_topologySet.begin();
   407        it != m_topologySet.end();)
   408     {
   409       if (it->lastAddr == lastAddr && it->sequenceNumber < ansn)
   410         {
   411           it = m_topologySet.erase (it);
   412         }
   413       else
   414         {
   415           it++;
   416         }
   417     }
   418 }
   419 
   420 void
   421 OlsrState::InsertTopologyTuple (TopologyTuple const &tuple)
   422 {
   423   m_topologySet.push_back (tuple);
   424 }
   425 
   426 /********** Interface Association Set Manipulation **********/
   427 
   428 IfaceAssocTuple*
   429 OlsrState::FindIfaceAssocTuple (Ipv4Address const &ifaceAddr)
   430 {
   431   for (IfaceAssocSet::iterator it = m_ifaceAssocSet.begin ();
   432        it != m_ifaceAssocSet.end (); it++)
   433     {
   434       if (it->ifaceAddr == ifaceAddr)
   435         return &(*it);
   436     }
   437   return NULL;
   438 }
   439 
   440 const IfaceAssocTuple*
   441 OlsrState::FindIfaceAssocTuple (Ipv4Address const &ifaceAddr) const
   442 {
   443   for (IfaceAssocSet::const_iterator it = m_ifaceAssocSet.begin ();
   444        it != m_ifaceAssocSet.end (); it++)
   445     {
   446       if (it->ifaceAddr == ifaceAddr)
   447         return &(*it);
   448     }
   449   return NULL;
   450 }
   451 
   452 void
   453 OlsrState::EraseIfaceAssocTuple (const IfaceAssocTuple &tuple)
   454 {
   455   for (IfaceAssocSet::iterator it = m_ifaceAssocSet.begin ();
   456        it != m_ifaceAssocSet.end (); it++)
   457     {
   458       if (*it == tuple)
   459         {
   460           m_ifaceAssocSet.erase (it);
   461           break;
   462         }
   463     }
   464 }
   465 
   466 void
   467 OlsrState::InsertIfaceAssocTuple (const IfaceAssocTuple &tuple)
   468 {
   469   m_ifaceAssocSet.push_back (tuple);
   470 }
   471 
   472 std::vector<Ipv4Address>
   473 OlsrState::FindNeighborInterfaces (const Ipv4Address &neighborMainAddr) const
   474 {
   475   std::vector<Ipv4Address> retval;
   476   for (IfaceAssocSet::const_iterator it = m_ifaceAssocSet.begin ();
   477        it != m_ifaceAssocSet.end (); it++)
   478     {
   479       if (it->mainAddr == neighborMainAddr)
   480         retval.push_back (it->ifaceAddr);
   481     }
   482   return retval;
   483 }
   484 
   485 } // namespace ns3