00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
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
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
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
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;
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;
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;
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;
00219
00220 if (c == p.length()) {
00221 if (cache_use_overheard_routes) {
00222
00223
00224 if (p.index() == 0) {
00225
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
00236 first_tested = false;
00237 }
00238 else {
00239 return STOP_PROCESSING;
00240 }
00241 }
00242 else {
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
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
00307