routing-module.cc

00001 /*
00002  * Copyright (c) 2008 Regents of the SIGNET lab, University of Padova.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University of Padova (SIGNET lab) nor the 
00014  *    names of its contributors may be used to endorse or promote products 
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00018  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
00019  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00020  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00021  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00023  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00024  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00026  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00027  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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         //printf("ninfo %d infoLen %d Nmetric %d \n", nInfo_, infoLen_, i->getNMetric());
00079         info_[nInfo_++] = i;
00080         //int id = i->getModuleId();
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         //printf("Updated modules[%d] = %d\n", id, nInfo_ -1);
00098 }
00099 
00100 int RouteReachable::length()
00101 {
00102         return nInfo_;
00103 }
00104 
00105 RouteInfo *RouteReachable::getRouteInfo(int id)
00106 {
00107 //      printf("asks for routeInfo %d nModules_%d \n", id, nModules_);
00108         if(id >= nModules_)
00109                 return 0;
00110         int i = modules_[id];
00111 //      printf("module_[%d] %d\n", id, modules_[id]);
00112         if(i < 0)
00113                 return 0;
00114 //      printf("info_[i] %p\n", info_[i]);
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 // RouteReachableTracer::RouteReachableTracer() : ClMessageTracer(CL_ROUTEMESSAGE)
00160 // {
00161 // }
00162 // 
00163 // void RouteReachableTracer::format(ClMessage *m, ClSAP *sap)
00164 // {
00165 //      if (m->type()!=CL_ROUTEMESSAGE)
00166 //              return;
00167 //      
00168 //      writeTrace(sap, " [CL_ROUTE_MSG] ");
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         //printf("Module %d addRouteInfo\n", getId());
00272         rr_->addRouteInfo(i);
00273         for(int j = 0; j < getUpLaySAPnum(); j++)
00274         {
00275                 int id = getUpLaySAP(j)->getModuleUpId();
00276 //              printf("Try to upSAP %d module %d source %d\n", j, id, source);
00277                 if(id != source)
00278                 {
00279                         rr_->processed(0);
00280 //                      printf("Try to send to %d\n", id);
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 //              else
00294 //              {
00295 //                      printf("RM %d module %d is not a father :-(\n", getId(), getDownLaySAP(j)->getModuleUpId());
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                         //printf("\t\t\tmodule %d addchild %d (source=%d)\n",getId(),id,source);
00314                         rr_->getRouteInfo(getId())->addChild(rr_->getRouteInfo(id));
00315                 }
00316 //              else
00317 //              {
00318 //                      printf("RM %d Module %d is not child :-(\n", getId(), getDownLaySAP(j)->getModuleDownId());
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                 //printf("RoutingModule %d has rx a CL_ROUTEMESSAGE\n", getId());
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                 //printf("\t\ti=%d, j=%d, id=%d, nch=%d\n", i, j, info[j]->getModuleId(), info[j]->getNChild());
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                 //if we have already compute the path
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         //else
00410         //getConfiguration(a, getId());
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         //printf("HERE (%d) rr->length = %d\n", getId(), rr_->length());
00422         // Dealloc
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 //                              printf("\tFIND A FATHER %d (%i)\n", f->getModuleId(), mr->modules.count());
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                 //printf("\t\trr_-getIndex(%d)=%d ",j, rr_->getIndex(j));
00475                 j = findNextLeaf(rr_->getIndex(j));
00476                 //printf("j=%d\n",j);
00477         }
00478         // Resort Routes
00479         MetricComparator comp;
00480 //      for(int k = 0; k< routes_.count(); k++)
00481 //              printf("BEFORE_SORT route %d etric %f\n", k, ((ModuleRoute *)routes_.get(k))->w);
00482         routes_.sort(&comp);
00483 //      for(int k = 0; k< routes_.count(); k++)
00484 //              printf("AFTER_SORT route %d etric %f (%d)\n", k, ((ModuleRoute *)routes_.get(k))->w, ((ModuleRoute *)routes_.get(k))->modules.count());
00485         // Return the modules
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                 // this is a control packet of this routing module -> just processed it -> drop it
00512                 //drop(p, CTRL_PKT_DROP_VERBOSITY, CTRL_PKT_DROP_MSG);
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                         // Packet has not been yet solved -> try to solve it
00525                         // here the packet has to be solved for the 1st time
00526                         if(ch->direction() == hdr_cmn::DOWN)
00527                         {
00528                                 // first routing module which processes the packet set the source address
00529                                 assert(nAddresses()>0);
00530                                 MrclAddress::storeAddr(mrhdr->saddr(), addresses_[0]->getAddr());
00531                         }
00532                         forward(p);
00533                 }
00534                 else
00535                 {
00536                         // Packet has been solved -> not for me -> send Up
00537                         sendUp(p, delayUp_);
00538                 }
00539         }
00540         else
00541         {
00542                 // go through the Module Id list
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                                         // get the next ModuleId in the path
00551                                         nextModule = mrhdr->getModuleRoute(i+1);
00552                                 }
00553                                 else
00554                                 {
00555                                         // this is the last Routing Module: clean the Module Id list in the packet header and solve the routing
00556                                         nextModule = mrhdr->getModuleRoute(i);
00557                                         mrhdr->clearModuleRoute();
00558                                         char *nextHop = getNextHop(p);
00559                                         if(nextHop)
00560                                         {
00561                                                 MrclAddress::storeAddr(mrhdr->nexthop(), nextHop);
00562 //                                              setOldAddresses(p);
00563                                                 // here the packet has to be solved from the leaf module
00564                                         }
00565                                         else
00566                                         {
00567                                                 // maybe someone has chosen this module when he said that the destination is MAYBE reacheable
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                         //      intermediate node -> send the packet to upper module
00580                         sendUp(p, delayUp_);
00581                 }
00582                 else if(nextModule == getId())
00583                 {
00584                         sendDown(p, delayDown_);
00585                 }
00586                 else
00587                 {
00588                         // Send the packet to the next Module in the path -> try with the above modules
00589                         sendDown(nextModule, p, delayDown_);
00590                 } // end nextModule==-1
00591         } // end nModule==0
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 }

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2