aodv_rtable unit test added
authorBorovkova Elena <borovkovaes@iitp.ru>
Sun, 05 Jul 2009 16:59:03 +0400
changeset 5542 1b504e63a1b1
parent 5541 06d67178ae33
child 5543 be0a97484ad4
aodv_rtable unit test added
src/routing/aodv/aodv-rqueue.cc
src/routing/aodv/aodv-rqueue.h
src/routing/aodv/aodv-rtable.cc
src/routing/aodv/aodv-rtable.h
src/routing/aodv/aodv.h
src/routing/aodv/rfc3561.txt
--- a/src/routing/aodv/aodv-rqueue.cc	Fri Jul 03 16:42:51 2009 +0400
+++ b/src/routing/aodv/aodv-rqueue.cc	Sun Jul 05 16:59:03 2009 +0400
@@ -28,160 +28,164 @@
 #include <algorithm>
 
 namespace ns3 {
-namespace aodv {
+  namespace aodv {
+
+    aodv_rqueue::aodv_rqueue() : limit_(AODV_RTQ_MAX_LEN), timeout_(Seconds(AODV_RTQ_TIMEOUT))
+    {
+    }
 
-aodv_rqueue::aodv_rqueue() : limit_(AODV_RTQ_MAX_LEN), timeout_(Seconds(AODV_RTQ_TIMEOUT))
-{
-}
+    uint32_t
+    aodv_rqueue::size ()
+    {
+      purge();
+      return queue.size();
+    }
 
-uint32_t
-aodv_rqueue::size ()
-{
-  purge();
-  return queue.size();
-}
+    void
+    aodv_rqueue::enque(QueueEntry & entry)
+    {
+      // Purge any packets that have timed out.
+      purge();
+      entry.enExpire = Simulator::Now() + timeout_;
 
-void
-aodv_rqueue::enque(QueueEntry & entry) 
-{
-  // Purge any packets that have timed out.
-  purge();
-  entry.enExpire = Simulator::Now() + timeout_;
+      if (queue.size() == limit_) drop(remove_head()); // drop the most aged packet
+      queue.push_back(entry);
+    }
+
+    QueueEntry
+    aodv_rqueue::deque()
+    {
+      purge();
+      return remove_head();
+    }
 
-  if (queue.size() == limit_) drop(remove_head()); // drop the most aged packet
-  queue.push_back(entry);
-}
-
-QueueEntry
-aodv_rqueue::deque() 
-{
-  purge();
-  return remove_head();
-}
+    bool
+    aodv_rqueue::deque(Ipv4Address dst, QueueEntry & entry)
+    {
+      purge();
+      for(std::vector<QueueEntry>::iterator i = queue.begin(); i != queue.end(); ++i)
+        if(i->header.GetDestination() == dst)
+          {
+            entry = *i;
+            queue.erase(i);
+            return true;
+          }
+      return false;
+    }
 
-bool
-aodv_rqueue::deque(Ipv4Address dst, QueueEntry & entry)
-{
-  purge();
-  for(std::vector<QueueEntry>::iterator i = queue.begin(); i != queue.end(); ++i)
-    if(i->header.GetDestination() == dst)
+    bool
+    aodv_rqueue::find(Ipv4Address dst)
+    {
+      for( std::vector<QueueEntry>::const_iterator i = queue.begin(); i != queue.end(); ++i)
+        if(i->header.GetDestination() == dst)
+          return true;
+      return false;
+    }
+
+    QueueEntry
+    aodv_rqueue::remove_head()
+    {
+      QueueEntry entry = queue.front();
+      queue.erase(queue.begin());
+      return entry;
+    }
+
+    struct IsExpired
+    {
+      bool operator() (QueueEntry const & e) const
       {
-        entry = *i;
-        queue.erase(i);
-        return true;
+        return (e.enExpire < Simulator::Now());
       }
-  return false;
-}
-
-bool
-aodv_rqueue::find(Ipv4Address dst)
-{
-  for( std::vector<QueueEntry>::const_iterator i = queue.begin(); i != queue.end(); ++i)
-    if(i->header.GetDestination() == dst)
-      return true;
-  return false;
-}
-
-QueueEntry
-aodv_rqueue::remove_head() 
-{
-  QueueEntry entry = queue.front();
-  queue.erase(queue.begin());  
-  return entry;
-}
+    };
 
-struct IsExpired
-{
-  bool operator() (QueueEntry const & e) const
-  {
-    return (e.enExpire < Simulator::Now());
-  }
-};
+    void
+    aodv_rqueue::purge()
+    {
+      std::vector<QueueEntry>::iterator i = std::remove_if(queue.begin(), queue.end(), IsExpired());
+      for (std::vector<QueueEntry>::iterator j = i ; j < queue.end(); ++j)
+        drop (*j);
+      queue.erase(i, queue.end());
+    }
 
-void
-aodv_rqueue::purge()
-{
-  std::vector<QueueEntry>::iterator i = std::remove_if(queue.begin(), queue.end(), IsExpired());
-  for (std::vector<QueueEntry>::iterator j = i ; j < queue.end(); ++j)
-    drop (*j); 
-  queue.erase(i, queue.end());
-}
-
-void 
-aodv_rqueue::drop(QueueEntry)
-{
-  // TODO do nothing now.
-}
+    void
+    aodv_rqueue::drop(QueueEntry)
+    {
+      // TODO do nothing now.
+    }
 
 #ifdef RUN_SELF_TESTS
-/// Unit test for aodv_rqueue
-struct AodvRqueueTest : public Test 
-{
-  AodvRqueueTest () : Test ("AODV/Rqueue"), result(true) {}
-  virtual bool RunTests();
-  
-  void CheckSizeLimit ();
-  void CheckTimeout ();
-  
-  aodv_rqueue q;
-  bool result;
-};
+    /// Unit test for aodv_rqueue
+    struct AodvRqueueTest : public Test
+    {
+      AodvRqueueTest () : Test ("AODV/Rqueue"), result(true) {}
+      virtual bool RunTests();
+
+      void CheckSizeLimit ();
+      void CheckTimeout ();
+
+      aodv_rqueue q;
+      bool result;
+    };
+
+    /// Test instance
+    static AodvRqueueTest g_AodvRqueueTest;
 
-/// Test instance
-static AodvRqueueTest g_AodvRqueueTest;
+    bool
+    AodvRqueueTest::RunTests ()
+    {
+      Ptr<Packet> packet = Create<Packet>();
+      Ipv4Header header;
+      QueueEntry e1 (packet, header);
+      q.enque (e1);
+      QueueEntry e2 = q.deque ();
+      NS_TEST_ASSERT (e1 == e2);
+
+      Ipv4Address dst("1.2.3.4");
+      header.SetDestination (dst);
+      e1 = QueueEntry (packet, header);
+      q.enque (e1);
+
+      bool ok = q.deque (dst, e2);
+      NS_TEST_ASSERT (ok);
+      NS_TEST_ASSERT (e1 == e2);
+      NS_TEST_ASSERT (! q.find(dst));
+      q.enque (e1);
+      NS_TEST_ASSERT (q.find(dst));
 
-bool 
-AodvRqueueTest::RunTests ()
-{
-  Ptr<Packet> packet = Create<Packet>();
-  Ipv4Header header;
-  QueueEntry e1 (packet, header);
-  q.enque (e1);
-  QueueEntry e2 = q.deque ();
-  NS_TEST_ASSERT (e1 == e2);
-  
-  Ipv4Address dst("1.2.3.4");
-  header.SetDestination (dst);
-  e1 = QueueEntry (packet, header);
-  q.enque (e1);
-  
-  bool ok = q.deque (dst, e2);
-  NS_TEST_ASSERT (ok);
-  NS_TEST_ASSERT (e1 == e2);
-  NS_TEST_ASSERT (! q.find(dst));
-  q.enque (e1);
-  NS_TEST_ASSERT (q.find(dst));
-  
-  CheckSizeLimit ();
-  
-  Simulator::Schedule (Seconds(AODV_RTQ_TIMEOUT+1), & AodvRqueueTest::CheckTimeout, this);
-  
-  Simulator::Run ();
-  Simulator::Destroy ();
-  
-  return result;
-}
+      CheckSizeLimit ();
+
+      Ipv4Header header2;
+      Ipv4Address dst2("1.2.3.4");
+      header2.SetDestination (dst2);
+
+      Simulator::Schedule (Seconds(AODV_RTQ_TIMEOUT+1), & AodvRqueueTest::CheckTimeout, this);
+
+      Simulator::Run ();
+      Simulator::Destroy ();
+
+      return result;
+    }
 
-void 
-AodvRqueueTest::CheckSizeLimit ()
-{
-  Ptr<Packet> packet = Create<Packet>();
-  Ipv4Header header;
-  QueueEntry e1 (packet, header);
-  
-  for (uint32_t i = 0; i < AODV_RTQ_MAX_LEN; ++i)
-    q.enque (e1);
-  NS_TEST_ASSERT (q.size() == AODV_RTQ_MAX_LEN);
-  
-  for (uint32_t i = 0; i < AODV_RTQ_MAX_LEN; ++i)
-      q.enque (e1);
-  NS_TEST_ASSERT (q.size() == AODV_RTQ_MAX_LEN);
-}
+    void
+    AodvRqueueTest::CheckSizeLimit ()
+    {
+      Ptr<Packet> packet = Create<Packet>();
+      Ipv4Header header;
+      QueueEntry e1 (packet, header);
+
+      for (uint32_t i = 0; i < AODV_RTQ_MAX_LEN; ++i)
+        q.enque (e1);
+      NS_TEST_ASSERT (q.size() == AODV_RTQ_MAX_LEN);
 
-void 
-AodvRqueueTest::CheckTimeout ()
-{
-  NS_TEST_ASSERT (q.size() == 0);
-}
+      for (uint32_t i = 0; i < AODV_RTQ_MAX_LEN; ++i)
+        q.enque (e1);
+      NS_TEST_ASSERT (q.size() == AODV_RTQ_MAX_LEN);
+    }
+
+    void
+    AodvRqueueTest::CheckTimeout ()
+    {
+      NS_TEST_ASSERT (q.size() == 0);
+    }
 #endif
-}}
+  }}
--- a/src/routing/aodv/aodv-rqueue.h	Fri Jul 03 16:42:51 2009 +0400
+++ b/src/routing/aodv/aodv-rqueue.h	Sun Jul 05 16:59:03 2009 +0400
@@ -36,7 +36,10 @@
 #define AODV_RTQ_MAX_LEN 64
 /// The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
 #define AODV_RTQ_TIMEOUT 30
-
+/**
+ * \ingroup aodv
+ * \brief AODV Queue Entry
+ */
 struct QueueEntry
 {
   Ptr<Packet> p;
@@ -50,7 +53,10 @@
     return ((p == o.p)/*&& header == o.header*/ && (enExpire == o.enExpire));
   }
 };
-
+/**
+ * \ingroup aodv
+ * \brief AODV Queue
+ */
 class aodv_rqueue 
 {
 public:
--- a/src/routing/aodv/aodv-rtable.cc	Fri Jul 03 16:42:51 2009 +0400
+++ b/src/routing/aodv/aodv-rtable.cc	Sun Jul 05 16:59:03 2009 +0400
@@ -15,15 +15,16 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Authors: The AODV code developed by the CMU/MONARCH group was optimized and 
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati. 
+ * Authors: The AODV code developed by the CMU/MONARCH group was optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati.
  * The work was partially done in Sun Microsystems.
- * 
+ *
  * Ported to ns-3 by Elena Borovkova <borovkovaes@iitp.ru>
  */
 
 #include "aodv-rtable.h"
 #include <algorithm>
+#include "ns3/test.h"
 
 namespace ns3 {
 namespace aodv {
@@ -34,22 +35,17 @@
 
 aodv_rt_entry::aodv_rt_entry()
 {
-  rt_req_timeout = 0.0;
+  rt_req_timeout = MilliSeconds(0.0);
   rt_req_cnt = 0;
-
-  rt_dst = 0;
+  rt_dst = Ipv4Address("127.0.0.1");
+  validSeqNo = false;
   rt_seqno = 0;
   rt_hops = rt_last_hop_count = INFINITY2;
-  rt_nexthop = 0;
-  rt_expire = 0.0;
+  rt_nexthop = Ipv4Address("127.0.0.1");
+  rt_lifetime = MilliSeconds(0.0);
   rt_flags = RTF_DOWN;
 
-  /*
- rt_errors = 0;
- rt_error_time = 0.0;
-   */
-  
-  for (int i=0; i < MAX_HISTORY; i++) 
+  for (int i=0; i < MAX_HISTORY; i++)
     {
       rt_disc_latency[i] = 0.0;
     }
@@ -57,36 +53,33 @@
   rt_req_last_ttl = 0;
 }
 
+aodv_rt_entry::aodv_rt_entry(Ipv4Address dst, bool vSeqNo, u_int32_t seqNo,
+		u_int16_t  hops,Ipv4Address nextHop, Time lifetime)
+{
+	rt_dst = dst;
+	validSeqNo = vSeqNo;
+	if(validSeqNo == true)
+		rt_seqno = seqNo;
+	rt_hops = hops;
+	rt_nexthop = nextHop;
+	rt_lifetime = lifetime;
+}
 
 aodv_rt_entry::~aodv_rt_entry()
 {
 }
 
-
-void
-aodv_rt_entry::nb_insert(Ipv4Address id)
-{
-  rt_nblist.push_back(AODV_Neighbor(id));
-}
-
 bool
-aodv_rt_entry::nb_lookup(Ipv4Address id, AODV_Neighbor & n)
-{
-  for(std::vector<AODV_Neighbor>::const_iterator i = rt_nblist.begin(); i != rt_nblist.end(); ++i)
-    if (i->nb_addr == id)
-      {
-        n = *i;
-        return true;
-      }
-  return false;
-}
-
-void
 aodv_rt_entry::pc_insert(Ipv4Address id)
 {
   AODV_Precursor p (id);
- 
-  if (! pc_lookup(id, p)) rt_pclist.push_back(p);
+
+  if (! pc_lookup(id, p))
+  {
+  	rt_pclist.push_back(p);
+  	return true;
+  }
+  else return false;
 }
 
 bool
@@ -101,18 +94,23 @@
   return false;
 }
 
-void
-aodv_rt_entry::pc_delete(Ipv4Address id) 
+bool
+aodv_rt_entry::pc_delete(Ipv4Address id)
 {
   AODV_Precursor p(id);
-  rt_pclist.erase (std::remove(rt_pclist.begin(), rt_pclist.end(), p), rt_pclist.end());
+  std::vector<AODV_Precursor>::iterator i = std::remove(rt_pclist.begin(), rt_pclist.end(), p);
+  if(i == rt_pclist.end())
+  	return false;
+  else
+  	rt_pclist.erase (i, rt_pclist.end());
+  return true;
 }
 
 void
-aodv_rt_entry::pc_delete() 
+aodv_rt_entry::pc_delete()
 {
   rt_pclist.clear();
-}	
+}
 
 bool
 aodv_rt_entry::pc_empty() const
@@ -127,24 +125,94 @@
 bool
 aodv_rtable::rt_lookup(Ipv4Address id, aodv_rt_entry & rt) const
 {
-  std::vector<aodv_rt_entry>::const_iterator i = std::find (rthead.begin(), rthead.end(), id);  
+  std::vector<aodv_rt_entry>::const_iterator i = std::find (rthead.begin(), rthead.end(), id);
   if (i == rthead.end()) return false;
   rt = *i;
   return true;
 }
 
-void
-aodv_rtable::rt_delete(Ipv4Address id)
+bool
+aodv_rtable::rt_delete(Ipv4Address dst)
 {
-  rthead.erase (std::remove(rthead.begin(), rthead.end(), id), rthead.end());
+	std::vector<aodv_rt_entry>::iterator i = std::remove(rthead.begin(), rthead.end(), dst);
+	if(i == rthead.end())
+		return false;
+  rthead.erase (i, rthead.end());
+  return true;
 }
 
-void
+bool
 aodv_rtable::rt_add(aodv_rt_entry const & rt)
 {
   aodv_rt_entry dummy;
-  NS_ASSERT(! rt_lookup(rt.rt_dst, dummy));
+  if(rt_lookup(rt.rt_dst, dummy))
+  	return false;
   rthead.push_back(rt);
+  return true;
 }
 
+#ifdef RUN_SELF_TESTS
+    /// Unit test for aodv_rqueue
+    struct AodvRtableTest : public Test
+    {
+      AodvRtableTest () : Test ("AODV/Rtable"), result(true) {}
+      virtual bool RunTests();
+      bool result;
+    };
+
+    /// Test instance
+    static AodvRtableTest g_AodvRtableTest;
+
+    bool
+    AodvRtableTest::RunTests ()
+    {
+    	AODV_Neighbor nb1(Ipv4Address("1.2.3.4"));
+    	AODV_Neighbor nb2(Ipv4Address("4.3.2.1"));
+    	NS_TEST_ASSERT(!(nb1==nb2));
+
+    	AODV_Neighbor nb3(Ipv4Address("3.3.3.3"));
+    	AODV_Neighbor nb4(Ipv4Address("3.3.3.3"), Seconds(1));
+    	NS_TEST_ASSERT(!(nb1==nb2));
+
+    	AODV_Precursor pc1(Ipv4Address("1.1.1.1"));
+    	AODV_Precursor pc2(Ipv4Address("2.2.2.2"));
+    	NS_TEST_ASSERT(!(pc1==pc2));
+
+    	aodv_rt_entry entry1;
+    	Ipv4Address dst1("3.3.3.3");
+    	Ipv4Address dst2("1.2.3.4");
+    	aodv_rt_entry entry2 = aodv_rt_entry(dst2, true, 34, 1, Ipv4Address("5.5.5.5"),  Seconds(5));
+    	NS_TEST_ASSERT( !(entry1 == dst1) );
+    	NS_TEST_ASSERT(entry2 == dst2);
+
+    	entry2.pc_insert(dst1);
+    	AODV_Precursor pc3(dst1);
+    	NS_TEST_ASSERT(entry2.pc_lookup(dst1, pc2));
+    	NS_TEST_ASSERT(pc3==pc2);
+    	NS_TEST_ASSERT(!entry2.pc_delete(dst2));
+    	NS_TEST_ASSERT(entry2.pc_delete(dst1));
+    	NS_TEST_ASSERT(entry2.pc_empty());
+    	entry2.pc_insert(dst2);
+    	NS_TEST_ASSERT(entry2.pc_insert(dst1));
+    	NS_TEST_ASSERT(!entry2.pc_insert(dst2));
+    	entry2.pc_delete();
+    	NS_TEST_ASSERT(entry2.pc_empty());
+
+    	aodv_rtable rtable;
+    	rtable.rt_add(entry2);
+    	NS_TEST_ASSERT(rtable.rt_lookup(dst2, entry1));
+    	NS_TEST_ASSERT(entry1 == dst2);
+    	NS_TEST_ASSERT(!rtable.rt_lookup(dst1, entry1));
+    	NS_TEST_ASSERT(rtable.rt_delete(dst2));
+    	NS_TEST_ASSERT(!rtable.rt_lookup(dst2, entry1));
+
+
+
+
+      return result;
+    }
+
+
+#endif
+
 }}
--- a/src/routing/aodv/aodv-rtable.h	Fri Jul 03 16:42:51 2009 +0400
+++ b/src/routing/aodv/aodv-rtable.h	Sun Jul 05 16:59:03 2009 +0400
@@ -15,10 +15,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Authors: The AODV code developed by the CMU/MONARCH group was optimized and 
- * tuned by Samir Das and Mahesh Marina, University of Cincinnati. 
+ * Authors: The AODV code developed by the CMU/MONARCH group was optimized and
+ * tuned by Samir Das and Mahesh Marina, University of Cincinnati.
  * The work was partially done in Sun Microsystems.
- * 
+ *
  * Ported to ns-3 by Elena Borovkova <borovkovaes@iitp.ru>
  */
 #ifndef __aodv_rtable_h__
@@ -29,6 +29,7 @@
 #include <sys/types.h>
 #include "ns3/ipv4.h"
 #include "ns3/nstime.h"
+#include "ns3/nstime.h"
 
 namespace ns3 {
 namespace aodv {
@@ -39,13 +40,17 @@
  * \ingroup aodv
  * \brief AODV Neighbor Cache Entry
  */
-class AODV_Neighbor 
+class AODV_Neighbor
 {
   friend class AODV;
   friend class aodv_rt_entry;
 
 public:
-  AODV_Neighbor(Ipv4Address const & a) : nb_addr(a), nb_expire(Seconds(0)) {}
+  AODV_Neighbor(Ipv4Address const & a, Time exp = Seconds(0)) : nb_addr(a), nb_expire(exp) {}
+  bool operator==(AODV_Neighbor const & n) const
+  {
+    return (nb_addr == n.nb_addr)&&(nb_expire == n.nb_expire);
+  }
 
 protected:
   Ipv4Address nb_addr;
@@ -54,73 +59,105 @@
 
 /**
  * \ingroup aodv
- * 
+ *
  * \brief AODV Precursor list data structure
  */
-class AODV_Precursor 
+class AODV_Precursor
 {
   friend class AODV;
   friend class aodv_rt_entry;
 public:
   AODV_Precursor(Ipv4Address const & a) : pc_addr(a) {}
-
   bool operator==(AODV_Precursor const & o) const
   {
     return (pc_addr == o.pc_addr);
   }
 protected:
-  Ipv4Address pc_addr;	// precursor address
+  /// Precursor address
+  Ipv4Address pc_addr;
 };
 
 /**
  * \ingroup aodv
  * \brief Route Table Entry
  */
-class aodv_rt_entry 
+class aodv_rt_entry
 {
   friend class aodv_rtable;
   friend class AODV;
   friend class LocalRepairTimer;
 public:
-  /// TODO make functional c-tor
-  aodv_rt_entry(); 
+  aodv_rt_entry();
+  aodv_rt_entry(Ipv4Address dst, bool vSeqNo, u_int32_t seqNo,
+  		u_int16_t  hops,Ipv4Address nextHop, Time lifetime);
   ~aodv_rt_entry();
 
-  void nb_insert(Ipv4Address id);
-  /// Lookup neighbor by address, return true on success
-  bool nb_lookup(Ipv4Address id, AODV_Neighbor & n);
-  void pc_insert(Ipv4Address id);
-  /// Lookup precursor by address, return true on success
+//  void nb_insert(Ipv4Address id);
+//  /// Lookup neighbor by address, return true on success
+//  bool nb_lookup(Ipv4Address id, AODV_Neighbor & n);
+  /**
+   * Insert precursor in precursor list if it doesn't yet exist in the list
+   * \param id precursor address
+   * \return true on success
+   */
+  bool pc_insert(Ipv4Address id);
+  /**
+   * Lookup precursor by address
+   * \param id precursor address
+   * \param p precursor with address id if exists
+   * \return true on success
+   */
   bool pc_lookup(Ipv4Address id, AODV_Precursor & p);
-  void pc_delete(Ipv4Address id);
+  /**
+   * \brief Delete precursor
+   * \param id precursor address
+   * \return true on success
+   */
+  bool pc_delete(Ipv4Address id);
+  /// Delete all precursors
   void pc_delete();
+  /**
+   * \return true if precursor list empty
+   */
   bool pc_empty() const;
-  
-  /// Compare destination address
-  bool operator==(Ipv4Address id) const
+  /**
+   * \brief Compare destination address
+   * \return true if equal
+   */
+  bool operator==(Ipv4Address const  dst) const
   {
-    return rt_dst == id;
+    return rt_dst == dst;
   }
 
-  /// when I can send another req
-  double rt_req_timeout;         
-  /// number of route requests
-  u_int8_t rt_req_cnt;             
+  /// When I can send another request
+  Time rt_req_timeout;
+  /// Number of route requests
+  u_int8_t rt_req_cnt;
 
 protected:
+  /// Destination address
   Ipv4Address rt_dst;
+  /// Valid Destination Sequence Number flag
+  bool validSeqNo;
+  /// Destination Sequence Number, if validSeqNo = true
   u_int32_t rt_seqno;
   /* u_int8_t 	rt_interface; */
-  /// hop count
+  /// Hop Count (number of hops needed to reach destination)
   u_int16_t rt_hops;
-  /// last valid hop count
+  /// Last valid hop count
   int rt_last_hop_count;
-  /// next hop IP address
-  Ipv4Address rt_nexthop;    		
-  /// list of precursors 
+  /// Next hop IP address
+  Ipv4Address rt_nexthop;
+  /// List of precursors
   std::vector<AODV_Precursor> rt_pclist;
-  /// when entry expires
-  double rt_expire;
+  /**
+  * \brief Expiration or deletion time of the route
+  *	Lifetime field in the routing table plays dual role --
+  *	for an active route it is the expiry time, and for an invalid route
+  *	it is the deletion time.
+  */
+  Time rt_lifetime;
+  /// Routing flags: down, up or in repair
   u_int8_t rt_flags;
 
 #define RTF_DOWN        0
@@ -130,27 +167,41 @@
 
   double rt_disc_latency[MAX_HISTORY];
   char hist_indx;
-  /// last ttl value used
+  /// Last ttl value used
   int rt_req_last_ttl;
-  /// a list of neighbors that are using this route.
-  std::vector<AODV_Neighbor> rt_nblist;
+//  /// a list of neighbors that are using this route.
+//  std::vector<AODV_Neighbor> rt_nblist;
 };
 
 /**
  * \ingroup aodv
  * The Routing Table
  */
-class aodv_rtable 
+class aodv_rtable
 {
 public:
   aodv_rtable() {}
 
   // aodv_rt_entry * head() {TODO}
-  
-  void rt_add(aodv_rt_entry const & r);
-  void rt_delete(Ipv4Address id);
-  /// Lookup routing table entry by destination. Return true on success.
-  bool rt_lookup(Ipv4Address id, aodv_rt_entry & rt) const;
+  /**
+   * Add routing table entry if it doesn't yet exist in routing table
+   * \param r routing table entry
+   * \return true in success
+   */
+  bool rt_add(aodv_rt_entry const & r);
+  /**
+   * Delete routing table entry
+   * \param dst destination address
+   * \return true on success
+   */
+  bool rt_delete(Ipv4Address dst);
+  /**
+   * Lookup routing table entry
+   * \param dst destination address
+   * \param rt entry with destination address dst, if exists
+   * \return true on success
+   */
+  bool rt_lookup(Ipv4Address dst, aodv_rt_entry & rt) const;
 
 private:
   std::vector<aodv_rt_entry> rthead;
--- a/src/routing/aodv/rfc3561.txt	Fri Jul 03 16:42:51 2009 +0400
+++ b/src/routing/aodv/rfc3561.txt	Sun Jul 05 16:59:03 2009 +0400
@@ -1518,7 +1518,7 @@
 
    It can be shown [4] that by the time the rebooted node comes out of
    the waiting phase and becomes an active router again, none of its
-   neighbors will be using it as an active next hop any more.  Its own
+   iftrs will be using it as an active next hop any more.  Its own
    sequence number gets updated once it receives a RREQ from any other
    node, as the RREQ always carries the maximum destination sequence
    number seen en route.  If no such RREQ arrives, the node MUST