/usr/src/other/ns-allinone-2.27/ns_orig/aodv/aodv.cc
00032
00033 //#include <ip.h>
00034
00035 #include <aodv/aodv.h>
00036 #include <aodv/aodv_packet.h>
00037 #include <random.h>
00038 #include <cmu-trace.h>
00039 //#include <energy-model.h>
00040
00041 #define max(a,b) ( (a) > (b) ? (a) : (b) )
00042 #define CURRENT_TIME Scheduler::instance().clock()
00043
00044 //#define DEBUG
00045 //#define ERROR
00046
00047 #ifdef DEBUG
00048 static int extra_route_reply = 0;
00049 static int limit_route_request = 0;
00050 static int route_request = 0;
00051 #endif
00052
00053
00054 /*
00055 TCL Hooks
00056 */
00057
00058
00059 int hdr_aodv::offset_;
00060 static class AODVHeaderClass : public PacketHeaderClass {
00061 public:
00062 AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",
00063 sizeof(hdr_all_aodv)) {
00064 bind_offset(&hdr_aodv::offset_);
00065 }
00066 } class_rtProtoAODV_hdr;
00067
00068 static class AODVclass : public TclClass {
00069 public:
00070 AODVclass() : TclClass("Agent/AODV") {}
00071 TclObject* create(int argc, const char*const* argv) {
00072 assert(argc == 5);
00073 //return (new AODV((nsaddr_t) atoi(argv[4])));
00074 return (new AODV((nsaddr_t) Address::instance().str2addr(argv[4])));
00075 }
00076 } class_rtProtoAODV;
00077
00078
00079 int
00080 AODV::command(int argc, const char*const* argv) {
00081 if(argc == 2) {
00082 Tcl& tcl = Tcl::instance();
00083
00084 if(strncasecmp(argv[1], "id", 2) == 0) {
00085 tcl.resultf("%d", index);
00086 return TCL_OK;
00087 }
00088
00089 if(strncasecmp(argv[1], "start", 2) == 0) { //初始化了所有的timer,除了localrepair
00090 btimer.handle((Event*) 0);
00091
00092 #ifndef AODV_LINK_LAYER_DETECTION
00093 htimer.handle((Event*) 0);
00094 ntimer.handle((Event*) 0);
00095 #endif // LINK LAYER DETECTION
00096
00097 rtimer.handle((Event*) 0);
00098 return TCL_OK;
00099 }
00100 }
00101 else if(argc == 3) {
00102 if(strcmp(argv[1], "index") == 0) {
00103 index = atoi(argv[2]);
00104 return TCL_OK;
00105 }
00106
00107 else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) {
00108 logtarget = (Trace*) TclObject::lookup(argv[2]);
00109 if(logtarget == 0)
00110 return TCL_ERROR;
00111 return TCL_OK;
00112 }
00113 else if(strcmp(argv[1], "drop-target") == 0) {
00114 int stat = rqueue.command(argc,argv);
00115 if (stat != TCL_OK) return stat;
00116 return Agent::command(argc, argv);
00117 }
00118 else if(strcmp(argv[1], "if-queue") == 0) {
00119 ifqueue = (PriQueue*) TclObject::lookup(argv[2]);
00120
00121 if(ifqueue == 0)
00122 return TCL_ERROR;
00123 return TCL_OK;
00124 }
00125 else if (strcmp(argv[1], "port-dmux") == 0) {
返回页顶
00126 dmux_ = (PortClassifier *)TclObject::lookup(argv[2]);
00127 if (dmux_ == 0) {
00128 fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__,
00129 argv[1], argv[2]);
00130 return TCL_ERROR;
00131 }
00132 return TCL_OK;
00133 }
00134 }
00135 return Agent::command(argc, argv);
00136 }
00137
00138 /*
00139 Constructor
00140 */
00141
00142 AODV::AODV(nsaddr_t id) : Agent(PT_AODV),
00143 btimer(this), htimer(this), ntimer(this),
00144 rtimer(this), lrtimer(this), rqueue() {
00145
00146
00147 index = id;
00148 seqno = 2;
00149 bid = 1;
00150
00151 LIST_INIT(&nbhead); //初始化neighbor list
00152 LIST_INIT(&bihead); //初始化broadcast id list
00153
00154 logtarget = 0;
00155 ifqueue = 0;
00156 }
00157
00158 /*
00159 Timers
00160 */
00161
00162 void
00163 BroadcastTimer::handle(Event*) {
00164 agent->id_purge();
00165 Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);
00166 }
00167
00168 void
00169 HelloTimer::handle(Event*) {
00170 agent->sendHello();
00171 double interval = MinHelloInterval +
00172 ((MaxHelloInterval - MinHelloInterval) * Random::uniform());
00173 assert(interval >= 0);
00174 Scheduler::instance().schedule(this, &intr, interval);
00175 }
00176
00177 void
00178 NeighborTimer::handle(Event*) {
00179 agent->nb_purge();
00180 Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);
00181 }
00182
00183 void
00184 RouteCacheTimer::handle(Event*) {
00185 agent->rt_purge();
00186 #define FREQUENCY 0.5 // sec
00187 Scheduler::instance().schedule(this, &intr, FREQUENCY);
00188 }
00189
00190 void
00191 LocalRepairTimer::handle(Event* p) { // SRD: 5/4/99
00192 aodv_rt_entry *rt;
00193 struct hdr_ip *ih = HDR_IP( (Packet *)p);
00194
00195 /* you get here after the timeout in a local repair attempt */
00196 /* fprintf(stderr, "%s\n", __FUNCTION__); */
00197
00198
00199 rt = agent->rtable.rt_lookup(ih->daddr()); //看routing table里有没有到目标节点的路由
00200
00201 if (rt && rt->rt_flags != RTF_UP) { //有且有效,也就是说路由等待repair
00202 // route is yet to be repaired
00203 // I will be conservative and bring down the route
00204 // and send route errors upstream.
00205 /* The following assert fails, not sure why */
00206 /* assert (rt->rt_flags == RTF_IN_REPAIR); */
00207
00208 //rt->rt_seqno++;
00209 agent->rt_down(rt); //调用rt_down(aodv_rt_entry *rt)函数,用以标志这条路由break down
00210 // send RERR
00211 #ifdef DEBUG
00212 fprintf(stderr,"Node %d: Dst - %d, failed local repair\n",index, rt->rt_dst);
00213 #endif
00214 }
00215 Packet::free((Packet *)p);
00216 }
00217
00218
00219 /*
00220 Broadcast ID Management Functions
00221 */
00222
00223
00224 void
00225 AODV::id_insert(nsaddr_t id, u_int32_t bid) {
00226 BroadcastID *b = new BroadcastID(id, bid);
00227
00228 assert(b);
00229 b->expire = CURRENT_TIME + BCAST_ID_SAVE;
00230 LIST_INSERT_HEAD(&bihead, b, link); //把新的id放在broadcast id list的头上
00231 }
00232
00233 /* SRD */
00234 bool
00235 AODV::id_lookup(nsaddr_t id, u_int32_t bid) {
00236 BroadcastID *b = bihead.lh_first;
00237
00238 // Search the list for a match of source and bid
00239 for( ; b; b = b->link.le_next) {
00240 if ((b->src == id) && (b->id == bid)) //看list里source的地址与id能不能对应?
00241 return true;
00242 }
00243 return false;
00244 }
00245
00246 void
00247 AODV::id_purge() { //丢掉所有已经过期的id
00248 BroadcastID *b = bihead.lh_first;
00249 BroadcastID *bn;
00250 double now = CURRENT_TIME;
00251
00252 for(; b; b = bn) {
00253 bn = b->link.le_next;
00254 if(b->expire <= now) { //表示已经过期
00255 LIST_REMOVE(b,link);
00256 delete b;
00257 }
00258 }
00259 }
00260
00261 /*
00262 Helper Functions //不懂
00263 */
00264
00265 double
00266 AODV::PerHopTime(aodv_rt_entry *rt) {
00267 int num_non_zero = 0, i;
00268 double total_latency = 0.0;
00269
00270 if (!rt)
00271 return (