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