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 #include "routing-module.h"
00031 #include<ip.h>
00032
00033
00034
00035 RouteReachable::RouteReachable(int source) : ClMessage(ROUTEREACHABLE_VERBOSITY, CL_ROUTEMESSAGE, UNICAST, 0), info_(0), nInfo_(0), infoLen_(0), modules_(0), nModules_(0), myIP_(0), processed_(0)
00036 {
00037 memset(addr_, 0, MRCL_ADDRESS_MAX_LEN);
00038 setSource(source);
00039 }
00040
00041 RouteReachable::~RouteReachable()
00042 {
00043 if(infoLen_)
00044 delete [] info_;
00045 }
00046
00047 void RouteReachable::setAddress(char *a)
00048 {
00049 MrclAddress::storeAddr(addr_, a);
00050 }
00051
00052 char *RouteReachable::getAddress()
00053 {
00054 return addr_;
00055 }
00056
00057 void RouteReachable::addRouteInfo(RouteInfo *i)
00058 {
00059 int id = i->getModuleId();
00060 if(id < nModules_ && modules_[id]>=0)
00061 {
00062 info_[modules_[id]] = i;
00063 return;
00064 }
00065 if(nInfo_ >= infoLen_)
00066 {
00067 RouteInfo **tmp = new RouteInfo*[infoLen_ + ROUTE_REACHABLE_ALLOC_INFO_PER_TIME];
00068 for(int j = 0; j < infoLen_; j++)
00069 {
00070 if(j < nInfo_)
00071 tmp[j] = info_[j];
00072 }
00073 if(infoLen_ > 0)
00074 delete [] info_;
00075 info_ = tmp;
00076 infoLen_ += ROUTE_REACHABLE_ALLOC_INFO_PER_TIME;
00077 }
00078
00079 info_[nInfo_++] = i;
00080
00081 if(id >= nModules_)
00082 {
00083 int *tmp = new int[id + 1];
00084 for(int j = 0; j <= id; j++)
00085 {
00086 if(j < nModules_)
00087 tmp[j] = modules_[j];
00088 else
00089 tmp[j] = -1;
00090 }
00091 if(nModules_ > 0)
00092 delete [] modules_;
00093 modules_ = tmp;
00094 nModules_ = id + 1;
00095 }
00096 modules_[id] = nInfo_ - 1;
00097
00098 }
00099
00100 int RouteReachable::length()
00101 {
00102 return nInfo_;
00103 }
00104
00105 RouteInfo *RouteReachable::getRouteInfo(int id)
00106 {
00107
00108 if(id >= nModules_)
00109 return 0;
00110 int i = modules_[id];
00111
00112 if(i < 0)
00113 return 0;
00114
00115 return info_[i];
00116 }
00117
00118 RouteInfo **RouteReachable::getRouteInfo()
00119 {
00120 return info_;
00121 }
00122
00123 void RouteReachable::empty()
00124 {
00125 memset(info_, 0, sizeof(RouteInfo) * nInfo_);
00126 myIP_ = 0;
00127 nInfo_ = 0;
00128 for(int j = 0; j < nModules_; j++)
00129 modules_[j] = -1;
00130 }
00131
00132 void RouteReachable::setMyIP()
00133 {
00134 myIP_ = 1;
00135 }
00136
00137 int RouteReachable::isMyIP()
00138 {
00139 return myIP_;
00140 }
00141
00142 void RouteReachable::processed(int value)
00143 {
00144 processed_ = value;
00145 }
00146
00147 int RouteReachable::processed()
00148 {
00149 return processed_;
00150 }
00151
00152 int RouteReachable::getIndex(int id)
00153 {
00154 if(id >= nModules_)
00155 return -1;
00156 return modules_[id];
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 MrclRouting::MrclRouting() : rr_(0), lastGetConfiguration_(-1), delayUp_(0.0), delayDown_(0.0), nAddresses_(0)
00175 {
00176 bind("overheadLength_", &overheadLength_);
00177 }
00178
00179 MrclRouting::~MrclRouting()
00180 {
00181 if(rr_)
00182 delete rr_;
00183 }
00184
00185 int MrclRouting::command(int argc, const char *const* argv)
00186 {
00187 Tcl& tcl = Tcl::instance();
00188 if(argc == 3)
00189 {
00190 if(strcasecmp(argv[1], "id_") == 0)
00191 {
00192 int id = atoi(argv[2]);
00193 rr_ = new RouteReachable(id);
00194 }
00195 else if (strcasecmp(argv[1],"getAddr")==0)
00196 {
00197 int addrNum = atoi(argv[2]);
00198 if (addrNum-1>nAddresses())
00199 {
00200 printf("Error AodvModule %s command, ask for an unexisting address (%d, while max is %d)\n", argv[1], addrNum, nAddresses());
00201 return TCL_ERROR;
00202 }
00203 MrclAddress *addr = getAddress(addrNum-1);
00204 if (addr==0)
00205 return TCL_ERROR;
00206 int len = addr->strlen() + 2;
00207 char *str = new char[len];
00208 addr->toString(str, len);
00209 tcl.resultf("%s", str);
00210 return TCL_OK;
00211 }
00212 else if (strcasecmp(argv[1],"setAddr")==0)
00213 {
00214 MrclAddress *addr = (MrclAddress *)(TclObject::lookup(argv[2]));
00215 if (addr==0)
00216 {
00217 printf("AodvModule::command(%s), error in address lookup\n", argv[1]);
00218 return TCL_ERROR;
00219 }
00220 int len = addr->strlen() + 2;
00221 char *str = new char[len];
00222 addr->toString(str, len);
00223 addAddress(addr);
00224 if(debug_>5)
00225 {
00226 printf("AodvModule::command(%s) -- setAddr(%d) = %s\n", argv[1], nAddresses(), str);
00227 }
00228 return TCL_OK;
00229 }
00230 }
00231 return Module::command(argc, argv);
00232 }
00233
00234 int MrclRouting::getConfiguration(char *a, int source)
00235 {
00236 for(int i = 0; i < nAddresses_; i++)
00237 {
00238 if(MrclAddress::areEqual(a, addresses_[i]->getAddr()))
00239 {
00240 return -1;
00241 }
00242 }
00243 if(source < 0)
00244 rr_->empty();
00245 rr_->setAddress(a);
00246 Metric **m;
00247 int r = canIReach(a, &m);
00248 RouteInfo *i = new RouteInfo();
00249 i->setModuleId(getId());
00250 if(r != 0)
00251 {
00252 if(r > 0)
00253 {
00254 i->setReachability(REACHABLE);
00255 }
00256 else
00257 {
00258 i->setReachability(MAYBE);
00259 r *= -1;
00260 }
00261
00262 for(int j = 0; j < r; j++)
00263 {
00264 i->addMetric(m[j]);
00265 }
00266 }
00267 else
00268 {
00269 i->setReachability(UNREACHABLE);
00270 }
00271
00272 rr_->addRouteInfo(i);
00273 for(int j = 0; j < getUpLaySAPnum(); j++)
00274 {
00275 int id = getUpLaySAP(j)->getModuleUpId();
00276
00277 if(id != source)
00278 {
00279 rr_->processed(0);
00280
00281 rr_->setDest(id);
00282 sendSyncClMsgUp(rr_);
00283 if(rr_->isMyIP())
00284 {
00285 return -1;
00286 }
00287 }
00288 if(rr_->processed() || (id >= 0 && id == source))
00289 {
00290 printf("\t\t\tmodule %d addfather %d (source=%d) %p\n",getId(),id,source, rr_->getRouteInfo(id));
00291 rr_->getRouteInfo(getId())->addFather(rr_->getRouteInfo(id));
00292 }
00293
00294
00295
00296
00297 }
00298 for(int j = 0; j < getDownLaySAPnum(); j++)
00299 {
00300 int id = getDownLaySAP(j)->getModuleDownId();
00301 if(id != source)
00302 {
00303 rr_->processed(0);
00304 rr_->setDest(id);
00305 sendSyncClMsgDown(rr_);
00306 if(rr_->isMyIP())
00307 {
00308 return -1;
00309 }
00310 }
00311 if(rr_->processed() || (id >= 0 && id == source))
00312 {
00313
00314 rr_->getRouteInfo(getId())->addChild(rr_->getRouteInfo(id));
00315 }
00316
00317
00318
00319
00320 }
00321 return rr_->length();
00322
00323 }
00324
00325 int MrclRouting::recvSyncClMsg(ClMessage *m)
00326 {
00327 if(m->type() == CL_ROUTEMESSAGE)
00328 {
00329 RouteReachable *r = (RouteReachable *)m;
00330 r->processed(1);
00331 RouteInfo **info = r->getRouteInfo();
00332 rr_->empty();
00333 for(int i = 0; i < r->length(); i++)
00334 {
00335 printf("crLay.... addRouteInfo %d\n", info[i]->getModuleId());
00336 rr_->addRouteInfo(info[i]);
00337 }
00338
00339 int nInfo = getConfiguration(((RouteReachable *)m)->getAddress(), m->getSource());
00340 if(nInfo < 0)
00341 {
00342 ((RouteReachable *)m)->setMyIP();
00343 }
00344 else
00345 {
00346 for(int i = 0; i < nInfo; i++)
00347 {
00348 ((RouteReachable *)m)->addRouteInfo((rr_->getRouteInfo())[i]);
00349 }
00350 }
00351 return 0;
00352 }
00353 return Module::recvSyncClMsg(m);
00354 }
00355
00356 int MrclRouting::findNextLeaf(int i)
00357 {
00358 RouteInfo **info = rr_->getRouteInfo();
00359 for(int j = i + 1; j < rr_->length(); j++)
00360 {
00361
00362 if(info[j]->getNChild() == 0)
00363 return info[j]->getModuleId();
00364 }
00365 return -1;
00366 }
00367
00368 class MetricComparator : public Comparator
00369 {
00370 public:
00371 virtual int isLess(void *a, void *b)
00372 {
00373 ModuleRoute *ma = (ModuleRoute *)a;
00374 ModuleRoute *mb = (ModuleRoute *)b;
00375 return (ma->w < mb->w);
00376 }
00377 };
00378
00379 int MrclRouting::getRoute(MrclAddress *a, Packet *p, int i)
00380 {
00381 getRoute(a->getAddr(), p, i);
00382 }
00383
00384 int MrclRouting::getRoute(char *a, Packet *p, int i)
00385 {
00386 if(lastGetConfiguration_ == Scheduler::instance().clock() && MrclAddress::areEqual(a, rr_->getAddress()))
00387 {
00388
00389 if(rr_->isMyIP())
00390 {
00391 RoutingHdr *rhdr = HDR_ROUTING(p);
00392 rhdr->setSendup();
00393 return -1;
00394 }
00395 if(i < routes_.count())
00396 {
00397 RoutingHdr *rhdr = HDR_ROUTING(p);
00398 rhdr->clearModuleRoute();
00399 ModuleRoute *mr = (ModuleRoute *)routes_.get(i);
00400 for(int k = mr->modules.count() - 1; k >= 0; k--)
00401 {
00402 RouteInfo *info = (RouteInfo *)(mr->modules.get(k));
00403 rhdr->addModuleRoute(mr->modules.count() - 1 - k, info->getModuleId());
00404 }
00405 }
00406
00407 return routes_.count();
00408 }
00409
00410
00411 getConfiguration(a);
00412 lastGetConfiguration_ = Scheduler::instance().clock();
00413
00414 if(rr_->isMyIP())
00415 {
00416 RoutingHdr *rhdr = HDR_ROUTING(p);
00417 rhdr->setSendup();
00418 return -1;
00419 }
00420 int j = findNextLeaf();
00421
00422
00423 for(int k = 0; k < routes_.count(); k++)
00424 {
00425 ModuleRoute *tmp = (ModuleRoute *)routes_.get(k);
00426 delete tmp;
00427 }
00428 routes_.clear();
00429 int c = 0;
00430 while(j >= 0)
00431 {
00432 RouteInfo *info = rr_->getRouteInfo(j);
00433 if(info->reachability() != UNREACHABLE)
00434 {
00435 RouteInfo *f = info->getFather();
00436 MetricList l;
00437 ModuleRoute *mr = new ModuleRoute;
00438 mr->modules.set(0,(void *)info);
00439 for(int k = 0; k < info->getNMetric(); k++)
00440 {
00441 l.addMetric(info->getMetric(k));
00442 }
00443 int d = 1;
00444 while(f)
00445 {
00446 mr->modules.set(d++,(void *)f);
00447
00448 if(f->getNMetric() > 0)
00449 {
00450 for(int k = 0; k < f->getNMetric(); k++)
00451 {
00452 f->getMetric(k)->clearParam();
00453 f->getMetric(k)->insertParam(&l);
00454 }
00455 l.empty();
00456 for(int k = 0; k < f->getNMetric(); k++)
00457 {
00458 l.addMetric(f->getMetric(k));
00459 }
00460 }
00461 f = f->getFather();
00462 }
00463 double w = 0.0;
00464 for(int k = 0; k < l.length(); k++)
00465 {
00466 w += l.getMetric(k)->value(p);
00467 }
00468 mr->w = w;
00469 mr->reachability = info->reachability();
00470 if (debug_>10)
00471 printf("[RoutingModule] Module %d Add new route %d (j=%d) metric %f\n", getId(), c, j, mr->w);
00472 routes_.set(c++,(void *)mr);
00473 }
00474
00475 j = findNextLeaf(rr_->getIndex(j));
00476
00477 }
00478
00479 MetricComparator comp;
00480
00481
00482 routes_.sort(&comp);
00483
00484
00485
00486 int ret = routes_.count();
00487 if(i < ret)
00488 {
00489 RoutingHdr *rhdr = HDR_ROUTING(p);
00490 rhdr->clearModuleRoute();
00491 rhdr->setSendup();
00492 ModuleRoute *mr = (ModuleRoute *)routes_.get(i);
00493 for(int k = mr->modules.count() - 1; k >= 0; k--)
00494 {
00495 RouteInfo *info = (RouteInfo *)(mr->modules.get(k));
00496 rhdr->addModuleRoute(mr->modules.count() - 1 - k, info->getModuleId());
00497 if (debug_>10)
00498 printf("[RoutingModule::getRoute] - ADDMODULEROUTE %d (%d)\n", info->getModuleId(), mr->modules.count());
00499 }
00500 if (mr->reachability==MAYBE) ret *= -1;
00501 }
00502
00503 return ret;
00504 }
00505
00506
00507 void MrclRouting::recv(Packet *p)
00508 {
00509 if (controlPacket(p))
00510 {
00511
00512
00513 return;
00514 }
00515 RoutingHdr* mrhdr = HDR_ROUTING(p);
00516 hdr_cmn* ch = hdr_cmn::access(p);
00517 int nModule = mrhdr->moduleRouteCount();
00518 if (debug_>10)
00519 printf("\t\tModule %d - recv - nmodule=%d\n", getId(), nModule);
00520 if (nModule==0)
00521 {
00522 if (mrhdr->sendup()==0)
00523 {
00524
00525
00526 if(ch->direction() == hdr_cmn::DOWN)
00527 {
00528
00529 assert(nAddresses()>0);
00530 MrclAddress::storeAddr(mrhdr->saddr(), addresses_[0]->getAddr());
00531 }
00532 forward(p);
00533 }
00534 else
00535 {
00536
00537 sendUp(p, delayUp_);
00538 }
00539 }
00540 else
00541 {
00542
00543 int nextModule = -1;
00544 for(int i=0; i<nModule; i++)
00545 {
00546 if (mrhdr->getModuleRoute(i)==getId())
00547 {
00548 if (i < nModule-1)
00549 {
00550
00551 nextModule = mrhdr->getModuleRoute(i+1);
00552 }
00553 else
00554 {
00555
00556 nextModule = mrhdr->getModuleRoute(i);
00557 mrhdr->clearModuleRoute();
00558 char *nextHop = getNextHop(p);
00559 if(nextHop)
00560 {
00561 MrclAddress::storeAddr(mrhdr->nexthop(), nextHop);
00562
00563
00564 }
00565 else
00566 {
00567
00568 resolve(p);
00569 }
00570
00571 }
00572 break;
00573 }
00574 }
00575 if (debug_>10)
00576 printf("\t\tModule %d - recv - nextModule=%d\n",getId(), nextModule);
00577 if (nextModule==-1)
00578 {
00579
00580 sendUp(p, delayUp_);
00581 }
00582 else if(nextModule == getId())
00583 {
00584 sendDown(p, delayDown_);
00585 }
00586 else
00587 {
00588
00589 sendDown(nextModule, p, delayDown_);
00590 }
00591 }
00592 }
00593
00594 void MrclRouting::addAddress(MrclAddress *a)
00595 {
00596 addresses_ = (MrclAddress **)realloc(addresses_, nAddresses_ * sizeof(MrclAddress *), (nAddresses_ + 1) * sizeof(MrclAddress *));
00597 addresses_[nAddresses_++] = a;
00598 }
00599
00600 MrclAddress *MrclRouting::getAddress(int i)
00601 {
00602 if(i < 0 || i >= nAddresses_)
00603 return 0;
00604 return addresses_[i];
00605 }
00606
00607 int MrclRouting::nAddresses()
00608 {
00609 return nAddresses_;
00610 }
00611
00612 int MrclRouting::isMyAddress(char *addr)
00613 {
00614 for(int i = 0; i < nAddresses();i++)
00615 {
00616 if(getAddress(i)->isEqual(addr))
00617 return 1;
00618 }
00619 return 0;
00620 }