routecache.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:8k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * routecache.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: routecache.cc,v 1.8 2006/02/21 15:20:18 mahrenho Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as 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 along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. /*
  46.  * Ported from CMU/Monarch's code, appropriate copyright applies.  
  47.  * routecache.cc
  48.  *   handles routes
  49.  */
  50. extern "C" {
  51. #include <stdio.h>
  52. #include <stdarg.h>
  53. }
  54. #undef DEBUG
  55. #include "path.h"
  56. #include "routecache.h"
  57. #include <god.h>
  58. static const int verbose_debug = 0;
  59. /*===============================================================
  60.   OTcl definition
  61. ----------------------------------------------------------------*/
  62. static class RouteCacheClass : public TclClass {
  63. public:
  64.         RouteCacheClass() : TclClass("RouteCache") {}
  65.         TclObject* create(int, const char*const*) {
  66.                 return makeRouteCache();
  67.         }
  68. } class_RouteCache;
  69. /*===============================================================
  70.  Constructors
  71. ----------------------------------------------------------------*/
  72. RouteCache::RouteCache():
  73. #ifdef DSR_CACHE_STATS
  74. mh(this),
  75. #endif
  76. MAC_id(invalid_addr), net_id(invalid_addr)
  77. {
  78. #ifdef DSR_CACHE_STATS
  79. stat.reset();
  80. #endif
  81. }
  82. RouteCache::~RouteCache()
  83. {
  84. }
  85. int
  86. RouteCache::command(int argc, const char*const* argv)
  87. {
  88.   if(argc == 2)
  89.     {
  90.       if(strcasecmp(argv[1], "startdsr") == 0)
  91. {
  92. #ifdef DSR_CACHE_STATS
  93.   mh.start();
  94. #endif
  95.   return TCL_OK;
  96. }
  97.     }
  98.   else if(argc == 3) 
  99.     {    
  100.       if (strcasecmp(argv[1], "ip-addr") == 0) {
  101. net_id = ID(atoi(argv[2]), ::IP);
  102. return TCL_OK;
  103.       }
  104.       else if(strcasecmp(argv[1], "mac-addr") == 0) {
  105. MAC_id = ID(atoi(argv[2]), ::MAC);
  106.       return TCL_OK;
  107.       }
  108.       
  109.       /* must be a looker up */
  110.       TclObject *obj = (TclObject*) TclObject::lookup(argv[2]);
  111.       if(obj == 0)
  112. return TCL_ERROR;
  113.       
  114.       if(strcasecmp(argv[1], "log-target") == 0 || 
  115.  strcasecmp(argv[1], "tracetarget") == 0) {
  116. logtarget = (Trace*) obj;
  117. return TCL_OK;
  118.       }
  119.       return TCL_ERROR;
  120.     }
  121.   
  122.   return TclObject::command(argc, argv);
  123. }
  124. void
  125. RouteCache::trace(char* fmt, ...)
  126. {
  127.   va_list ap;
  128.   
  129.   if (!logtarget) return;
  130.   va_start(ap, fmt);
  131.   vsprintf(logtarget->pt_->buffer(), fmt, ap);
  132.   logtarget->pt_->dump();
  133.   va_end(ap);
  134. }
  135. void
  136. RouteCache::dump(FILE *out)
  137. {
  138.   fprintf(out, "Route cache dump unimplementedn");
  139.   fflush(out);
  140. }
  141. ///////////////////////////////////////////////////////////////////////////
  142. extern bool cache_ignore_hints;
  143. extern bool cache_use_overheard_routes;
  144. #define STOP_PROCESSING 0
  145. #define CONT_PROCESSING 1
  146. int
  147. RouteCache::pre_addRoute(const Path& route, Path& rt,
  148.  Time t, const ID& who_from)
  149. {
  150.   assert(!(net_id == invalid_addr));
  151.   
  152.   if (route.length() < 2)
  153.     return STOP_PROCESSING; // we laugh in your face
  154.   if(verbose_debug)
  155.     trace("SRC %.9f _%s_ adding rt %s from %s",
  156.   Scheduler::instance().clock(), net_id.dump(),
  157.   route.dump(), who_from.dump());
  158.   if (route[0] != net_id && route[0] != MAC_id) 
  159.     {
  160.       fprintf(stderr,"%.9f _%s_ adding bad route to cache %s %sn",
  161.       t, net_id.dump(), who_from.dump(), route.dump());
  162.       return STOP_PROCESSING;
  163.     }
  164.      
  165.   rt = (Path&) route; // cast away const Path&
  166.   rt.owner() = who_from;
  167.   Link_Type kind = LT_TESTED;
  168.   for (int c = 0; c < rt.length(); c++)
  169.     {
  170.       rt[c].log_stat = LS_UNLOGGED;
  171.       if (rt[c] == who_from) kind = LT_UNTESTED; // remaining ids came from $
  172.       rt[c].link_type = kind;
  173.       rt[c].t = t;
  174.     }
  175.   return CONT_PROCESSING;
  176. }
  177. int
  178. RouteCache::pre_noticeRouteUsed(const Path& p, Path& stub,
  179. Time t, const ID& who_from)
  180. {
  181.   int c;
  182.   bool first_tested = true;
  183.   if (p.length() < 2)
  184.   return STOP_PROCESSING;
  185.   if (cache_ignore_hints == true)
  186.   return STOP_PROCESSING;
  187.   for (c = 0; c < p.length() ; c++) {
  188.   if (p[c] == net_id || p[c] == MAC_id) break;
  189.   }
  190.   if (c == p.length() - 1)
  191.   return STOP_PROCESSING; // path contains only us
  192.   if (c == p.length()) { // we aren't in the path...
  193.   if (cache_use_overheard_routes) {
  194.   // assume a link from us to the person who
  195.   // transmitted the packet
  196.   if (p.index() == 0) {
  197.    /* must be a route request */
  198.   return STOP_PROCESSING;
  199.   }
  200.   stub.reset();
  201.   stub.appendToPath(net_id);
  202.   int i = p.index() - 1;
  203.   for ( ; i < p.length() && !stub.full() ; i++) {
  204.   stub.appendToPath(p[i]);
  205.   }
  206.   // link to xmiter might be unidirectional
  207.   first_tested = false;
  208.   }
  209.   else {
  210.   return STOP_PROCESSING;
  211.   }
  212.   }
  213.   else { // we are in the path, extract the subpath
  214.   CopyIntoPath(stub, p, c, p.length() - 1);
  215.   }
  216.   Link_Type kind = LT_TESTED;
  217.   for (c = 0; c < stub.length(); c++) {
  218.   stub[c].log_stat = LS_UNLOGGED;
  219.    // remaining ids came from $
  220.   if (stub[c] == who_from)
  221.   kind = LT_UNTESTED;
  222.   stub[c].link_type = kind;
  223.   stub[c].t = t;
  224.   }
  225.   if (first_tested == false)
  226.   stub[0].link_type = LT_UNTESTED;
  227.   return CONT_PROCESSING;
  228. }
  229. #undef STOP_PROCESSING
  230. #undef CONT_PROCESSING
  231. //////////////////////////////////////////////////////////////////////
  232. #ifdef DSR_CACHE_STATS
  233. void
  234. MobiHandler::handle(Event *) {
  235.         cache->periodic_checkCache();
  236.         Scheduler::instance().schedule(this, &intr, interval);
  237. }
  238. int
  239. RouteCache::checkRoute_logall(Path *p, int action, int start)
  240. {
  241.   int c;
  242.   int subroute_bad_count = 0;
  243.   if(p->length() == 0)
  244.     return 0;
  245.   assert(p->length() >= 2);
  246.   assert(action == ACTION_DEAD_LINK ||
  247.          action == ACTION_EVICT ||
  248.          action == ACTION_FIND_ROUTE);
  249.   for (c = start; c < p->length() - 1; c++)
  250.     {
  251.       if (God::instance()->hops((*p)[c].getNSAddr_t(), (*p)[c+1].getNSAddr_t()) != 1)
  252. {
  253.           trace("SRC %.9f _%s_ %s [%d %d] %s->%s dead %d %.9f",
  254.                 Scheduler::instance().clock(), net_id.dump(),
  255.                 action_name[action], p->length(), c,
  256.                 (*p)[c].dump(), (*p)[c+1].dump(),
  257.                 (*p)[c].link_type, (*p)[c].t);
  258.           if(subroute_bad_count == 0)
  259.             subroute_bad_count = p->length() - c - 1;
  260. }
  261.     }
  262.   return subroute_bad_count;
  263. }
  264. #endif /* DSR_CACHE_STAT */