routecache.cc

Go to the documentation of this file.
00001 
00002 /*
00003  * routecache.cc
00004  * Copyright (C) 2000 by the University of Southern California
00005  * $Id: routecache.cc,v 1.7 2005/08/25 18:58:05 johnh Exp $
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  *
00020  *
00021  * The copyright of this module includes the following
00022  * linking-with-specific-other-licenses addition:
00023  *
00024  * In addition, as a special exception, the copyright holders of
00025  * this module give you permission to combine (via static or
00026  * dynamic linking) this module with free software programs or
00027  * libraries that are released under the GNU LGPL and with code
00028  * included in the standard release of ns-2 under the Apache 2.0
00029  * license or under otherwise-compatible licenses with advertising
00030  * requirements (or modified versions of such code, with unchanged
00031  * license).  You may copy and distribute such a system following the
00032  * terms of the GNU GPL for this module and the licenses of the
00033  * other code concerned, provided that you include the source code of
00034  * that other code when and as the GNU GPL requires distribution of
00035  * source code.
00036  *
00037  * Note that people who make modified versions of this module
00038  * are not obligated to grant this special exception for their
00039  * modified versions; it is their choice whether to do so.  The GNU
00040  * General Public License gives permission to release a modified
00041  * version without this exception; this exception also makes it
00042  * possible to release a modified version which carries forward this
00043  * exception.
00044  *
00045  */
00046 
00047 /*
00048  * Ported from CMU/Monarch's code, appropriate copyright applies.  
00049  * routecache.cc
00050  *   handles routes
00051  */
00052 
00053 extern "C" {
00054 #include <stdio.h>
00055 #include <stdarg.h>
00056 };
00057 
00058 #undef DEBUG
00059 
00060 #include "path.h"
00061 #include "routecache.h"
00062 #include <god.h>
00063 
00064 static const int verbose_debug = 0;
00065 
00066 /*===============================================================
00067   OTcl definition
00068 ----------------------------------------------------------------*/
00069 static class RouteCacheClass : public TclClass {
00070 public:
00071         RouteCacheClass() : TclClass("RouteCache") {}
00072         TclObject* create(int, const char*const*) {
00073                 return makeRouteCache();
00074         }
00075 } class_RouteCache;
00076 
00077 /*===============================================================
00078  Constructors
00079 ----------------------------------------------------------------*/
00080 RouteCache::RouteCache():
00081 #ifdef DSR_CACHE_STATS
00082     mh(this),
00083 #endif
00084     MAC_id(invalid_addr), net_id(invalid_addr)
00085 {
00086 #ifdef DSR_CACHE_STATS
00087     stat.reset();
00088 #endif
00089 }
00090 
00091 RouteCache::~RouteCache()
00092 {
00093 }
00094 
00095 int
00096 RouteCache::command(int argc, const char*const* argv)
00097 {
00098   if(argc == 2)
00099     {
00100       if(strcasecmp(argv[1], "startdsr") == 0)
00101     {
00102 #ifdef DSR_CACHE_STATS
00103       mh.start();
00104 #endif
00105       return TCL_OK;
00106     }
00107     }
00108   else if(argc == 3) 
00109     {    
00110       if (strcasecmp(argv[1], "ip-addr") == 0) {
00111     net_id = ID(atoi(argv[2]), ::IP);
00112     return TCL_OK;
00113       }
00114       else if(strcasecmp(argv[1], "mac-addr") == 0) {
00115     MAC_id = ID(atoi(argv[2]), ::MAC);
00116       return TCL_OK;
00117       }
00118       
00119       /* must be a looker up */
00120       TclObject *obj = (TclObject*) TclObject::lookup(argv[2]);
00121       if(obj == 0)
00122     return TCL_ERROR;
00123       
00124       if(strcasecmp(argv[1], "log-target") == 0 || 
00125      strcasecmp(argv[1], "tracetarget") == 0) {
00126     logtarget = (Trace*) obj;
00127     return TCL_OK;
00128       }
00129 
00130       return TCL_ERROR;
00131     }
00132   
00133   return TclObject::command(argc, argv);
00134 }
00135 
00136 void
00137 RouteCache::trace(char* fmt, ...)
00138 {
00139   va_list ap;
00140   
00141   if (!logtarget) return;
00142 
00143   va_start(ap, fmt);
00144   vsprintf(logtarget->pt_->buffer(), fmt, ap);
00145   logtarget->pt_->dump();
00146   va_end(ap);
00147 }
00148 
00149 
00150 void
00151 RouteCache::dump(FILE *out)
00152 {
00153   fprintf(out, "Route cache dump unimplemented\n");
00154   fflush(out);
00155 }
00156 
00158 
00159 extern bool cache_ignore_hints;
00160 extern bool cache_use_overheard_routes;
00161 
00162 #define STOP_PROCESSING 0
00163 #define CONT_PROCESSING 1
00164 
00165 int
00166 RouteCache::pre_addRoute(const Path& route, Path& rt,
00167              Time t, const ID& who_from)
00168 {
00169   assert(!(net_id == invalid_addr));
00170   
00171   if (route.length() < 2)
00172     return STOP_PROCESSING; // we laugh in your face
00173 
00174   if(verbose_debug)
00175     trace("SRC %.9f _%s_ adding rt %s from %s",
00176       Scheduler::instance().clock(), net_id.dump(),
00177       route.dump(), who_from.dump());
00178 
00179   if (route[0] != net_id && route[0] != MAC_id) 
00180     {
00181       fprintf(stderr,"%.9f _%s_ adding bad route to cache %s %s\n",
00182           t, net_id.dump(), who_from.dump(), route.dump());
00183       return STOP_PROCESSING;
00184     }
00185          
00186   rt = (Path&) route;   // cast away const Path&
00187   rt.owner() = who_from;
00188 
00189   Link_Type kind = LT_TESTED;
00190   for (int c = 0; c < rt.length(); c++)
00191     {
00192       rt[c].log_stat = LS_UNLOGGED;
00193       if (rt[c] == who_from) kind = LT_UNTESTED; // remaining ids came from $
00194       rt[c].link_type = kind;
00195       rt[c].t = t;
00196     }
00197 
00198   return CONT_PROCESSING;
00199 }
00200 
00201 int
00202 RouteCache::pre_noticeRouteUsed(const Path& p, Path& stub,
00203                 Time t, const ID& who_from)
00204 {
00205   int c;
00206   bool first_tested = true;
00207 
00208   if (p.length() < 2)
00209       return STOP_PROCESSING;
00210   if (cache_ignore_hints == true)
00211       return STOP_PROCESSING;
00212 
00213   for (c = 0; c < p.length() ; c++) {
00214       if (p[c] == net_id || p[c] == MAC_id) break;
00215   }
00216 
00217   if (c == p.length() - 1)
00218       return STOP_PROCESSING; // path contains only us
00219 
00220   if (c == p.length()) { // we aren't in the path...
00221       if (cache_use_overheard_routes) {
00222           // assume a link from us to the person who
00223           // transmitted the packet
00224           if (p.index() == 0) {
00225                /* must be a route request */
00226               return STOP_PROCESSING;
00227           }
00228 
00229           stub.reset();
00230           stub.appendToPath(net_id);
00231           int i = p.index() - 1;
00232           for ( ; i < p.length() && !stub.full() ; i++) {
00233               stub.appendToPath(p[i]);
00234           }
00235           // link to xmiter might be unidirectional
00236           first_tested = false;
00237       }
00238       else {
00239           return STOP_PROCESSING;
00240       }
00241   }
00242   else { // we are in the path, extract the subpath
00243       CopyIntoPath(stub, p, c, p.length() - 1);
00244   }
00245 
00246   Link_Type kind = LT_TESTED;
00247   for (c = 0; c < stub.length(); c++) {
00248       stub[c].log_stat = LS_UNLOGGED;
00249 
00250        // remaining ids came from $
00251       if (stub[c] == who_from)
00252           kind = LT_UNTESTED;
00253       stub[c].link_type = kind;
00254       stub[c].t = t;
00255   }
00256   if (first_tested == false)
00257       stub[0].link_type = LT_UNTESTED;
00258 
00259   return CONT_PROCESSING;
00260 }
00261 
00262 #undef STOP_PROCESSING
00263 #undef CONT_PROCESSING
00264 
00266 
00267 #ifdef DSR_CACHE_STATS
00268 
00269 void
00270 MobiHandler::handle(Event *) {
00271         cache->periodic_checkCache();
00272         Scheduler::instance().schedule(this, &intr, interval);
00273 }
00274 
00275 int
00276 RouteCache::checkRoute_logall(Path *p, int action, int start)
00277 {
00278   int c;
00279   int subroute_bad_count = 0;
00280 
00281   if(p->length() == 0)
00282     return 0;
00283   assert(p->length() >= 2);
00284 
00285   assert(action == ACTION_DEAD_LINK ||
00286          action == ACTION_EVICT ||
00287          action == ACTION_FIND_ROUTE);
00288 
00289   for (c = start; c < p->length() - 1; c++)
00290     {
00291       if (God::instance()->hops((*p)[c].getNSAddr_t(), (*p)[c+1].getNSAddr_t()) != 1)
00292     {
00293           trace("SRC %.9f _%s_ %s [%d %d] %s->%s dead %d %.9f",
00294                 Scheduler::instance().clock(), net_id.dump(),
00295                 action_name[action], p->length(), c,
00296                 (*p)[c].dump(), (*p)[c+1].dump(),
00297                 (*p)[c].link_type, (*p)[c].t);
00298 
00299           if(subroute_bad_count == 0)
00300             subroute_bad_count = p->length() - c - 1;
00301     }
00302     }
00303   return subroute_bad_count;
00304 }
00305 
00306 #endif /* DSR_CACHE_STAT */
00307 

Generated on Tue Mar 6 16:47:50 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6