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 #include <aodv/aodv.h>
00034 #include <aodv/aodv_packet.h>
00035 #include <random.h>
00036 #include <cmu-trace.h>
00037
00038
00039 #define max(a,b) ( (a) > (b) ? (a) : (b) )
00040 #define CURRENT_TIME Scheduler::instance().clock()
00041
00042
00043
00044
00045 #ifdef DEBUG
00046 static int extra_route_reply = 0;
00047 static int limit_route_request = 0;
00048 static int route_request = 0;
00049 #endif
00050
00051
00052
00053
00054
00055
00056
00057 int hdr_aodv::offset_;
00058 static class AODVHeaderClass : public PacketHeaderClass {
00059 public:
00060 AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",
00061 sizeof(hdr_all_aodv)) {
00062 bind_offset(&hdr_aodv::offset_);
00063 }
00064 } class_rtProtoAODV_hdr;
00065
00066 static class AODVclass : public TclClass {
00067 public:
00068 AODVclass() : TclClass("Agent/AODV") {}
00069 TclObject* create(int argc, const char*const* argv) {
00070 assert(argc == 5);
00071
00072 return (new AODV((nsaddr_t) Address::instance().str2addr(argv[4])));
00073 }
00074 } class_rtProtoAODV;
00075
00076
00077 int
00078 AODV::command(int argc, const char*const* argv) {
00079 if(argc == 2) {
00080 Tcl& tcl = Tcl::instance();
00081
00082 if(strncasecmp(argv[1], "id", 2) == 0) {
00083 tcl.resultf("%d", index);
00084 return TCL_OK;
00085 }
00086
00087 if(strncasecmp(argv[1], "start", 2) == 0) {
00088 btimer.handle((Event*) 0);
00089
00090 #ifndef AODV_LINK_LAYER_DETECTION
00091 htimer.handle((Event*) 0);
00092 ntimer.handle((Event*) 0);
00093 #endif // LINK LAYER DETECTION
00094
00095 rtimer.handle((Event*) 0);
00096 return TCL_OK;
00097 }
00098 }
00099 else if(argc == 3) {
00100 if(strcmp(argv[1], "index") == 0) {
00101 index = atoi(argv[2]);
00102 return TCL_OK;
00103 }
00104
00105 else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) {
00106 logtarget = (Trace*) TclObject::lookup(argv[2]);
00107 if(logtarget == 0)
00108 return TCL_ERROR;
00109 return TCL_OK;
00110 }
00111 else if(strcmp(argv[1], "drop-target") == 0) {
00112 int stat = rqueue.command(argc,argv);
00113 if (stat != TCL_OK) return stat;
00114 return Agent::command(argc, argv);
00115 }
00116 else if(strcmp(argv[1], "if-queue") == 0) {
00117 ifqueue = (PriQueue*) TclObject::lookup(argv[2]);
00118
00119 if(ifqueue == 0)
00120 return TCL_ERROR;
00121 return TCL_OK;
00122 }
00123 else if (strcmp(argv[1], "port-dmux") == 0) {
00124 dmux_ = (PortClassifier *)TclObject::lookup(argv[2]);
00125 if (dmux_ == 0) {
00126 fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__,
00127 argv[1], argv[2]);
00128 return TCL_ERROR;
00129 }
00130 return TCL_OK;
00131 }
00132 }
00133 return Agent::command(argc, argv);
00134 }
00135
00136
00137
00138
00139
00140 AODV::AODV(nsaddr_t id) : Agent(PT_AODV),
00141 btimer(this), htimer(this), ntimer(this),
00142 rtimer(this), lrtimer(this), rqueue() {
00143
00144
00145 index = id;
00146 seqno = 2;
00147 bid = 1;
00148
00149 LIST_INIT(&nbhead);
00150 LIST_INIT(&bihead);
00151
00152 logtarget = 0;
00153 ifqueue = 0;
00154 }
00155
00156
00157
00158
00159
00160 void
00161 BroadcastTimer::handle(Event*) {
00162 agent->id_purge();
00163 Scheduler::instance().schedule(this, &intr, BCAST_ID_SAVE);
00164 }
00165
00166 void
00167 HelloTimer::handle(Event*) {
00168 agent->sendHello();
00169 double interval = MinHelloInterval +
00170 ((MaxHelloInterval - MinHelloInterval) * Random::uniform());
00171 assert(interval >= 0);
00172 Scheduler::instance().schedule(this, &intr, interval);
00173 }
00174
00175 void
00176 NeighborTimer::handle(Event*) {
00177 agent->nb_purge();
00178 Scheduler::instance().schedule(this, &intr, HELLO_INTERVAL);
00179 }
00180
00181 void
00182 RouteCacheTimer::handle(Event*) {
00183 agent->rt_purge();
00184 #define FREQUENCY 0.5 // sec
00185 Scheduler::instance().schedule(this, &intr, FREQUENCY);
00186 }
00187
00188 void
00189 LocalRepairTimer::handle(Event* p) {
00190 aodv_rt_entry *rt;
00191 struct hdr_ip *ih = HDR_IP( (Packet *)p);
00192
00193
00194
00195
00196
00197 rt = agent->rtable.rt_lookup(ih->daddr());
00198
00199 if (rt && rt->rt_flags != RTF_UP) {
00200
00201
00202
00203
00204
00205
00206
00207 agent->rt_down(rt);
00208
00209 #ifdef DEBUG
00210 fprintf(stderr,"Node %d: Dst - %d, failed local repair\n",index, rt->rt_dst);
00211 #endif
00212 }
00213 Packet::free((Packet *)p);
00214 }
00215
00216
00217
00218
00219
00220
00221
00222 void
00223 AODV::id_insert(nsaddr_t id, u_int32_t bid) {
00224 BroadcastID *b = new BroadcastID(id, bid);
00225
00226 assert(b);
00227 b->expire = CURRENT_TIME + BCAST_ID_SAVE;
00228 LIST_INSERT_HEAD(&bihead, b, link);
00229 }
00230
00231
00232 bool
00233 AODV::id_lookup(nsaddr_t id, u_int32_t bid) {
00234 BroadcastID *b = bihead.lh_first;
00235
00236
00237 for( ; b; b = b->link.le_next) {
00238 if ((b->src == id) && (b->id == bid))
00239 return true;
00240 }
00241 return false;
00242 }
00243
00244 void
00245 AODV::id_purge() {
00246 BroadcastID *b = bihead.lh_first;
00247 BroadcastID *bn;
00248 double now = CURRENT_TIME;
00249
00250 for(; b; b = bn) {
00251 bn = b->link.le_next;
00252 if(b->expire <= now) {
00253 LIST_REMOVE(b,link);
00254 delete b;
00255 }
00256 }
00257 }
00258
00259
00260
00261
00262
00263 double
00264 AODV::PerHopTime(aodv_rt_entry *rt) {
00265 int num_non_zero = 0, i;
00266 double total_latency = 0.0;
00267
00268 if (!rt)
00269 return ((double) NODE_TRAVERSAL_TIME );
00270
00271 for (i=0; i < MAX_HISTORY; i++) {
00272 if (rt->rt_disc_latency[i] > 0.0) {
00273 num_non_zero++;
00274 total_latency += rt->rt_disc_latency[i];
00275 }
00276 }
00277 if (num_non_zero > 0)
00278 return(total_latency / (double) num_non_zero);
00279 else
00280 return((double) NODE_TRAVERSAL_TIME);
00281
00282 }
00283
00284
00285
00286
00287
00288 static void
00289 aodv_rt_failed_callback(Packet *p, void *arg) {
00290 ((AODV*) arg)->rt_ll_failed(p);
00291 }
00292
00293
00294
00295
00296 void
00297 AODV::rt_ll_failed(Packet *p) {
00298 struct hdr_cmn *ch = HDR_CMN(p);
00299 struct hdr_ip *ih = HDR_IP(p);
00300 aodv_rt_entry *rt;
00301 nsaddr_t broken_nbr = ch->next_hop_;
00302
00303 #ifndef AODV_LINK_LAYER_DETECTION
00304 drop(p, DROP_RTR_MAC_CALLBACK);
00305 #else
00306
00307
00308
00309
00310 if(! DATA_PACKET(ch->ptype()) ||
00311 (u_int32_t) ih->daddr() == IP_BROADCAST) {
00312 drop(p, DROP_RTR_MAC_CALLBACK);
00313 return;
00314 }
00315 log_link_broke(p);
00316 if((rt = rtable.rt_lookup(ih->daddr())) == 0) {
00317 drop(p, DROP_RTR_MAC_CALLBACK);
00318 return;
00319 }
00320 log_link_del(ch->next_hop_);
00321
00322 #ifdef AODV_LOCAL_REPAIR
00323
00324
00325
00326
00327 if (ch->num_forwards() > rt->rt_hops) {
00328 local_rt_repair(rt, p);
00329
00330
00331 return;
00332 }
00333 else
00334 #endif // LOCAL REPAIR
00335
00336 {
00337 drop(p, DROP_RTR_MAC_CALLBACK);
00338
00339
00340 while((p = ifqueue->filter(broken_nbr))) {
00341 drop(p, DROP_RTR_MAC_CALLBACK);
00342 }
00343 nb_delete(broken_nbr);
00344 }
00345
00346 #endif // LINK LAYER DETECTION
00347 }
00348
00349 void
00350 AODV::handle_link_failure(nsaddr_t id) {
00351 aodv_rt_entry *rt, *rtn;
00352 Packet *rerr = Packet::alloc();
00353 struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);
00354
00355 re->DestCount = 0;
00356 for(rt = rtable.head(); rt; rt = rtn) {
00357 rtn = rt->rt_link.le_next;
00358 if ((rt->rt_hops != INFINITY2) && (rt->rt_nexthop == id) ) {
00359 assert (rt->rt_flags == RTF_UP);
00360 assert((rt->rt_seqno%2) == 0);
00361 rt->rt_seqno++;
00362 re->unreachable_dst[re->DestCount] = rt->rt_dst;
00363 re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;
00364 #ifdef DEBUG
00365 fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\n", __FUNCTION__, CURRENT_TIME,
00366 index, re->unreachable_dst[re->DestCount],
00367 re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);
00368 #endif // DEBUG
00369 re->DestCount += 1;
00370 rt_down(rt);
00371 }
00372
00373 rt->pc_delete(id);
00374 }
00375
00376 if (re->DestCount > 0) {
00377 #ifdef DEBUG
00378 fprintf(stderr, "%s(%f): %d\tsending RERR...\n", __FUNCTION__, CURRENT_TIME, index);
00379 #endif // DEBUG
00380 sendError(rerr, false);
00381 }
00382 else {
00383 Packet::free(rerr);
00384 }
00385 }
00386
00387 void
00388 AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {
00389 #ifdef DEBUG
00390 fprintf(stderr,"%s: Dst - %d\n", __FUNCTION__, rt->rt_dst);
00391 #endif
00392
00393 rqueue.enque(p);
00394
00395
00396 rt->rt_flags = RTF_IN_REPAIR;
00397
00398 sendRequest(rt->rt_dst);
00399
00400
00401 Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);
00402 }
00403
00404 void
00405 AODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric,
00406 nsaddr_t nexthop, double expire_time) {
00407
00408 rt->rt_seqno = seqnum;
00409 rt->rt_hops = metric;
00410 rt->rt_flags = RTF_UP;
00411 rt->rt_nexthop = nexthop;
00412 rt->rt_expire = expire_time;
00413 }
00414
00415 void
00416 AODV::rt_down(aodv_rt_entry *rt) {
00417
00418
00419
00420
00421 if(rt->rt_flags == RTF_DOWN) {
00422 return;
00423 }
00424
00425
00426 rt->rt_last_hop_count = rt->rt_hops;
00427 rt->rt_hops = INFINITY2;
00428 rt->rt_flags = RTF_DOWN;
00429 rt->rt_nexthop = 0;
00430 rt->rt_expire = 0;
00431
00432 }
00433
00434
00435
00436
00437
00438 void
00439 AODV::rt_resolve(Packet *p) {
00440 struct hdr_cmn *ch = HDR_CMN(p);
00441 struct hdr_ip *ih = HDR_IP(p);
00442 aodv_rt_entry *rt;
00443
00444
00445
00446
00447
00448 ch->xmit_failure_ = aodv_rt_failed_callback;
00449 ch->xmit_failure_data_ = (void*) this;
00450 rt = rtable.rt_lookup(ih->daddr());
00451 if(rt == 0) {
00452 rt = rtable.rt_add(ih->daddr());
00453 }
00454
00455
00456
00457
00458
00459 if(rt->rt_flags == RTF_UP) {
00460 assert(rt->rt_hops != INFINITY2);
00461 forward(rt, p, NO_DELAY);
00462 }
00463
00464
00465
00466 else if(ih->saddr() == index) {
00467 rqueue.enque(p);
00468 sendRequest(rt->rt_dst);
00469 }
00470
00471
00472
00473 else if (rt->rt_flags == RTF_IN_REPAIR) {
00474 rqueue.enque(p);
00475 }
00476
00477
00478
00479
00480
00481 else {
00482 Packet *rerr = Packet::alloc();
00483 struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);
00484
00485
00486
00487
00488
00489
00490 assert (rt->rt_flags == RTF_DOWN);
00491 re->DestCount = 0;
00492 re->unreachable_dst[re->DestCount] = rt->rt_dst;
00493 re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;
00494 re->DestCount += 1;
00495 #ifdef DEBUG
00496 fprintf(stderr, "%s: sending RERR...\n", __FUNCTION__);
00497 #endif
00498 sendError(rerr, false);
00499
00500 drop(p, DROP_RTR_NO_ROUTE);
00501 }
00502
00503 }
00504
00505 void
00506 AODV::rt_purge() {
00507 aodv_rt_entry *rt, *rtn;
00508 double now = CURRENT_TIME;
00509 double delay = 0.0;
00510 Packet *p;
00511
00512 for(rt = rtable.head(); rt; rt = rtn) {
00513 rtn = rt->rt_link.le_next;
00514 if ((rt->rt_flags == RTF_UP) && (rt->rt_expire < now)) {
00515
00516
00517 assert(rt->rt_hops != INFINITY2);
00518 while((p = rqueue.deque(rt->rt_dst))) {
00519 #ifdef DEBUG
00520 fprintf(stderr, "%s: calling drop()\n",
00521 __FUNCTION__);
00522 #endif // DEBUG
00523 drop(p, DROP_RTR_NO_ROUTE);
00524 }
00525 rt->rt_seqno++;
00526 assert (rt->rt_seqno%2);
00527 rt_down(rt);
00528 }
00529 else if (rt->rt_flags == RTF_UP) {
00530
00531
00532
00533
00534 assert(rt->rt_hops != INFINITY2);
00535 while((p = rqueue.deque(rt->rt_dst))) {
00536 forward (rt, p, delay);
00537 delay += ARP_DELAY;
00538 }
00539 }
00540 else if (rqueue.find(rt->rt_dst))
00541
00542
00543
00544
00545
00546
00547
00548
00549 sendRequest(rt->rt_dst);
00550 }
00551
00552 }
00553
00554
00555
00556
00557
00558 void
00559 AODV::recv(Packet *p, Handler*) {
00560 struct hdr_cmn *ch = HDR_CMN(p);
00561 struct hdr_ip *ih = HDR_IP(p);
00562
00563 assert(initialized());
00564
00565
00566
00567 if(ch->ptype() == PT_AODV) {
00568 ih->ttl_ -= 1;
00569 recvAODV(p);
00570 return;
00571 }
00572
00573
00574
00575
00576
00577 if((ih->saddr() == index) && (ch->num_forwards() == 0)) {
00578
00579
00580
00581 ch->size() += IP_HDR_LEN;
00582
00583 if ( (u_int32_t)ih->daddr() != IP_BROADCAST)
00584 ih->ttl_ = NETWORK_DIAMETER;
00585 }
00586
00587
00588
00589
00590 else if(ih->saddr() == index) {
00591 drop(p, DROP_RTR_ROUTE_LOOP);
00592 return;
00593 }
00594
00595
00596
00597 else {
00598
00599
00600
00601 if(--ih->ttl_ == 0) {
00602 drop(p, DROP_RTR_TTL);
00603 return;
00604 }
00605 }
00606
00607 if ( (u_int32_t)ih->daddr() != IP_BROADCAST)
00608 rt_resolve(p);
00609 else
00610 forward((aodv_rt_entry*) 0, p, NO_DELAY);
00611 }
00612
00613
00614 void
00615 AODV::recvAODV(Packet *p) {
00616 struct hdr_aodv *ah = HDR_AODV(p);
00617
00618 assert(HDR_IP (p)->sport() == RT_PORT);
00619 assert(HDR_IP (p)->dport() == RT_PORT);
00620
00621
00622
00623
00624 switch(ah->ah_type) {
00625
00626 case AODVTYPE_RREQ:
00627 recvRequest(p);
00628 break;
00629
00630 case AODVTYPE_RREP:
00631 recvReply(p);
00632 break;
00633
00634 case AODVTYPE_RERR:
00635 recvError(p);
00636 break;
00637
00638 case AODVTYPE_HELLO:
00639 recvHello(p);
00640 break;
00641
00642 default:
00643 fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type);
00644 exit(1);
00645 }
00646
00647 }
00648
00649
00650 void
00651 AODV::recvRequest(Packet *p) {
00652 struct hdr_ip *ih = HDR_IP(p);
00653 struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
00654 aodv_rt_entry *rt;
00655
00656
00657
00658
00659
00660
00661
00662 if(rq->rq_src == index) {
00663 #ifdef DEBUG
00664 fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__);
00665 #endif // DEBUG
00666 Packet::free(p);
00667 return;
00668 }
00669
00670 if (id_lookup(rq->rq_src, rq->rq_bcast_id)) {
00671
00672 #ifdef DEBUG
00673 fprintf(stderr, "%s: discarding request\n", __FUNCTION__);
00674 #endif // DEBUG
00675
00676 Packet::free(p);
00677 return;
00678 }
00679
00680
00681
00682
00683 id_insert(rq->rq_src, rq->rq_bcast_id);
00684
00685
00686
00687
00688
00689
00690
00691
00692 aodv_rt_entry *rt0;
00693
00694 rt0 = rtable.rt_lookup(rq->rq_src);
00695 if(rt0 == 0) {
00696
00697 rt0 = rtable.rt_add(rq->rq_src);
00698 }
00699
00700 rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE));
00701
00702 if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||
00703 ((rq->rq_src_seqno == rt0->rt_seqno) &&
00704 (rq->rq_hop_count < rt0->rt_hops)) ) {
00705
00706
00707 rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(),
00708 max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) );
00709 if (rt0->rt_req_timeout > 0.0) {
00710
00711
00712
00713
00714 rt0->rt_req_cnt = 0;
00715 rt0->rt_req_timeout = 0.0;
00716 rt0->rt_req_last_ttl = rq->rq_hop_count;
00717 rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
00718 }
00719
00720
00721
00722
00723
00724 assert (rt0->rt_flags == RTF_UP);
00725 Packet *buffered_pkt;
00726 while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) {
00727 if (rt0 && (rt0->rt_flags == RTF_UP)) {
00728 assert(rt0->rt_hops != INFINITY2);
00729 forward(rt0, buffered_pkt, NO_DELAY);
00730 }
00731 }
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741 rt = rtable.rt_lookup(rq->rq_dst);
00742
00743
00744
00745 if(rq->rq_dst == index) {
00746
00747 #ifdef DEBUG
00748 fprintf(stderr, "%d - %s: destination sending reply\n",
00749 index, __FUNCTION__);
00750 #endif // DEBUG
00751
00752
00753
00754
00755 seqno = max(seqno, rq->rq_dst_seqno)+1;
00756 if (seqno%2) seqno++;
00757
00758 sendReply(rq->rq_src,
00759 1,
00760 index,
00761 seqno,
00762 MY_ROUTE_TIMEOUT,
00763 rq->rq_timestamp);
00764
00765 Packet::free(p);
00766 }
00767
00768
00769
00770 else if (rt && (rt->rt_hops != INFINITY2) &&
00771 (rt->rt_seqno >= rq->rq_dst_seqno) ) {
00772
00773
00774 assert(rq->rq_dst == rt->rt_dst);
00775
00776 sendReply(rq->rq_src,
00777 rt->rt_hops + 1,
00778 rq->rq_dst,
00779 rt->rt_seqno,
00780 (u_int32_t) (rt->rt_expire - CURRENT_TIME),
00781
00782 rq->rq_timestamp);
00783
00784
00785 rt->pc_insert(rt0->rt_nexthop);
00786 rt0->pc_insert(rt->rt_nexthop);
00787
00788 #ifdef RREQ_GRAT_RREP
00789
00790 sendReply(rq->rq_dst,
00791 rq->rq_hop_count,
00792 rq->rq_src,
00793 rq->rq_src_seqno,
00794 (u_int32_t) (rt->rt_expire - CURRENT_TIME),
00795
00796 rq->rq_timestamp);
00797 #endif
00798
00799
00800
00801
00802
00803 Packet::free(p);
00804 }
00805
00806
00807
00808 else {
00809 ih->saddr() = index;
00810 ih->daddr() = IP_BROADCAST;
00811 rq->rq_hop_count += 1;
00812
00813 if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno);
00814 forward((aodv_rt_entry*) 0, p, DELAY);
00815 }
00816
00817 }
00818
00819
00820 void
00821 AODV::recvReply(Packet *p) {
00822
00823 struct hdr_ip *ih = HDR_IP(p);
00824 struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
00825 aodv_rt_entry *rt;
00826 char suppress_reply = 0;
00827 double delay = 0.0;
00828
00829 #ifdef DEBUG
00830 fprintf(stderr, "%d - %s: received a REPLY\n", index, __FUNCTION__);
00831 #endif // DEBUG
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843 rt = rtable.rt_lookup(rp->rp_dst);
00844
00845
00846
00847
00848 if(rt == 0) {
00849 rt = rtable.rt_add(rp->rp_dst);
00850 }
00851
00852
00853
00854
00855
00856
00857 if ( (rt->rt_seqno < rp->rp_dst_seqno) ||
00858 ((rt->rt_seqno == rp->rp_dst_seqno) &&
00859 (rt->rt_hops > rp->rp_hop_count)) ) {
00860
00861
00862 rt_update(rt, rp->rp_dst_seqno, rp->rp_hop_count,
00863 rp->rp_src, CURRENT_TIME + rp->rp_lifetime);
00864
00865
00866 rt->rt_req_cnt = 0;
00867 rt->rt_req_timeout = 0.0;
00868 rt->rt_req_last_ttl = rp->rp_hop_count;
00869
00870 if (ih->daddr() == index) {
00871
00872
00873
00874 rt->rt_disc_latency[(unsigned char)rt->hist_indx] = (CURRENT_TIME - rp->rp_timestamp)
00875 / (double) rp->rp_hop_count;
00876
00877 rt->hist_indx = (rt->hist_indx + 1) % MAX_HISTORY;
00878 }
00879
00880
00881
00882
00883
00884
00885 Packet *buf_pkt;
00886 while((buf_pkt = rqueue.deque(rt->rt_dst))) {
00887 if(rt->rt_hops != INFINITY2) {
00888 assert (rt->rt_flags == RTF_UP);
00889
00890
00891 forward(rt, buf_pkt, delay);
00892 delay += ARP_DELAY;
00893 }
00894 }
00895 }
00896 else {
00897 suppress_reply = 1;
00898 }
00899
00900
00901
00902
00903
00904 if(ih->daddr() == index || suppress_reply) {
00905 Packet::free(p);
00906 }
00907
00908
00909
00910 else {
00911
00912 aodv_rt_entry *rt0 = rtable.rt_lookup(ih->daddr());
00913
00914 if(rt0 && (rt0->rt_hops != INFINITY2)) {
00915 assert (rt0->rt_flags == RTF_UP);
00916 rp->rp_hop_count += 1;
00917 rp->rp_src = index;
00918 forward(rt0, p, NO_DELAY);
00919
00920
00921 rt->pc_insert(rt0->rt_nexthop);
00922
00923 }
00924 else {
00925
00926 #ifdef DEBUG
00927 fprintf(stderr, "%s: dropping Route Reply\n", __FUNCTION__);
00928 #endif // DEBUG
00929 drop(p, DROP_RTR_NO_ROUTE);
00930 }
00931 }
00932 }
00933
00934
00935 void
00936 AODV::recvError(Packet *p) {
00937 struct hdr_ip *ih = HDR_IP(p);
00938 struct hdr_aodv_error *re = HDR_AODV_ERROR(p);
00939 aodv_rt_entry *rt;
00940 u_int8_t i;
00941 Packet *rerr = Packet::alloc();
00942 struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);
00943
00944 nre->DestCount = 0;
00945
00946 for (i=0; i<re->DestCount; i++) {
00947
00948 rt = rtable.rt_lookup(re->unreachable_dst[i]);
00949 if ( rt && (rt->rt_hops != INFINITY2) &&
00950 (rt->rt_nexthop == ih->saddr()) &&
00951 (rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {
00952 assert(rt->rt_flags == RTF_UP);
00953 assert((rt->rt_seqno%2) == 0);
00954 #ifdef DEBUG
00955 fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\t(%d\t%u\t%d)\n", __FUNCTION__,CURRENT_TIME,
00956 index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,
00957 re->unreachable_dst[i],re->unreachable_dst_seqno[i],
00958 ih->saddr());
00959 #endif // DEBUG
00960 rt->rt_seqno = re->unreachable_dst_seqno[i];
00961 rt_down(rt);
00962
00963
00964 Packet *pkt;
00965 while((pkt = ifqueue->filter(ih->saddr()))) {
00966 drop(pkt, DROP_RTR_MAC_CALLBACK);
00967 }
00968
00969
00970 if (!rt->pc_empty()) {
00971 nre->unreachable_dst[nre->DestCount] = rt->rt_dst;
00972 nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;
00973 nre->DestCount += 1;
00974 rt->pc_delete();
00975 }
00976 }
00977 }
00978
00979 if (nre->DestCount > 0) {
00980 #ifdef DEBUG
00981 fprintf(stderr, "%s(%f): %d\t sending RERR...\n", __FUNCTION__, CURRENT_TIME, index);
00982 #endif // DEBUG
00983 sendError(rerr);
00984 }
00985 else {
00986 Packet::free(rerr);
00987 }
00988
00989 Packet::free(p);
00990 }
00991
00992
00993
00994
00995
00996
00997 void
00998 AODV::forward(aodv_rt_entry *rt, Packet *p, double delay) {
00999 struct hdr_cmn *ch = HDR_CMN(p);
01000 struct hdr_ip *ih = HDR_IP(p);
01001
01002 if(ih->ttl_ == 0) {
01003
01004 #ifdef DEBUG
01005 fprintf(stderr, "%s: calling drop()\n", __PRETTY_FUNCTION__);
01006 #endif // DEBUG
01007
01008 drop(p, DROP_RTR_TTL);
01009 return;
01010 }
01011
01012 if (ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP &&
01013 ((u_int32_t)ih->daddr() == IP_BROADCAST)
01014 || (ih->daddr() == here_.addr_)) {
01015 dmux_->recv(p,0);
01016 return;
01017 }
01018
01019 if (rt) {
01020 assert(rt->rt_flags == RTF_UP);
01021 rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT;
01022 ch->next_hop_ = rt->rt_nexthop;
01023 ch->addr_type() = NS_AF_INET;
01024 ch->direction() = hdr_cmn::DOWN;
01025 }
01026 else {
01027
01028 assert(ih->daddr() == (nsaddr_t) IP_BROADCAST);
01029 ch->addr_type() = NS_AF_NONE;
01030 ch->direction() = hdr_cmn::DOWN;
01031 }
01032
01033 if (ih->daddr() == (nsaddr_t) IP_BROADCAST) {
01034
01035 assert(rt == 0);
01036
01037
01038
01039 Scheduler::instance().schedule(target_, p,
01040 0.01 * Random::uniform());
01041 }
01042 else {
01043 if(delay > 0.0) {
01044 Scheduler::instance().schedule(target_, p, delay);
01045 }
01046 else {
01047
01048 Scheduler::instance().schedule(target_, p, 0.);
01049 }
01050 }
01051
01052 }
01053
01054
01055 void
01056 AODV::sendRequest(nsaddr_t dst) {
01057
01058 Packet *p = Packet::alloc();
01059 struct hdr_cmn *ch = HDR_CMN(p);
01060 struct hdr_ip *ih = HDR_IP(p);
01061 struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p);
01062 aodv_rt_entry *rt = rtable.rt_lookup(dst);
01063
01064 assert(rt);
01065
01066
01067
01068
01069
01070
01071 if (rt->rt_flags == RTF_UP) {
01072 assert(rt->rt_hops != INFINITY2);
01073 Packet::free((Packet *)p);
01074 return;
01075 }
01076
01077 if (rt->rt_req_timeout > CURRENT_TIME) {
01078 Packet::free((Packet *)p);
01079 return;
01080 }
01081
01082
01083
01084
01085
01086 if (rt->rt_req_cnt > RREQ_RETRIES) {
01087 rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;
01088 rt->rt_req_cnt = 0;
01089 Packet *buf_pkt;
01090 while ((buf_pkt = rqueue.deque(rt->rt_dst))) {
01091 drop(buf_pkt, DROP_RTR_NO_ROUTE);
01092 }
01093 Packet::free((Packet *)p);
01094 return;
01095 }
01096
01097 #ifdef DEBUG
01098 fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n",
01099 ++route_request, index, rt->rt_dst);
01100 #endif // DEBUG
01101
01102
01103
01104
01105 rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count);
01106
01107 if (0 == rt->rt_req_last_ttl) {
01108
01109 ih->ttl_ = TTL_START;
01110 }
01111 else {
01112
01113 if (rt->rt_req_last_ttl < TTL_THRESHOLD)
01114 ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT;
01115 else {
01116
01117 ih->ttl_ = NETWORK_DIAMETER;
01118 rt->rt_req_cnt += 1;
01119 }
01120 }
01121
01122
01123 rt->rt_req_last_ttl = ih->ttl_;
01124
01125
01126
01127
01128
01129
01130 rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt);
01131 if (rt->rt_req_cnt > 0)
01132 rt->rt_req_timeout *= rt->rt_req_cnt;
01133 rt->rt_req_timeout += CURRENT_TIME;
01134
01135
01136 if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT)
01137 rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT;
01138 rt->rt_expire = 0;
01139
01140 #ifdef DEBUG
01141 fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout %f ms\n",
01142 ++route_request,
01143 index, rt->rt_dst,
01144 rt->rt_req_timeout - CURRENT_TIME);
01145 #endif // DEBUG
01146
01147
01148
01149
01150 ch->ptype() = PT_AODV;
01151 ch->size() = IP_HDR_LEN + rq->size();
01152 ch->iface() = -2;
01153 ch->error() = 0;
01154 ch->addr_type() = NS_AF_NONE;
01155 ch->prev_hop_ = index;
01156
01157 ih->saddr() = index;
01158 ih->daddr() = IP_BROADCAST;
01159 ih->sport() = RT_PORT;
01160 ih->dport() = RT_PORT;
01161
01162
01163 rq->rq_type = AODVTYPE_RREQ;
01164 rq->rq_hop_count = 1;
01165 rq->rq_bcast_id = bid++;
01166 rq->rq_dst = dst;
01167 rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0);
01168 rq->rq_src = index;
01169 seqno += 2;
01170 assert ((seqno%2) == 0);
01171 rq->rq_src_seqno = seqno;
01172 rq->rq_timestamp = CURRENT_TIME;
01173
01174 Scheduler::instance().schedule(target_, p, 0.);
01175
01176 }
01177
01178 void
01179 AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,
01180 u_int32_t rpseq, u_int32_t lifetime, double timestamp) {
01181 Packet *p = Packet::alloc();
01182 struct hdr_cmn *ch = HDR_CMN(p);
01183 struct hdr_ip *ih = HDR_IP(p);
01184 struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
01185 aodv_rt_entry *rt = rtable.rt_lookup(ipdst);
01186
01187 #ifdef DEBUG
01188 fprintf(stderr, "sending Reply from %d at %.2f\n", index, Scheduler::instance().clock());
01189 #endif // DEBUG
01190 assert(rt);
01191
01192 rp->rp_type = AODVTYPE_RREP;
01193
01194 rp->rp_hop_count = hop_count;
01195 rp->rp_dst = rpdst;
01196 rp->rp_dst_seqno = rpseq;
01197 rp->rp_src = index;
01198 rp->rp_lifetime = lifetime;
01199 rp->rp_timestamp = timestamp;
01200
01201
01202 ch->ptype() = PT_AODV;
01203 ch->size() = IP_HDR_LEN + rp->size();
01204 ch->iface() = -2;
01205 ch->error() = 0;
01206 ch->addr_type() = NS_AF_INET;
01207 ch->next_hop_ = rt->rt_nexthop;
01208 ch->prev_hop_ = index;
01209 ch->direction() = hdr_cmn::DOWN;
01210
01211 ih->saddr() = index;
01212 ih->daddr() = ipdst;
01213 ih->sport() = RT_PORT;
01214 ih->dport() = RT_PORT;
01215 ih->ttl_ = NETWORK_DIAMETER;
01216
01217 Scheduler::instance().schedule(target_, p, 0.);
01218
01219 }
01220
01221 void
01222 AODV::sendError(Packet *p, bool jitter) {
01223 struct hdr_cmn *ch = HDR_CMN(p);
01224 struct hdr_ip *ih = HDR_IP(p);
01225 struct hdr_aodv_error *re = HDR_AODV_ERROR(p);
01226
01227 #ifdef ERROR
01228 fprintf(stderr, "sending Error from %d at %.2f\n", index, Scheduler::instance().clock());
01229 #endif // DEBUG
01230
01231 re->re_type = AODVTYPE_RERR;
01232
01233
01234
01235
01236 ch->ptype() = PT_AODV;
01237 ch->size() = IP_HDR_LEN + re->size();
01238 ch->iface() = -2;
01239 ch->error() = 0;
01240 ch->addr_type() = NS_AF_NONE;
01241 ch->next_hop_ = 0;
01242 ch->prev_hop_ = index;
01243 ch->direction() = hdr_cmn::DOWN;
01244
01245 ih->saddr() = index;
01246 ih->daddr() = IP_BROADCAST;
01247 ih->sport() = RT_PORT;
01248 ih->dport() = RT_PORT;
01249 ih->ttl_ = 1;
01250
01251
01252 if (jitter)
01253 Scheduler::instance().schedule(target_, p, 0.01*Random::uniform());
01254 else
01255 Scheduler::instance().schedule(target_, p, 0.0);
01256
01257 }
01258
01259
01260
01261
01262
01263
01264 void
01265 AODV::sendHello() {
01266 Packet *p = Packet::alloc();
01267 struct hdr_cmn *ch = HDR_CMN(p);
01268 struct hdr_ip *ih = HDR_IP(p);
01269 struct hdr_aodv_reply *rh = HDR_AODV_REPLY(p);
01270
01271 #ifdef DEBUG
01272 fprintf(stderr, "sending Hello from %d at %.2f\n", index, Scheduler::instance().clock());
01273 #endif // DEBUG
01274
01275 rh->rp_type = AODVTYPE_HELLO;
01276
01277 rh->rp_hop_count = 1;
01278 rh->rp_dst = index;
01279 rh->rp_dst_seqno = seqno;
01280 rh->rp_lifetime = (1 + ALLOWED_HELLO_LOSS) * HELLO_INTERVAL;
01281
01282
01283 ch->ptype() = PT_AODV;
01284 ch->size() = IP_HDR_LEN + rh->size();
01285 ch->iface() = -2;
01286 ch->error() = 0;
01287 ch->addr_type() = NS_AF_NONE;
01288 ch->prev_hop_ = index;
01289
01290 ih->saddr() = index;
01291 ih->daddr() = IP_BROADCAST;
01292 ih->sport() = RT_PORT;
01293 ih->dport() = RT_PORT;
01294 ih->ttl_ = 1;
01295
01296 Scheduler::instance().schedule(target_, p, 0.0);
01297 }
01298
01299
01300 void
01301 AODV::recvHello(Packet *p) {
01302
01303 struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p);
01304 AODV_Neighbor *nb;
01305
01306 nb = nb_lookup(rp->rp_dst);
01307 if(nb == 0) {
01308 nb_insert(rp->rp_dst);
01309 }
01310 else {
01311 nb->nb_expire = CURRENT_TIME +
01312 (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
01313 }
01314
01315 Packet::free(p);
01316 }
01317
01318 void
01319 AODV::nb_insert(nsaddr_t id) {
01320 AODV_Neighbor *nb = new AODV_Neighbor(id);
01321
01322 assert(nb);
01323 nb->nb_expire = CURRENT_TIME +
01324 (1.5 * ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
01325 LIST_INSERT_HEAD(&nbhead, nb, nb_link);
01326 seqno += 2;
01327 assert ((seqno%2) == 0);
01328 }
01329
01330
01331 AODV_Neighbor*
01332 AODV::nb_lookup(nsaddr_t id) {
01333 AODV_Neighbor *nb = nbhead.lh_first;
01334
01335 for(; nb; nb = nb->nb_link.le_next) {
01336 if(nb->nb_addr == id) break;
01337 }
01338 return nb;
01339 }
01340
01341
01342
01343
01344
01345
01346 void
01347 AODV::nb_delete(nsaddr_t id) {
01348 AODV_Neighbor *nb = nbhead.lh_first;
01349
01350 log_link_del(id);
01351 seqno += 2;
01352 assert ((seqno%2) == 0);
01353
01354 for(; nb; nb = nb->nb_link.le_next) {
01355 if(nb->nb_addr == id) {
01356 LIST_REMOVE(nb,nb_link);
01357 delete nb;
01358 break;
01359 }
01360 }
01361
01362 handle_link_failure(id);
01363
01364 }
01365
01366
01367
01368
01369
01370
01371 void
01372 AODV::nb_purge() {
01373 AODV_Neighbor *nb = nbhead.lh_first;
01374 AODV_Neighbor *nbn;
01375 double now = CURRENT_TIME;
01376
01377 for(; nb; nb = nbn) {
01378 nbn = nb->nb_link.le_next;
01379 if(nb->nb_expire <= now) {
01380 nb_delete(nb->nb_addr);
01381 }
01382 }
01383
01384 }