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 extern "C" {
00035 #include <assert.h>
00036 #include <math.h>
00037 #include <stdio.h>
00038 #include <signal.h>
00039 #include <float.h>
00040 }
00041
00042 #include <object.h>
00043 #include <agent.h>
00044 #include <trace.h>
00045 #include <packet.h>
00046 #include <scheduler.h>
00047 #include <random.h>
00048
00049 #include <mac.h>
00050 #include <ll.h>
00051 #include <cmu-trace.h>
00052
00053 #include "path.h"
00054 #include "srpacket.h"
00055 #include "routecache.h"
00056 #include "requesttable.h"
00057 #include "dsragent.h"
00058
00059
00060
00061
00062
00063
00064
00065 #define NEW_SALVAGE_LOGIC
00066
00067 #ifdef NEW_SALVAGE_LOGIC
00068
00069
00070
00071 static int dsr_salvage_max_attempts = 15;
00072
00073
00074
00075
00076 static int dsr_salvage_max_requests = 1;
00077
00078
00079
00080
00081 static bool dsr_salvage_allow_propagating = 0;
00082
00083 #endif
00084
00085
00086 static const bool dsragent_enable_flowstate = true;
00087 static const bool dsragent_prefer_default_flow = true;
00088 static const bool dsragent_prefer_shorter_over_default = true;
00089 static const bool dsragent_always_reestablish = true;
00090 static const int min_adv_interval = 5;
00091 static const int default_flow_timeout = 60;
00092
00093
00094 static const int verbose = 0;
00095 static const int verbose_srr = 0;
00096 static const int verbose_ssalv = 1;
00097
00098 DSRAgent_List DSRAgent::agthead = { 0 };
00099
00100 Time arp_timeout = 30.0e-3;
00101 Time rt_rq_period = 0.5;
00102 Time rt_rq_max_period = 10.0;
00103
00104 #if 0
00105
00106 Time rt_rep_holdoff_period = 3.0e-3;
00107
00108
00109 #endif //0
00110
00111 Time grat_hold_down_time = 1.0;
00112
00113
00114 Time max_err_hold = 1.0;
00115
00116
00117
00118
00119
00120
00121 bool dsragent_snoop_forwarded_errors = true;
00122
00123 bool dsragent_snoop_source_routes = true;
00124
00125 bool dsragent_reply_only_to_first_rtreq = false;
00126
00127 bool dsragent_propagate_last_error = true;
00128
00129
00130
00131 bool dsragent_send_grat_replies = true;
00132
00133 bool dsragent_salvage_with_cache = true;
00134
00135
00136 bool dsragent_use_tap = true;
00137
00138 bool dsragent_reply_from_cache_on_propagating = true;
00139
00140
00141 bool dsragent_ring_zero_search = true;
00142
00143
00144
00145
00146
00147
00148
00149 bool dsragent_dont_salvage_bad_replies = true;
00150
00151
00152
00153
00154 bool dsragent_require_bi_routes = true;
00155
00156
00157
00158
00159 #if 0
00160 bool lsnode_holdoff_rt_reply = true;
00161
00162
00163 bool lsnode_require_use = true;
00164
00165
00166
00167 #endif
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 void
00195 SendBufferTimer::expire(Event *)
00196 {
00197 a_->sendBufferCheck();
00198 resched(BUFFER_CHECK + BUFFER_CHECK * Random::uniform(1.0));
00199 }
00200
00201 void
00202 DSRAgent::dropSendBuff(SRPacket &p)
00203
00204 {
00205 trace("Ssb %.5f _%s_ dropped %s -> %s", Scheduler::instance().clock(),
00206 net_id.dump(), p.src.dump(), p.dest.dump());
00207 drop(p.pkt, DROP_RTR_QTIMEOUT);
00208 p.pkt = 0;
00209 p.route.reset();
00210 }
00211
00212 void
00213 DSRAgent::stickPacketInSendBuffer(SRPacket& p)
00214 {
00215 Time min = DBL_MAX;
00216 int min_index = 0;
00217 int c;
00218
00219 if (verbose)
00220 trace("Sdebug %.5f _%s_ stuck into send buff %s -> %s",
00221 Scheduler::instance().clock(),
00222 net_id.dump(), p.src.dump(), p.dest.dump());
00223
00224 for (c = 0 ; c < SEND_BUF_SIZE ; c ++)
00225 if (send_buf[c].p.pkt == NULL)
00226 {
00227 send_buf[c].t = Scheduler::instance().clock();
00228 send_buf[c].p = p;
00229 return;
00230 }
00231 else if (send_buf[c].t < min)
00232 {
00233 min = send_buf[c].t;
00234 min_index = c;
00235 }
00236
00237
00238 dropSendBuff(send_buf[min_index].p);
00239 send_buf[min_index].t = Scheduler::instance().clock();
00240 send_buf[min_index].p = p;
00241 }
00242
00243 void
00244 DSRAgent::sendBufferCheck()
00245
00246
00247 {
00248
00249
00250 int c;
00251
00252 for (c = 0 ; c <SEND_BUF_SIZE ; c++) {
00253 if (send_buf[c].p.pkt == NULL)
00254 continue;
00255 if (Scheduler::instance().clock() - send_buf[c].t > SEND_TIMEOUT) {
00256 dropSendBuff(send_buf[c].p);
00257 send_buf[c].p.pkt = 0;
00258 continue;
00259 }
00260 #ifdef DEBUG
00261 trace("Sdebug %.5f _%s_ checking for route for dst %s",
00262 Scheduler::instance().clock(), net_id.dump(),
00263 send_buf[c].p.dest.dump());
00264 #endif
00265
00266 handlePktWithoutSR(send_buf[c].p, true);
00267 #ifdef DEBUG
00268 if (send_buf[c].p.pkt == NULL)
00269 trace("Sdebug %.5f _%s_ sendbuf pkt to %s liberated by handlePktWOSR",
00270 Scheduler::instance().clock(), net_id.dump(),
00271 send_buf[c].p.dest.dump());
00272 #endif
00273 }
00274 }
00275
00276
00277
00278
00279 static bool
00280 BackOffTest(Entry *e, Time time)
00281
00282
00283 {
00284 Time next = ((Time) (0x1 << (e->rt_reqs_outstanding * 2))) * rt_rq_period;
00285
00286 if (next > rt_rq_max_period)
00287 next = rt_rq_max_period;
00288
00289 if (next + e->last_rt_req > time)
00290 return false;
00291
00292
00293 if (e->rt_reqs_outstanding < 15)
00294 e->rt_reqs_outstanding++;
00295
00296 e->last_rt_req = time;
00297
00298 return true;
00299 }
00300
00301
00302
00303
00304 static class DSRAgentClass : public TclClass {
00305 public:
00306 DSRAgentClass() : TclClass("Agent/DSRAgent") {}
00307 TclObject* create(int, const char*const*) {
00308 return (new DSRAgent);
00309 }
00310 } class_DSRAgent;
00311
00312
00313
00314
00315 DSRAgent::DSRAgent(): Agent(PT_DSR), request_table(128), route_cache(NULL),
00316 send_buf_timer(this), flow_table(), ars_table()
00317 {
00318 int c;
00319 route_request_num = 1;
00320
00321 route_cache = makeRouteCache();
00322
00323 for (c = 0 ; c < RTREP_HOLDOFF_SIZE ; c++)
00324 rtrep_holdoff[c].requested_dest = invalid_addr;
00325 num_heldoff_rt_replies = 0;
00326
00327 target_ = 0;
00328 logtarget = 0;
00329
00330 grat_hold_victim = 0;
00331 for (c = 0; c < RTREP_HOLDOFF_SIZE ; c++) {
00332 grat_hold[c].t = 0;
00333 grat_hold[c].p.reset();
00334 }
00335
00336
00337
00338
00339
00340
00341 ll = 0;
00342 ifq = 0;
00343 mac_ = 0;
00344
00345 LIST_INSERT_HEAD(&agthead, this, link);
00346 #ifdef DSR_FILTER_TAP
00347 bzero(tap_uid_cache, sizeof(tap_uid_cache));
00348 #endif
00349 route_error_held = false;
00350 }
00351
00352 DSRAgent::~DSRAgent()
00353 {
00354 fprintf(stderr,"DFU: Don't do this! I haven't figured out ~DSRAgent\n");
00355 exit(-1);
00356 }
00357
00358 void
00359 DSRAgent::Terminate()
00360 {
00361 int c;
00362 for (c = 0 ; c < SEND_BUF_SIZE ; c++) {
00363 if (send_buf[c].p.pkt) {
00364 drop(send_buf[c].p.pkt, DROP_END_OF_SIMULATION);
00365 send_buf[c].p.pkt = 0;
00366 }
00367 }
00368 }
00369
00370 void
00371 DSRAgent::testinit()
00372 {
00373 struct hdr_sr hsr;
00374
00375 if (net_id == ID(1,::IP))
00376 {
00377 printf("adding route to 1\n");
00378 hsr.init();
00379 hsr.append_addr( 1, NS_AF_INET );
00380 hsr.append_addr( 2, NS_AF_INET );
00381 hsr.append_addr( 3, NS_AF_INET );
00382 hsr.append_addr( 4, NS_AF_INET );
00383
00384 route_cache->addRoute(Path(hsr.addrs(),
00385 hsr.num_addrs()), 0.0, ID(1,::IP));
00386 }
00387
00388 if (net_id == ID(3,::IP))
00389 {
00390 printf("adding route to 3\n");
00391 hsr.init();
00392 hsr.append_addr( 3, NS_AF_INET );
00393 hsr.append_addr( 2, NS_AF_INET );
00394 hsr.append_addr( 1, NS_AF_INET );
00395
00396 route_cache->addRoute(Path(hsr.addrs(),
00397 hsr.num_addrs()), 0.0, ID(3,::IP));
00398 }
00399 }
00400
00401
00402 int
00403 DSRAgent::command(int argc, const char*const* argv)
00404 {
00405 TclObject *obj;
00406
00407 if (argc == 2)
00408 {
00409 if (strcasecmp(argv[1], "testinit") == 0)
00410 {
00411 testinit();
00412 return TCL_OK;
00413 }
00414 if (strcasecmp(argv[1], "reset") == 0)
00415 {
00416 Terminate();
00417 return Agent::command(argc, argv);
00418 }
00419 if (strcasecmp(argv[1], "check-cache") == 0)
00420 {
00421 return route_cache->command(argc, argv);
00422 }
00423 if (strcasecmp(argv[1], "startdsr") == 0)
00424 {
00425 if (ID(1,::IP) == net_id)
00426 {
00427 trace("Sconfig %.5f tap: %s snoop: rts? %s errs? %s",
00428 Scheduler::instance().clock(),
00429 dsragent_use_tap ? "on" : "off",
00430 dsragent_snoop_source_routes ? "on" : "off",
00431 dsragent_snoop_forwarded_errors ? "on" : "off");
00432 trace("Sconfig %.5f salvage: %s !bd replies? %s",
00433 Scheduler::instance().clock(),
00434 dsragent_salvage_with_cache ? "on" : "off",
00435 dsragent_dont_salvage_bad_replies ? "on" : "off");
00436 trace("Sconfig %.5f grat error: %s grat reply: %s",
00437 Scheduler::instance().clock(),
00438 dsragent_propagate_last_error ? "on" : "off",
00439 dsragent_send_grat_replies ? "on" : "off");
00440 trace("Sconfig %.5f $reply for props: %s ring 0 search: %s",
00441 Scheduler::instance().clock(),
00442 dsragent_reply_from_cache_on_propagating ? "on" : "off",
00443 dsragent_ring_zero_search ? "on" : "off");
00444 }
00445
00446 send_buf_timer.sched(BUFFER_CHECK
00447 + BUFFER_CHECK * Random::uniform(1.0));
00448 return route_cache->command(argc,argv);
00449 }
00450 }
00451 else if(argc == 3)
00452 {
00453 if (strcasecmp(argv[1], "addr") == 0)
00454 {
00455 int temp;
00456 temp = Address::instance().str2addr(argv[2]);
00457 net_id = ID(temp, ::IP);
00458 flow_table.setNetAddr(net_id.addr);
00459 route_cache->net_id = net_id;
00460 return TCL_OK;
00461 }
00462 else if(strcasecmp(argv[1], "mac-addr") == 0)
00463 {
00464 MAC_id = ID(atoi(argv[2]), ::MAC);
00465 route_cache->MAC_id = MAC_id;
00466 return TCL_OK;
00467 }
00468
00469 if( (obj = TclObject::lookup(argv[2])) == 0)
00470 {
00471 fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1],
00472 argv[2]);
00473 return TCL_ERROR;
00474 }
00475
00476 if (strcasecmp(argv[1], "log-target") == 0) {
00477 logtarget = (Trace*) obj;
00478 return route_cache->command(argc, argv);
00479 }
00480 else if (strcasecmp(argv[1], "tracetarget") == 0 )
00481 {
00482 logtarget = (Trace*) obj;
00483 return route_cache->command(argc, argv);
00484 }
00485 else if (strcasecmp(argv[1], "install-tap") == 0)
00486 {
00487 mac_ = (Mac*) obj;
00488 mac_->installTap(this);
00489 return TCL_OK;
00490 }
00491 else if (strcasecmp(argv[1], "node") == 0)
00492 {
00493 node_ = (MobileNode *) obj;
00494 return TCL_OK;
00495 }
00496 else if (strcasecmp (argv[1], "port-dmux") == 0)
00497 {
00498 port_dmux_ = (NsObject *) obj;
00499 return TCL_OK;
00500 }
00501 }
00502 else if (argc == 4)
00503 {
00504 if (strcasecmp(argv[1], "add-ll") == 0)
00505 {
00506 if( (obj = TclObject::lookup(argv[2])) == 0) {
00507 fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1],
00508 argv[2]);
00509 return TCL_ERROR;
00510 }
00511 ll = (NsObject*) obj;
00512 if( (obj = TclObject::lookup(argv[3])) == 0) {
00513 fprintf(stderr, "DSRAgent: %s lookup of %s failed\n", argv[1],
00514 argv[3]);
00515 return TCL_ERROR;
00516 }
00517 ifq = (CMUPriQueue *) obj;
00518 return TCL_OK;
00519
00520 }
00521
00522
00523 }
00524 return Agent::command(argc, argv);
00525 }
00526
00527 void
00528 DSRAgent::sendOutBCastPkt(Packet *p)
00529 {
00530 hdr_cmn *cmh = hdr_cmn::access(p);
00531 if(cmh->direction() == hdr_cmn::UP)
00532 cmh->direction() = hdr_cmn::DOWN;
00533
00534 Scheduler::instance().schedule(ll, p, 0.0);
00535 }
00536
00537
00538
00539 void
00540 DSRAgent::recv(Packet* packet, Handler*)
00541
00542
00543 {
00544 hdr_sr *srh = hdr_sr::access(packet);
00545 hdr_ip *iph = hdr_ip::access(packet);
00546 hdr_cmn *cmh = hdr_cmn::access(packet);
00547
00548
00549 if (cmh->ptype() == PT_GAF) {
00550 if (iph->daddr() == (int)IP_BROADCAST) {
00551 if(cmh->direction() == hdr_cmn::UP)
00552 cmh->direction() = hdr_cmn::DOWN;
00553 Scheduler::instance().schedule(ll,packet,0);
00554 return;
00555 } else {
00556 target_->recv(packet, (Handler*)0);
00557 return;
00558 }
00559 }
00560
00561 assert(cmh->size() >= 0);
00562
00563 SRPacket p(packet, srh);
00564
00565
00566 p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
00567 p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
00568
00569 assert(logtarget != 0);
00570
00571 if (srh->valid() != 1) {
00572 unsigned int dst = cmh->next_hop();
00573 if (dst == IP_BROADCAST) {
00574
00575
00576 if (p.src == net_id)
00577
00578 sendOutBCastPkt(packet);
00579 else
00580
00581 port_dmux_->recv(packet, (Handler*)0);
00582
00583 } else {
00584
00585
00586 srh->init();
00587 cmh->size() += IP_HDR_LEN;
00588 if (verbose)
00589 trace("S %.9f _%s_ originating %s -> %s",
00590 Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
00591 p.dest.dump());
00592 handlePktWithoutSR(p, false);
00593 goto done;
00594 }
00595 }
00596 else if (srh->valid() == 1)
00597 {
00598 if (p.dest == net_id || p.dest == IP_broadcast)
00599 {
00600 handlePacketReceipt(p);
00601 goto done;
00602 }
00603
00604
00605
00606 if (dsragent_snoop_forwarded_errors && srh->route_error())
00607 {
00608 processBrokenRouteError(p);
00609 }
00610
00611 if (srh->route_request())
00612 {
00613 handleRouteRequest(p);
00614 }
00615 else
00616 {
00617 handleForwarding(p);
00618 }
00619 }
00620 else {
00621
00622 fprintf(stderr,"dsragent: Error-received Invalid pkt!\n");
00623 Packet::free(p.pkt);
00624 p.pkt =0;
00625 }
00626
00627 done:
00628 assert(p.pkt == 0);
00629
00630 p.pkt = 0;
00631 return;
00632 }
00633
00634
00635
00636
00637
00638 void
00639 DSRAgent::handlePktWithoutSR(SRPacket& p, bool retry)
00640
00641
00642 {
00643 hdr_sr *srh = hdr_sr::access(p.pkt);
00644 assert(srh->valid());
00645
00646 if (p.dest == net_id)
00647 {
00648 handlePacketReceipt(p);
00649 return;
00650 }
00651
00652
00653
00654
00655 ID dest;
00656 if (diff_subnet(p.dest,net_id)) {
00657 dest = ID(node_->base_stn(),::IP);
00658 p.dest = dest;
00659 }
00660
00661 if (route_cache->findRoute(p.dest, p.route, 1))
00662 {
00663 if (verbose)
00664 trace("S$hit %.5f _%s_ %s -> %s %s",
00665 Scheduler::instance().clock(), net_id.dump(),
00666 p.src.dump(), p.dest.dump(), p.route.dump());
00667 sendOutPacketWithRoute(p, true);
00668 return;
00669 }
00670 else
00671 {
00672 if (verbose)
00673 trace("S$miss %.5f _%s_ %s -> %s",
00674 Scheduler::instance().clock(), net_id.dump(),
00675 net_id.dump(), p.dest.dump());
00676
00677 getRouteForPacket(p, retry);
00678 return;
00679 }
00680 }
00681
00682 void
00683 DSRAgent::handlePacketReceipt(SRPacket& p)
00684
00685 {
00686 hdr_cmn *cmh = hdr_cmn::access(p.pkt);
00687 hdr_sr *srh = hdr_sr::access(p.pkt);
00688
00689 if (srh->route_reply())
00690 {
00691
00692
00693 acceptRouteReply(p);
00694 }
00695
00696 if (srh->route_request())
00697 {
00698 if (dsragent_reply_only_to_first_rtreq && ignoreRouteRequestp(p))
00699 {
00700
00701 Packet::free(p.pkt);
00702 p.pkt = 0;
00703 return;
00704 }
00705 else
00706 {
00707 request_table.insert(p.src, p.src, srh->rtreq_seq());
00708 returnSrcRouteToRequestor(p);
00709 }
00710 }
00711
00712 if (srh->route_error())
00713 {
00714 processBrokenRouteError(p);
00715 }
00716
00717 if (srh->flow_unknown())
00718 processUnknownFlowError(p, false);
00719
00720 if (srh->flow_default_unknown())
00721 processUnknownFlowError(p, true);
00722
00723
00724
00725
00726 assert(p.dest == net_id || p.dest == MAC_id);
00727
00728 #if 0
00729 if (iph->dport() == 255) {
00730 int mask = Address::instance().portmask();
00731 int shift = Address::instance().portshift();
00732 iph->daddr() = ((iph->dport() & mask) << shift) | ((~(mask) << shift) & iph->dst());
00733 }
00734 #endif
00735
00736 cmh->size() -= srh->size();
00737 srh->valid() = 0;
00738 cmh->size() -= IP_HDR_LEN;
00739 target_->recv(p.pkt, (Handler*)0);
00740 p.pkt = 0;
00741
00742 }
00743
00744
00745 void
00746 DSRAgent::handleDefaultForwarding(SRPacket &p) {
00747 hdr_ip *iph = hdr_ip::access(p.pkt);
00748 u_int16_t flowid;
00749 int flowidx;
00750
00751 if (!flow_table.defaultFlow(p.src.addr, p.dest.addr, flowid)) {
00752 sendUnknownFlow(p, true);
00753 assert(p.pkt == 0);
00754 return;
00755 }
00756
00757 if ((flowidx = flow_table.find(p.src.addr, p.dest.addr, flowid)) == -1) {
00758 sendUnknownFlow(p, false, flowid);
00759 assert(p.pkt == 0);
00760 return;
00761 }
00762
00763 if (iph->ttl() != flow_table[flowidx].expectedTTL) {
00764 sendUnknownFlow(p, true);
00765 assert(p.pkt == 0);
00766 return;
00767 }
00768
00769
00770
00771 handleFlowForwarding(p, flowidx);
00772 }
00773
00774 void
00775 DSRAgent::handleFlowForwarding(SRPacket &p, int flowidx) {
00776 hdr_sr *srh = hdr_sr::access(p.pkt);
00777 hdr_ip *iph = hdr_ip::access(p.pkt);
00778 hdr_cmn *cmnh = hdr_cmn::access(p.pkt);
00779 int amt;
00780
00781 assert(flowidx >= 0);
00782 assert(!srh->num_addrs());
00783
00784 cmnh->next_hop() = flow_table[flowidx].nextHop;
00785 cmnh->addr_type() = ::IP;
00786
00787 cmnh->xmit_failure_ = XmitFlowFailureCallback;
00788 cmnh->xmit_failure_data_ = (void *) this;
00789
00790
00791
00792 assert(cmnh->direction() == hdr_cmn::UP);
00793
00794 if (!iph->ttl()--) {
00795 drop(p.pkt, DROP_RTR_TTL);
00796 p.pkt = 0;
00797 return;
00798 }
00799
00800 trace("SFf %.9f _%s_ %d [%s -> %s] %d to %d",
00801 Scheduler::instance().clock(), net_id.dump(), cmnh->uid(),
00802 p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId,
00803 flow_table[flowidx].nextHop);
00804
00805
00806 if (!srh->salvaged() &&
00807 (amt = ars_table.findAndClear(cmnh->uid(), flow_table[flowidx].flowId)) &&
00808 p.route.index() - amt > 0) {
00809 trace("SFARS %.9f _%s_ %d [%s -> %s] %d %d",
00810 Scheduler::instance().clock(), net_id.dump(), cmnh->uid(),
00811 p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId, amt);
00812
00813
00814 p.route = flow_table[flowidx].sourceRoute;
00815 p.route.index() -= amt;
00816 sendRouteShortening(p, p.route.index(),
00817 flow_table[flowidx].sourceRoute.index());
00818 }
00819
00820 if (dsragent_always_reestablish) {
00821
00822
00823
00824
00825 flow_table[flowidx].timeout = Scheduler::instance().clock() +
00826 default_flow_timeout;
00827 }
00828
00829 cmnh->direction() = hdr_cmn::DOWN;
00830 Scheduler::instance().schedule(ll, p.pkt, 0);
00831 p.pkt = 0;
00832 }
00833
00834 void
00835 DSRAgent::handleFlowForwarding(SRPacket &p) {
00836 hdr_sr *srh = hdr_sr::access(p.pkt);
00837 hdr_ip *iph = hdr_ip::access(p.pkt);
00838 int flowidx = flow_table.find(p.src.addr, p.dest.addr, srh->flow_id());
00839
00840 assert(srh->flow_header());
00841
00842 if (srh->num_addrs()) {
00843 assert(srh->flow_timeout());
00844
00845 if (flowidx == -1) {
00846 flow_table.cleanup();
00847 flowidx = flow_table.createEntry(p.src.addr, p.dest.addr, srh->flow_id());
00848
00849 assert(flowidx != -1);
00850
00851 flow_table[flowidx].timeout = Scheduler::instance().clock() +
00852 srh->flow_timeout_time();
00853 flow_table[flowidx].hopCount = srh->hopCount();
00854 flow_table[flowidx].expectedTTL = iph->ttl();
00855 flow_table[flowidx].sourceRoute = p.route;
00856 flow_table[flowidx].nextHop = srh->get_next_addr();
00857 assert(srh->hopCount() == srh->cur_addr());
00858 assert(srh->get_next_type() == ::IP);
00859 assert(flow_table[flowidx].sourceRoute[flow_table[flowidx].hopCount] ==
00860 net_id);
00861
00862 flow_table[flowidx].count = 0;
00863 flow_table[flowidx].allowDefault = false;
00864 }
00865
00866 assert(flowidx != -1);
00867
00868
00869 srh->hopCount()++;
00870 return;
00871 }
00872
00873 if (flowidx == -1) {
00874
00875 sendUnknownFlow(p, false, srh->flow_id());
00876 assert(p.pkt == 0);
00877 return;
00878 }
00879
00880
00881
00882 srh->hopCount()++;
00883
00884
00885 handleFlowForwarding(p, flowidx);
00886 }
00887
00888 void
00889 DSRAgent::handleForwarding(SRPacket &p)
00890
00891
00892 {
00893 hdr_sr *srh = hdr_sr::access(p.pkt);
00894 hdr_ip *iph = hdr_ip::access(p.pkt);
00895 hdr_cmn *ch = hdr_cmn::access(p.pkt);
00896 bool flowOnly = !srh->num_addrs();
00897
00898 if (srh->flow_header())
00899 handleFlowForwarding(p);
00900 else if (!srh->num_addrs())
00901 handleDefaultForwarding(p);
00902
00903 if (flowOnly)
00904 return;
00905
00906 assert(p.pkt);
00907
00908
00909
00910 assert(p.route[p.route.index()] == net_id
00911 || p.route[p.route.index()] == MAC_id);
00912
00913 if (p.route.index() >= p.route.length())
00914 {
00915 fprintf(stderr,"dfu: ran off the end of a source route\n");
00916 trace("SDFU: ran off the end of a source route\n");
00917 drop(p.pkt, DROP_RTR_ROUTE_LOOP);
00918 p.pkt = 0;
00919
00920 return;
00921 }
00922
00923
00924 if (dsragent_snoop_source_routes)
00925 route_cache->noticeRouteUsed(p.route, Scheduler::instance().clock(),
00926 net_id);
00927
00928
00929
00930 ch->size() -= srh->size();
00931
00932
00933 if (!iph->ttl()--) {
00934 drop(p.pkt, DROP_RTR_TTL);
00935 p.pkt = 0;
00936 return;
00937 }
00938
00939
00940 sendOutPacketWithRoute(p, false);
00941 }
00942
00943 void
00944 DSRAgent::handleRouteRequest(SRPacket &p)
00945
00946 {
00947 hdr_sr *srh = hdr_sr::access(p.pkt);
00948 assert (srh->route_request());
00949
00950 #ifdef notdef
00951 {
00952 int src = mac_->hdr_src(HDR_MAC(p.pkt));
00953
00954 if(mac_->is_neighbor(src) == 0) {
00955 Packet::free(p.pkt);
00956 p.pkt = 0;
00957 return;
00958 }
00959 }
00960 #endif
00961
00962 if (ignoreRouteRequestp(p))
00963 {
00964 if (verbose_srr)
00965 trace("SRR %.5f _%s_ dropped %s #%d (ignored)",
00966 Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
00967 srh->rtreq_seq());
00968 Packet::free(p.pkt);
00969 p.pkt = 0;
00970 return;
00971 }
00972
00973
00974 request_table.insert(p.src, p.src, srh->rtreq_seq());
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 if ((srh->max_propagation() == 0 || dsragent_reply_from_cache_on_propagating)
00985 && replyFromRouteCache(p))
00986 return;
00987
00988 #ifdef NEW_REQUEST_LOGIC
00989
00990
00991
00992 if(ifq->prq_length() > 10) {
00993 trace("SRR %.9f _%s_ discarding %s #%d (ifq length %d)",
00994 Scheduler::instance().clock(),
00995 net_id.dump(),
00996 p.src.dump(),
00997 srh->rtreq_seq(),
00998 ifq->prq_length());
00999 Packet::free(p.pkt);
01000 p.pkt = 0;
01001 return;
01002 }
01003
01004
01005
01006
01007 {
01008 double atime = mac_->air_time_free(10);
01009
01010 if(atime > 0.0 && atime < 0.15) {
01011 trace("SRR %.9f _%s_ discarding %s #%d (free air time %f)",
01012 Scheduler::instance().clock(),
01013 net_id.dump(),
01014 p.src.dump(),
01015 srh->rtreq_seq(),
01016 atime);
01017 Packet::free(p.pkt);
01018 p.pkt = 0;
01019 return;
01020 }
01021 }
01022 #endif
01023
01024
01025 if (p.route.length() > srh->max_propagation())
01026 {
01027 if (verbose_srr)
01028 trace("SRR %.5f _%s_ dropped %s #%d (prop limit exceeded)",
01029 Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
01030 srh->rtreq_seq());
01031 Packet::free(p.pkt);
01032 p.pkt = 0;
01033 return;
01034 }
01035
01036
01037 if (p.route.full())
01038 {
01039 trace("SRR %.5f _%s_ dropped %s #%d (SR full)",
01040 Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
01041 srh->rtreq_seq());
01042
01043
01044
01045 Packet::free(p.pkt);
01046 p.pkt = 0;
01047 return;
01048 }
01049
01050
01051 p.route.appendToPath(net_id);
01052
01053 if (verbose_srr)
01054 trace("SRR %.5f _%s_ rebroadcast %s #%d ->%s %s",
01055 Scheduler::instance().clock(), net_id.dump(), p.src.dump(),
01056 srh->rtreq_seq(), p.dest.dump(), p.route.dump());
01057
01058 sendOutPacketWithRoute(p, false);
01059 return;
01060 }
01061
01062
01063
01064
01065 bool
01066 DSRAgent::ignoreRouteRequestp(SRPacket &p)
01067
01068 {
01069 hdr_sr *srh = hdr_sr::access(p.pkt);
01070
01071 if (request_table.get(p.src) >= srh->rtreq_seq())
01072 {
01073
01074 return true;
01075 }
01076 if (p.route.member(net_id,MAC_id))
01077 {
01078 return true;
01079 }
01080
01081 if (p.route.full())
01082 {
01083
01084
01085
01086
01087 return true;
01088 }
01089 return false;
01090 }
01091
01092
01093 bool
01094 DSRAgent::replyFromRouteCache(SRPacket &p)
01095
01096
01097
01098 {
01099 Path rest_of_route;
01100 Path complete_route = p.route;
01101
01102
01103 assert(!p.route.member(net_id, MAC_id));
01104
01105
01106
01107
01108 if (!route_cache->findRoute(p.dest, rest_of_route, 0))
01109 {
01110 return false;
01111 }
01112
01113
01114
01115 assert(rest_of_route[0] == net_id || rest_of_route[0] == MAC_id);
01116
01117 if (rest_of_route.length() + p.route.length() > MAX_SR_LEN)
01118 return false;
01119
01120
01121 complete_route.appendPath(rest_of_route);
01122
01123
01124 ::compressPath(complete_route);
01125
01126 if (!complete_route.member(net_id, MAC_id))
01127 {
01128 return false;
01129 }
01130
01131
01132
01133 hdr_cmn *cmh = hdr_cmn::access(p.pkt);
01134 hdr_sr *srh = hdr_sr::access(p.pkt);
01135 int request_seqnum = srh->rtreq_seq();
01136
01137 if (PT_DSR != cmh->ptype()
01138 || srh->route_reply()
01139 || (srh->route_error() &&
01140 srh->down_links()[srh->num_route_errors()-1].tell_addr
01141 != GRAT_ROUTE_ERROR))
01142 {
01143 SRPacket p_copy = p;
01144 p.pkt = 0;
01145 srh->route_request() = 0;
01146
01147 p_copy.route = complete_route;
01148 p_copy.route.setIterator(p.route.length());
01149
01150 assert(p.route[p.route.index()] == net_id);
01151
01152 if (verbose) trace("Sdebug %.9f _%s_ splitting %s to %s",
01153 Scheduler::instance().clock(), net_id.dump(),
01154 p.route.dump(), p_copy.route.dump());
01155
01156 sendOutPacketWithRoute(p_copy,false);
01157 }
01158 else
01159 {
01160 Packet::free(p.pkt);
01161 p.pkt = 0;
01162 }
01163
01164
01165 p.route.appendToPath(net_id);
01166 p.route.reverseInPlace();
01167 route_cache->addRoute(p.route, Scheduler::instance().clock(), net_id);
01168 p.dest = p.src;
01169 p.src = net_id;
01170 p.pkt = allocpkt();
01171
01172 hdr_ip *iph = hdr_ip::access(p.pkt);
01173 iph->saddr() = Address::instance().create_ipaddr(p.src.addr, RT_PORT);
01174 iph->sport() = RT_PORT;
01175 iph->daddr() = Address::instance().create_ipaddr(p.dest.addr, RT_PORT);
01176 iph->dport() = RT_PORT;
01177 iph->ttl() = 255;
01178
01179 srh = hdr_sr::access(p.pkt);
01180 srh->init();
01181 for (int i = 0 ; i < complete_route.length() ; i++)
01182 complete_route[i].fillSRAddr(srh->reply_addrs()[i]);
01183 srh->route_reply_len() = complete_route.length();
01184 srh->route_reply() = 1;
01185
01186
01187 srh->rtreq_seq() = request_seqnum;
01188
01189 hdr_cmn *cmnh = hdr_cmn::access(p.pkt);
01190 cmnh->ptype() = PT_DSR;
01191 cmnh->size() = IP_HDR_LEN;
01192
01193 if (verbose_srr)
01194 trace("SRR %.9f _%s_ cache-reply-sent %s -> %s #%d (len %d) %s",
01195 Scheduler::instance().clock(), net_id.dump(),
01196 p.src.dump(), p.dest.dump(), request_seqnum, complete_route.length(),
01197 complete_route.dump());
01198 sendOutPacketWithRoute(p, true);
01199 return true;
01200 }
01201
01202
01203 void
01204 DSRAgent::sendOutPacketWithRoute(SRPacket& p, bool fresh, Time delay)
01205
01206
01207
01208
01209
01210 {
01211 hdr_sr *srh = hdr_sr::access(p.pkt);
01212 hdr_cmn *cmnh = hdr_cmn::access(p.pkt);
01213
01214 assert(srh->valid());
01215 assert(cmnh->size() > 0);
01216
01217 ID dest;
01218 if (diff_subnet(p.dest,net_id)) {
01219 dest = ID(node_->base_stn(),::IP);
01220 p.dest = dest;
01221 }
01222
01223 if (p.dest == net_id)
01224 {
01225 recv(p.pkt, (Handler *) 0);
01226 p.pkt = 0;
01227 return;
01228 }
01229
01230 if (fresh)
01231 {
01232 p.route.resetIterator();
01233 if (verbose && !srh->route_request())
01234 {
01235 trace("SO %.9f _%s_ originating %s %s",
01236 Scheduler::instance().clock(),
01237 net_id.dump(), packet_info.name(cmnh->ptype()), p.route.dump());
01238 }
01239 }
01240
01241 p.route.fillSR(srh);
01242
01243
01244 cmnh->direction() = hdr_cmn::DOWN;
01245
01246
01247 if (dsragent_enable_flowstate &&
01248 p.src == net_id && !srh->route_request() && !srh->cur_addr() &&
01249
01250
01251 !srh->route_error() && !srh->route_reply()) {
01252 hdr_ip *iph = hdr_ip::access(p.pkt);
01253 int flowidx;
01254 u_int16_t flowid, default_flowid;
01255 double now = Scheduler::instance().clock();
01256
01257
01258 if (dsragent_prefer_default_flow &&
01259 flow_table.defaultFlow(p.src.addr, p.dest.addr, flowid) &&
01260 -1 != (flowidx = flow_table.find(p.src.addr, p.dest.addr, flowid)) &&
01261 flow_table[flowidx].timeout >= now &&
01262 (!dsragent_prefer_shorter_over_default ||
01263 flow_table[flowidx].sourceRoute.length() <= p.route.length()) &&
01264 !(p.route == flow_table[flowidx].sourceRoute)) {
01265
01266 p.route = flow_table[flowidx].sourceRoute;
01267 p.route.fillSR(srh);
01268 }
01269
01270 flowidx = flow_table.find(p.src.addr, p.dest.addr, p.route);
01271
01272 if (flowidx == -1 || flow_table[flowidx].timeout < now) {
01273
01274 flow_table.cleanup();
01275 flowid = flow_table.generateNextFlowId(p.dest.addr, true);
01276 flowidx = flow_table.createEntry(p.src.addr, p.dest.addr, flowid);
01277 assert(flowidx != -1);
01278
01279
01280 flow_table[flowidx].count = 1;
01281 flow_table[flowidx].lastAdvRt = Scheduler::instance().clock();
01282 flow_table[flowidx].timeout = now + default_flow_timeout;
01283 flow_table[flowidx].hopCount = 0;
01284 flow_table[flowidx].expectedTTL = iph->ttl();
01285 flow_table[flowidx].allowDefault = true;
01286 flow_table[flowidx].sourceRoute = p.route;
01287 flow_table[flowidx].nextHop = srh->get_next_addr();
01288 assert(srh->get_next_type() == ::IP);
01289
01290
01291 srh->flow_timeout() = 1;
01292 srh->flow_timeout_time() = default_flow_timeout;
01293 srh->cur_addr() = srh->cur_addr() + 1;
01294 } else if (flow_table[flowidx].count <= END_TO_END_COUNT ||
01295 flow_table[flowidx].lastAdvRt <
01296 (Scheduler::instance().clock() - min_adv_interval)) {
01297
01298 if (flow_table[flowidx].expectedTTL != iph->ttl())
01299 flow_table[flowidx].allowDefault = false;
01300
01301 flow_table[flowidx].count++;
01302 flow_table[flowidx].lastAdvRt = Scheduler::instance().clock();
01303
01304 srh->flow_timeout() = 1;
01305 if (dsragent_always_reestablish)
01306 srh->flow_timeout_time() = default_flow_timeout;
01307 else
01308 srh->flow_timeout_time() = (int)(flow_table[flowidx].timeout - now);
01309 srh->cur_addr() = srh->cur_addr() + 1;
01310 } else {
01311
01312 assert (flow_table[flowidx].sourceRoute == p.route);
01313 srh->flow_timeout() = srh->cur_addr() = srh->num_addrs() = 0;
01314 }
01315
01316 if (dsragent_always_reestablish) {
01317
01318 flow_table[flowidx].timeout = now + default_flow_timeout;
01319 }
01320
01321 cmnh->next_hop() = flow_table[flowidx].nextHop;
01322 cmnh->addr_type() = ::IP;
01323
01324 if (flow_table.defaultFlow(p.src.addr, p.dest.addr, default_flowid) &&
01325 flow_table[flowidx].flowId == default_flowid &&
01326 !srh->num_addrs() && iph->ttl() == flow_table[flowidx].expectedTTL &&
01327 flow_table[flowidx].allowDefault) {
01328
01329 assert(!srh->flow_header());
01330 } else {
01331 srh->flow_header() = 1;
01332 srh->flow_id() = flow_table[flowidx].flowId;
01333 srh->hopCount() = 1;
01334 }
01335
01336 trace("SF%ss %.9f _%s_ %d [%s -> %s] %d(%d) to %d %s",
01337 srh->num_addrs() ? "EST" : "",
01338 Scheduler::instance().clock(), net_id.dump(), cmnh->uid(),
01339 p.src.dump(), p.dest.dump(), flow_table[flowidx].flowId,
01340 srh->flow_header(), flow_table[flowidx].nextHop,
01341 srh->num_addrs() ? srh->dump() : "");
01342
01343 cmnh->size() += srh->size();
01344 cmnh->xmit_failure_ = srh->num_addrs() ? XmitFailureCallback :
01345 XmitFlowFailureCallback;
01346 cmnh->xmit_failure_data_ = (void *) this;
01347
01348 assert(!srh->num_addrs() || srh->flow_timeout());
01349 } else {
01350
01351 assert(p.src != net_id || !srh->flow_header());
01352 cmnh->size() += srh->size();
01353
01354 if (srh->route_request())
01355 {
01356 cmnh->xmit_failure_ = 0;
01357 cmnh->next_hop() = MAC_BROADCAST;
01358 cmnh->addr_type() = NS_AF_ILINK;
01359 }
01360 else
01361 {
01362 cmnh->xmit_failure_ = XmitFailureCallback;
01363 cmnh->xmit_failure_data_ = (void *) this;
01364
01365 cmnh->next_hop() = srh->get_next_addr();
01366 cmnh->addr_type() = srh->get_next_type();
01367 srh->cur_addr() = srh->cur_addr() + 1;
01368 }
01369 }
01370
01371
01372
01373
01374
01375 #ifdef notdef
01376 if (ifq->prq_length() > 25)
01377 trace("SIFQ %.5f _%s_ len %d",
01378 Scheduler::instance().clock(),
01379 net_id.dump(), ifq->prq_length());
01380 #endif
01381 #ifdef NEW_IFQ_LOGIC
01382
01383
01384
01385
01386
01387
01388
01389
01390 if(ifq->prq_isfull(p.pkt)) {
01391 xmitFailed(p.pkt, DROP_IFQ_QFULL);
01392 p.pkt = 0;
01393 return;
01394 }
01395 #endif
01396
01397
01398 assert(!srh->flow_header() || !srh->num_addrs() || srh->flow_timeout());
01399
01400
01401 if (srh->route_request())
01402 {
01403 Scheduler::instance().schedule(ll, p.pkt,
01404 Random::uniform(RREQ_JITTER) + delay);
01405 }
01406 else
01407 {
01408 Scheduler::instance().schedule(ll, p.pkt, delay);
01409 }
01410 p.pkt = NULL;
01411 }
01412
01413 void
01414 DSRAgent::getRouteForPacket(SRPacket &p, bool retry)
01415
01416
01417
01418 {
01419
01420
01421
01422 Entry *e = request_table.getEntry(p.dest);
01423 Time time = Scheduler::instance().clock();
01424
01425 #if 0
01426
01427
01428
01429
01430
01431
01432
01433 SRPacket rrp = p;
01434 rrp.pkt = p.pkt->copy();
01435 hdr_sr *srh = hdr_sr::access(rrp.pkt);
01436 hdr_ip *iph = hdr_ip::access(rrp.pkt);
01437 hdr_cmn *cmh = hdr_cmn::access(rrp.pkt);
01438
01439 iph->daddr() = Address::instance().create_ipaddr(p.dest.getNSAddr_t(),RT_PORT);
01440 iph->dport() = RT_PORT;
01441
01442 iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);
01443 iph->sport() = RT_PORT;
01444 cmnh->ptype() = PT_DSR;
01445 cmnh->size() = size_;
01446 cmnh->num_forwards() = 0;
01447 #endif
01448
01449
01450 SRPacket rrp;
01451 rrp.dest = p.dest;
01452 rrp.src = net_id;
01453 rrp.pkt = allocpkt();
01454
01455 hdr_sr *srh = hdr_sr::access(rrp.pkt);
01456 hdr_ip *iph = hdr_ip::access(rrp.pkt);
01457 hdr_cmn *cmnh = hdr_cmn::access(rrp.pkt);
01458
01459 iph->daddr() = Address::instance().create_ipaddr(p.dest.getNSAddr_t(),RT_PORT);
01460 iph->dport() = RT_PORT;
01461 iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);
01462 iph->sport() = RT_PORT;
01463 cmnh->ptype() = PT_DSR;
01464 cmnh->size() = size_ + IP_HDR_LEN;
01465 cmnh->num_forwards() = 0;
01466
01467 srh->init();
01468
01469
01470 if (BackOffTest(e, time)) {
01471
01472
01473 #ifdef NEW_SALVAGE_LOGIC
01474 if(p.src != net_id) {
01475
01476 assert(dsr_salvage_max_requests > 0);
01477 assert(p.pkt);
01478
01479 if(e->rt_reqs_outstanding > dsr_salvage_max_requests) {
01480 drop(p.pkt, DROP_RTR_NO_ROUTE);
01481 p.pkt = 0;
01482
01483
01484 Packet::free(rrp.pkt);
01485 rrp.pkt = 0;
01486
01487 return;
01488 }
01489 }
01490 #endif
01491
01492 if (dsragent_ring_zero_search) {
01493
01494 e->last_type = LIMIT0;
01495 sendOutRtReq(rrp, 0);
01496 } else {
01497
01498 e->last_type = UNLIMIT;
01499 sendOutRtReq(rrp, MAX_SR_LEN);
01500 }
01501
01502 e->last_arp = time;
01503 } else if (LIMIT0 == e->last_type &&
01504 #ifdef NEW_SALVAGE_LOGIC
01505 (dsr_salvage_allow_propagating || p.src == net_id) &&
01506 #endif
01507 (time - e->last_arp) > arp_timeout) {
01508
01509
01510
01511 e->last_type = UNLIMIT;
01512 sendOutRtReq(rrp, MAX_SR_LEN);
01513 }
01514 else {
01515
01516 if (!retry && verbose_srr)
01517 trace("SRR %.5f _%s_ RR-not-sent %s -> %s",
01518 Scheduler::instance().clock(),
01519 net_id.dump(), rrp.src.dump(), rrp.dest.dump());
01520 Packet::free(rrp.pkt);
01521 rrp.pkt = 0;
01522 }
01523
01524
01525 if (!retry) {
01526 stickPacketInSendBuffer(p);
01527 p.pkt = 0;
01528 }
01529
01530 }
01531
01532 void
01533 DSRAgent::sendOutRtReq(SRPacket &p, int max_prop)
01534
01535
01536
01537 {
01538 hdr_sr *srh = hdr_sr::access(p.pkt);
01539 assert(srh->valid());
01540
01541 srh->route_request() = 1;
01542 srh->rtreq_seq() = route_request_num++;
01543 srh->max_propagation() = max_prop;
01544 p.route.reset();
01545 p.route.appendToPath(net_id);
01546
01547 if (dsragent_propagate_last_error && route_error_held
01548 && Scheduler::instance().clock() - route_error_data_time < max_err_hold)
01549 {
01550 assert(srh->num_route_errors() < MAX_ROUTE_ERRORS);
01551 srh->route_error() = 1;
01552 link_down *deadlink = &(srh->down_links()[srh->num_route_errors()]);
01553 deadlink->addr_type = NS_AF_INET;
01554 deadlink->from_addr = err_from.getNSAddr_t();
01555 deadlink->to_addr = err_to.getNSAddr_t();
01556 deadlink->tell_addr = GRAT_ROUTE_ERROR;
01557 srh->num_route_errors() += 1;
01558
01559
01560
01561 if(max_prop > 0) route_error_held = false;
01562 }
01563
01564 if (verbose_srr)
01565 trace("SRR %.5f _%s_ new-request %d %s #%d -> %s",
01566 Scheduler::instance().clock(), net_id.dump(),
01567 max_prop, p.src.dump(), srh->rtreq_seq(), p.dest.dump());
01568 sendOutPacketWithRoute(p, false);
01569 }
01570
01571 void
01572 DSRAgent::returnSrcRouteToRequestor(SRPacket &p)
01573
01574
01575
01576 {
01577 hdr_sr *old_srh = hdr_sr::access(p.pkt);
01578
01579 if (p.route.full())
01580 return;
01581
01582 SRPacket p_copy = p;
01583 p_copy.pkt = allocpkt();
01584 p_copy.dest = p.src;
01585 p_copy.src = net_id;
01586
01587 p_copy.route.appendToPath(net_id);
01588
01589 hdr_ip *new_iph = hdr_ip::access(p_copy.pkt);
01590
01591 new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
01592 new_iph->dport() = RT_PORT;
01593
01594 new_iph->saddr() =
01595 Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT);
01596 new_iph->sport() = RT_PORT;
01597 new_iph->ttl() = 255;
01598
01599 hdr_sr *new_srh = hdr_sr::access(p_copy.pkt);
01600 new_srh->init();
01601 for (int i = 0 ; i < p_copy.route.length() ; i++)
01602 p_copy.route[i].fillSRAddr(new_srh->reply_addrs()[i]);
01603 new_srh->route_reply_len() = p_copy.route.length();
01604 new_srh->route_reply() = 1;
01605
01606
01607 new_srh->rtreq_seq() = old_srh->rtreq_seq();
01608
01609 hdr_cmn *new_cmnh = hdr_cmn::access(p_copy.pkt);
01610 new_cmnh->ptype() = PT_DSR;
01611 new_cmnh->size() = IP_HDR_LEN;
01612
01613 if (verbose_srr)
01614 trace("SRR %.9f _%s_ reply-sent %s -> %s #%d (len %d) %s",
01615 Scheduler::instance().clock(), net_id.dump(),
01616 p_copy.src.dump(), p_copy.dest.dump(), old_srh->rtreq_seq(),
01617 p_copy.route.length(), p_copy.route.dump());
01618
01619
01620
01621 p_copy.route.reverseInPlace();
01622 route_cache->addRoute(p_copy.route, Scheduler::instance().clock(), net_id);
01623
01624 p_copy.route.resetIterator();
01625 p_copy.route.fillSR(new_srh);
01626 new_cmnh->size() += new_srh->size();
01627
01628
01629
01630
01631
01632 {
01633 double d = Random::uniform(RREQ_JITTER);
01634 #if 0
01635 fprintf(stderr, "Random Delay: %f\n", d);
01636 #endif
01637 Scheduler::instance().schedule(this, p_copy.pkt, d);
01638 }
01639 }
01640
01641 int
01642 DSRAgent::diff_subnet(ID dest, ID myid)
01643 {
01644 int dst = dest.addr;
01645 int id = myid.addr;
01646 char* dstnet = Address::instance().get_subnetaddr(dst);
01647 char * subnet = Address::instance().get_subnetaddr(id);
01648 if (subnet != NULL) {
01649 if (dstnet != NULL) {
01650 if (strcmp(dstnet, subnet) != 0) {
01651 delete [] dstnet;
01652 return 1;
01653 }
01654 delete [] dstnet;
01655 }
01656 delete [] subnet;
01657 }
01658 assert(dstnet == NULL);
01659 return 0;
01660 }
01661
01662
01663 void
01664 DSRAgent::acceptRouteReply(SRPacket &p)
01665
01666
01667
01668 {
01669 hdr_sr *srh = hdr_sr::access(p.pkt);
01670 Path reply_route(srh->reply_addrs(), srh->route_reply_len());
01671
01672 if (!srh->route_reply())
01673 {
01674 trace("SDFU non route containing packet given to acceptRouteReply");
01675 fprintf(stderr,
01676 "dfu: non route containing packet given to acceptRouteReply\n");
01677 }
01678
01679 bool good_reply = true;
01680
01681
01682 int i;
01683
01684 for (i = 0; i < reply_route.length()-1 ; i++)
01685 if (God::instance()->hops(reply_route[i].getNSAddr_t(),
01686 reply_route[i+1].getNSAddr_t()) != 1)
01687 {
01688 good_reply = false;
01689 break;
01690 }
01691
01692
01693 if (verbose_srr)
01694 trace("SRR %.9f _%s_ reply-received %d from %s %s #%d -> %s %s",
01695 Scheduler::instance().clock(), net_id.dump(),
01696 good_reply ? 1 : 0,
01697 p.src.dump(), reply_route[0].dump(), srh->rtreq_seq(),
01698 reply_route[reply_route.length()-1].dump(),
01699 reply_route.dump());
01700
01701
01702 route_cache->addRoute(reply_route, Scheduler::instance().clock(), p.src);
01703
01704
01705 Entry *e = request_table.getEntry(reply_route[reply_route.length()-1]);
01706 e->rt_reqs_outstanding = 0;
01707 e->last_rt_req = 0.0;
01708
01709
01710
01711 Time delay = 0.0;
01712 ID dest;
01713 for (int c = 0; c < SEND_BUF_SIZE; c++)
01714 {
01715 if (send_buf[c].p.pkt == NULL) continue;
01716
01717
01718 if (diff_subnet(send_buf[c].p.dest,net_id)) {
01719 dest = ID(node_->base_stn(),::IP);
01720 send_buf[c].p.dest = dest;
01721 }
01722
01723 if (route_cache->findRoute(send_buf[c].p.dest, send_buf[c].p.route, 1))
01724 {
01725 #ifdef DEBUG
01726 struct hdr_cmn *ch = HDR_CMN(send_buf[c].p.pkt);
01727 if(ch->size() < 0) {
01728 drop(send_buf[c].p.pkt, "XXX");
01729 abort();
01730 }
01731 #endif
01732 if (verbose)
01733 trace("Sdebug %.9f _%s_ liberated from sendbuf %s->%s %s",
01734 Scheduler::instance().clock(), net_id.dump(),
01735 send_buf[c].p.src.dump(), send_buf[c].p.dest.dump(),
01736 send_buf[c].p.route.dump());
01737
01738
01739
01740
01741 sendOutPacketWithRoute(send_buf[c].p, true, delay);
01742 delay += arp_timeout;
01743 send_buf[c].p.pkt = NULL;
01744 }
01745 }
01746 }
01747
01748 void
01749 DSRAgent::processUnknownFlowError(SRPacket &p, bool asDefault) {
01750 hdr_sr *srh = hdr_sr::access(p.pkt);
01751 int flowidx = -1;
01752 struct flow_error *fe;
01753 u_int16_t flowid;
01754
01755 if (asDefault) {
01756 assert (srh->flow_default_unknown() && srh->num_default_unknown());
01757 fe = &srh->unknown_defaults()[srh->num_default_unknown()-1];
01758 } else {
01759 assert (srh->flow_unknown() && srh->num_flow_unknown());
01760 fe = &srh->unknown_flows()[srh->num_flow_unknown()-1];
01761 if (!flow_table.defaultFlow(fe->flow_src, fe->flow_dst, flowid))
01762 goto skip_proc;
01763 }
01764
01765
01766 if (fe->flow_src != (int) net_id.addr)
01767 return;
01768
01769 if (-1 != (flowidx = flow_table.find(fe->flow_src, fe->flow_dst,
01770 asDefault ? flowid : fe->flow_id)))
01771 flow_table[flowidx].count = 0;
01772
01773 skip_proc:
01774 trace("SFEr %.9f _%s_ from %d re %d : %d [%d]",
01775 Scheduler::instance().clock(), net_id.dump(), p.src.addr, fe->flow_dst,
01776 asDefault ? -1 : fe->flow_id,
01777 flowidx != -1 ? flow_table[flowidx].count : -1);
01778
01779 if ((asDefault ? srh->num_default_unknown() : srh->num_flow_unknown()) == 1)
01780 return;
01781
01782 SRPacket p_copy = p;
01783 p_copy.pkt = p.pkt->copy();
01784
01785 hdr_sr *new_srh = hdr_sr::access(p_copy.pkt);
01786 hdr_ip *new_iph = hdr_ip::access(p_copy.pkt);
01787
01788
01789 if (asDefault)
01790 new_srh->num_default_unknown()--;
01791 else
01792 new_srh->num_flow_unknown()--;
01793
01794
01795 p_copy.dest = ID(fe[-1].flow_src, ::IP);
01796 p_copy.src = net_id;
01797
01798
01799 new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
01800 new_iph->dport() = RT_PORT;
01801
01802 new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT);
01803 new_iph->sport() = RT_PORT;
01804 new_iph->ttl() = 255;
01805
01806 new_srh->flow_header() = 0;
01807 new_srh->flow_timeout() = 0;
01808
01809
01810
01811 handlePktWithoutSR(p_copy, false);
01812 }
01813
01814 void
01815 DSRAgent::processBrokenRouteError(SRPacket& p)
01816
01817
01818
01819 {
01820 hdr_sr *srh = hdr_sr::access(p.pkt);
01821
01822 if (!srh->route_error())
01823 return;
01824
01825
01826
01827
01828
01829
01830
01831 assert(srh->num_route_errors() > 0);
01832 for (int c = 0 ; c < srh->num_route_errors() ; c++)
01833 {
01834 assert(srh->down_links()[c].addr_type == NS_AF_INET);
01835 route_cache->noticeDeadLink(ID(srh->down_links()[c].from_addr,::IP),
01836 ID(srh->down_links()[c].to_addr,::IP),
01837 Scheduler::instance().clock());
01838 flow_table.noticeDeadLink(ID(srh->down_links()[c].from_addr,::IP),
01839 ID(srh->down_links()[c].to_addr,::IP));
01840
01841 if (verbose_srr)
01842 trace("SRR %.9f _%s_ dead-link tell %d %d -> %d",
01843 Scheduler::instance().clock(), net_id.dump(),
01844 srh->down_links()[c].tell_addr,
01845 srh->down_links()[c].from_addr,
01846 srh->down_links()[c].to_addr);
01847 }
01848
01849 ID who = ID(srh->down_links()[srh->num_route_errors()-1].tell_addr, ::IP);
01850 if (who != net_id && who != MAC_id)
01851 {
01852
01853 return;
01854 }
01855
01856
01857
01858 route_error_held = true;
01859 err_from = ID(srh->down_links()[srh->num_route_errors()-1].from_addr,::IP);
01860 err_to = ID(srh->down_links()[srh->num_route_errors()-1].to_addr,::IP);
01861 route_error_data_time = Scheduler::instance().clock();
01862
01863 if (1 == srh->num_route_errors())
01864 {
01865
01866
01867
01868 return;
01869 }
01870
01871
01872
01873
01874 if (verbose)
01875 trace("Sdebug %.5f _%s_ unwrapping nested route error",
01876 Scheduler::instance().clock(), net_id.dump());
01877
01878 SRPacket p_copy = p;
01879 p_copy.pkt = p.pkt->copy();
01880
01881 hdr_sr *new_srh = hdr_sr::access(p_copy.pkt);
01882 hdr_ip *new_iph = hdr_ip::access(p_copy.pkt);
01883
01884
01885 new_srh->num_route_errors() -= 1;
01886
01887
01888 p_copy.dest = ID(new_srh->down_links()[new_srh->num_route_errors()-1].tell_addr, ::IP);
01889 p_copy.src = net_id;
01890
01891
01892 new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
01893 new_iph->dport() = RT_PORT;
01894
01895 new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT);
01896 new_iph->sport() = RT_PORT;
01897 new_iph->ttl() = 255;
01898
01899 new_srh->flow_header() = 0;
01900 new_srh->flow_timeout() = 0;
01901
01902
01903
01904 handlePktWithoutSR(p_copy, false);
01905 }
01906
01907 #ifdef DSR_FILTER_TAP
01908 int64_t dsr_tap = 0;
01909 int64_t dsr_tap_skip = 0;
01910 #endif
01911
01912
01913 void
01914 DSRAgent::processFlowARS(const Packet *packet) {
01915
01916 hdr_sr *srh = hdr_sr::access(packet);
01917 hdr_ip *iph = hdr_ip::access(packet);
01918 hdr_cmn *cmh = hdr_cmn::access(packet);
01919
01920
01921
01922 u_int16_t flowid;
01923 int flowidx;
01924 int shortamt;
01925
01926 assert(!srh->num_addrs());
01927
01928 if (srh->flow_header()) {
01929 flowid = srh->flow_id();
01930
01931
01932 if (-1 == (flowidx = flow_table.find(iph->saddr(), iph->daddr(), flowid)))
01933 return;
01934
01935 shortamt = flow_table[flowidx].hopCount - srh->hopCount();
01936 } else {
01937
01938 if (!flow_table.defaultFlow(iph->saddr(), iph->daddr(), flowid))
01939 return;
01940
01941
01942 if (-1 == (flowidx = flow_table.find(iph->saddr(), iph->daddr(), flowid)))
01943 return;
01944
01945 shortamt = iph->ttl() - flow_table[flowidx].expectedTTL;
01946 }
01947
01948
01949 if (shortamt <= 0)
01950 return;
01951
01952
01953 if (flow_table[flowidx].sourceRoute.length() < shortamt)
01954 return;
01955
01956 ars_table.insert(cmh->uid(), flowid, shortamt);
01957 }
01958
01959 void
01960 DSRAgent::tap(const Packet *packet)
01961
01962
01963 {
01964 hdr_sr *srh = hdr_sr::access(packet);
01965 hdr_ip *iph = hdr_ip::access(packet);
01966 hdr_cmn *cmh = hdr_cmn::access(packet);
01967
01968 if (!dsragent_use_tap) return;
01969
01970 if (!srh->valid()) return;
01971
01972 if (!srh->num_addrs()) {
01973 processFlowARS(packet);
01974 return;
01975 }
01976
01977
01978
01979 ID next_hop(srh->addrs()[srh->cur_addr()]);
01980 if (next_hop == net_id || next_hop == MAC_id) return;
01981
01982 SRPacket p((Packet *) packet, srh);
01983
01984
01985 p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
01986 p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
01987
01988
01989 if (p.src == net_id) return;
01990
01991 #ifdef DSR_FILTER_TAP
01992
01993
01994
01995
01996
01997 {
01998 int uid = cmh->uid();
01999 if(tap_uid_cache[(uid & TAP_BITMASK)] == uid) {
02000 dsr_tap_skip++;
02001 return;
02002 }
02003 dsr_tap++;
02004 tap_uid_cache[(uid & TAP_BITMASK)] = uid;
02005 }
02006 #endif
02007
02008
02009 if (srh->route_error())
02010 {
02011 if (verbose)
02012 trace("Sdebug _%s_ tap saw error %d", net_id.dump(), cmh->uid());
02013 processBrokenRouteError(p);
02014 }
02015
02016 if (srh->route_reply())
02017 {
02018 Path reply_path(srh->reply_addrs(), srh->route_reply_len());
02019 if(verbose)
02020 trace("Sdebug _%s_ tap saw route reply %d %s",
02021 net_id.dump(), cmh->uid(), reply_path.dump());
02022 route_cache->noticeRouteUsed(reply_path, Scheduler::instance().clock(),
02023 p.src);
02024 }
02025
02026
02027
02028
02029
02030
02031 if (srh->route_request()) return;
02032
02033
02034 if (dsragent_snoop_source_routes)
02035 {
02036 if (verbose)
02037 trace("Sdebug _%s_ tap saw route use %d %s", net_id.dump(),
02038 cmh->uid(), p.route.dump());
02039 route_cache->noticeRouteUsed(p.route, Scheduler::instance().clock(),
02040 net_id);
02041 }
02042
02043 if (PT_DSR == cmh->ptype()) return;
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095 if (p.route[p.route.index()] != net_id
02096 && p.route[p.route.index()] != MAC_id)
02097 {
02098 for (int i = p.route.index() + 1; i < p.route.length(); i++)
02099 if (p.route[i] == net_id || p.route[i] == MAC_id)
02100 {
02101 sendRouteShortening(p, p.route.index(), i);
02102 }
02103 }
02104 }
02105
02106 static GratReplyHoldDown *
02107 FindGratHoldDown(GratReplyHoldDown *hd, int sz, Path& query)
02108 {
02109 int c;
02110 for (c = 0; c < sz; c++)
02111 if (query == hd[c].p) return &hd[c];
02112 return NULL;
02113 }
02114
02115 void
02116 DSRAgent::sendRouteShortening(SRPacket &p, int heard_at, int xmit_at)
02117
02118
02119
02120
02121 {
02122
02123
02124 if (!dsragent_send_grat_replies) return;
02125
02126 if (verbose)
02127 trace("Sdebug %s consider grat arp for %s", net_id.dump(), p.route.dump());
02128 GratReplyHoldDown *g = FindGratHoldDown(grat_hold, RTREP_HOLDOFF_SIZE,
02129 p.route);
02130 if (!g)
02131 {
02132 grat_hold[grat_hold_victim].p = p.route;
02133 grat_hold_victim = (grat_hold_victim + 1) % RTREP_HOLDOFF_SIZE;
02134 g = &grat_hold[grat_hold_victim];
02135 }
02136 else if (Scheduler::instance().clock() - g->t < grat_hold_down_time) return;
02137 g->t = Scheduler::instance().clock();
02138
02139 SRPacket p_copy = p;
02140 p_copy.pkt = allocpkt();
02141 p_copy.dest = p.route[0];
02142 p_copy.src = net_id;
02143
02144
02145 p_copy.route[p_copy.route.index()] = net_id;
02146 p_copy.route.reverseInPlace();
02147 p_copy.route.removeSection(0,p_copy.route.index());
02148
02149 hdr_ip *new_iph = hdr_ip::access(p_copy.pkt);
02150
02151 new_iph->daddr() = Address::instance().create_ipaddr(p_copy.dest.getNSAddr_t(),RT_PORT);
02152 new_iph->dport() = RT_PORT;
02153
02154 new_iph->saddr() = Address::instance().create_ipaddr(p_copy.src.getNSAddr_t(),RT_PORT);
02155 new_iph->sport() = RT_PORT;
02156 new_iph->ttl() = 255;
02157
02158
02159 p.route.removeSection(heard_at, xmit_at);
02160 hdr_sr *new_srh = hdr_sr::access(p_copy.pkt);
02161 new_srh->init();
02162 for (int i = 0 ; i < p.route.length() ; i++)
02163 p.route[i].fillSRAddr(new_srh->reply_addrs()[i]);
02164 new_srh->route_reply_len() = p.route.length();
02165 new_srh->route_reply() = 1;
02166
02167 new_srh->rtreq_seq() = 0;
02168
02169 hdr_cmn *new_cmnh = hdr_cmn::access(p_copy.pkt);
02170 new_cmnh->ptype() = PT_DSR;
02171 new_cmnh->size() += IP_HDR_LEN;
02172
02173 if (verbose_srr)
02174 trace("SRR %.9f _%s_ gratuitous-reply-sent %s -> %s (len %d) %s",
02175 Scheduler::instance().clock(), net_id.dump(),
02176 p_copy.src.dump(), p_copy.dest.dump(), p.route.length(),
02177 p.route.dump());
02178
02179
02180 route_cache->addRoute(p_copy.route, Scheduler::instance().clock(), p.src);
02181 sendOutPacketWithRoute(p_copy, true);
02182 }
02183
02184
02185
02186
02187 void
02188 DSRAgent::trace(char* fmt, ...)
02189 {
02190 va_list ap;
02191
02192 if (!logtarget) return;
02193
02194 va_start(ap, fmt);
02195 vsprintf(logtarget->pt_->buffer(), fmt, ap);
02196 logtarget->pt_->dump();
02197 va_end(ap);
02198 }
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227 void
02228 DSRAgent::undeliverablePkt(Packet *pkt, int mine)
02229
02230
02231 {
02232 hdr_sr *srh = hdr_sr::access(pkt);
02233 hdr_ip *iph = hdr_ip::access(pkt);
02234 hdr_cmn *cmh;
02235
02236 SRPacket p(pkt,srh);
02237
02238
02239 p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
02240 p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
02241 p.pkt = mine ? pkt : pkt->copy();
02242
02243 srh = hdr_sr::access(p.pkt);
02244 iph = hdr_ip::access(p.pkt);
02245 cmh = hdr_cmn::access(p.pkt);
02246
02247
02248
02249 cmh->size() -= srh->size();
02250 srh->flow_timeout() = 0;
02251 srh->flow_header() = 0;
02252 cmh->size() += srh->size();
02253
02254 if (ID((Address::instance().get_nodeaddr(iph->saddr())),::IP) == net_id) {
02255
02256 cmh->size() -= srh->size();
02257 assert(cmh->size() >= 0);
02258
02259 handlePktWithoutSR(p, false);
02260
02261 return;
02262 }
02263
02264
02265
02266
02267 if(dsragent_salvage_with_cache == 0) {
02268 assert(mine);
02269 drop(pkt, DROP_RTR_NO_ROUTE);
02270 return;
02271 }
02272
02273 #ifdef NEW_SALVAGE_LOGIC
02274 if(srh->salvaged() >= dsr_salvage_max_attempts) {
02275 assert(mine);
02276 drop(pkt, DROP_RTR_SALVAGE);
02277 return;
02278 }
02279 #endif
02280
02281
02282 Path salvage_route;
02283
02284 if (route_cache->findRoute(p.dest, salvage_route, 0)) {
02285
02286 #if 0
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 int our_index = p.route.index();
02304
02305 p.route.setLength(our_index);
02306
02307
02308 p.route.appendPath(salvage_route);
02309
02310 p.route.setIterator(our_index);
02311 #else
02312 p.route = salvage_route;
02313 p.route.resetIterator();
02314 #endif
02315
02316 if (dsragent_dont_salvage_bad_replies && srh->route_reply()) {
02317
02318
02319
02320 ID to_id(srh->addrs()[srh->cur_addr()+1].addr,
02321 (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
02322 bool bad_reply = false;
02323
02324 for (int i = 0 ; i < srh->route_reply_len()-1; i++) {
02325
02326 if (net_id == ID(srh->reply_addrs()[i]) &&
02327 to_id == ID(srh->reply_addrs()[i+1]) ||
02328 (dsragent_require_bi_routes &&
02329 to_id == ID(srh->reply_addrs()[i]) &&
02330 net_id == ID(srh->reply_addrs()[i+1]))) {
02331
02332 bad_reply = true;
02333 break;
02334 }
02335 }
02336 if (bad_reply) {
02337
02338 srh->route_reply() = 0;
02339 if (PT_DSR == cmh->ptype() &&
02340 ! srh->route_request() &&
02341 ! srh->route_error()) {
02342
02343 if (verbose_srr)
02344 trace("SRR %.5f _%s_ --- %d dropping bad-reply %s -> %s",
02345 Scheduler::instance().clock(), net_id.dump(),
02346 cmh->uid(), p.src.dump(), p.dest.dump());
02347 if (mine)
02348 drop(pkt, DROP_RTR_MAC_CALLBACK);
02349 return;
02350 }
02351 }
02352 }
02353
02354 if (verbose_ssalv)
02355 trace("Ssalv %.5f _%s_ salvaging %s -> %s --- %d with %s",
02356 Scheduler::instance().clock(), net_id.dump(),
02357 p.src.dump(), p.dest.dump(),
02358 cmh->uid(), p.route.dump());
02359
02360
02361 cmh->size() -= srh->size();
02362 assert(cmh->size() >= 0);
02363 #ifdef NEW_SALVAGE_LOGIC
02364 srh->salvaged() += 1;
02365 #endif
02366 sendOutPacketWithRoute(p, false);
02367 }
02368 #ifdef NEW_SALVAGE_LOGIC
02369 else if(dsr_salvage_max_requests > 0) {
02370
02371
02372
02373
02374 if (verbose_ssalv)
02375 trace("Ssalv %.5f _%s_ adding to SB --- %d %s -> %s [%d]",
02376 Scheduler::instance().clock(),
02377 net_id.dump(),
02378 cmh->uid(),
02379 p.src.dump(), p.dest.dump(),
02380 srh->salvaged());
02381 stickPacketInSendBuffer(p);
02382 }
02383 #endif
02384 else {
02385
02386
02387
02388 if (verbose_ssalv)
02389 trace("Ssalv %.5f _%s_ dropping --- %d %s -> %s [%d]",
02390 Scheduler::instance().clock(),
02391 net_id.dump(), cmh->uid(),
02392 p.src.dump(), p.dest.dump(),
02393 srh->salvaged());
02394 if (mine)
02395 drop(pkt, DROP_RTR_NO_ROUTE);
02396 }
02397 }
02398
02399 #ifdef USE_GOD_FEEDBACK
02400 static int linkerr_is_wrong = 0;
02401 #endif
02402
02403 void
02404 DSRAgent::sendUnknownFlow(SRPacket &p, bool asDefault, u_int16_t flowid) {
02405 hdr_sr *srh = hdr_sr::access(p.pkt);
02406 hdr_ip *iph = hdr_ip::access(p.pkt);
02407 hdr_cmn *cmh = hdr_cmn::access(p.pkt);
02408 struct flow_error *fe;
02409
02410 assert(!srh->num_addrs());
02411 #if 0
02412
02413
02414
02415
02416
02417 assert(p.src != net_id);
02418
02419
02420
02421
02422 assert(srh->flow_header() ^ asDefault);
02423 #endif
02424
02425 if (p.src == net_id) {
02426 Packet::free(p.pkt);
02427 p.pkt = 0;
02428 return;
02429 }
02430
02431 undeliverablePkt(p.pkt, false);
02432
02433
02434 if (asDefault) {
02435 if (!srh->flow_default_unknown()) {
02436 srh->num_default_unknown() = 1;
02437 srh->flow_default_unknown() = 1;
02438 fe = srh->unknown_defaults();
02439 } else if (srh->num_default_unknown() < MAX_ROUTE_ERRORS) {
02440 fe = srh->unknown_defaults() + srh->num_default_unknown();
02441 srh->num_default_unknown()++;
02442 } else {
02443 trace("SYFU %.5f _%s_ dumping maximally nested Flow error %d -> %d",
02444 Scheduler::instance().clock(), net_id.dump(), p.src.addr, p.dest.addr);
02445
02446 Packet::free(p.pkt);
02447 p.pkt = 0;
02448 return;
02449 }
02450 } else {
02451 if (!srh->flow_unknown()) {
02452 srh->num_flow_unknown() = 1;
02453 srh->flow_unknown() = 1;
02454 fe = srh->unknown_flows();
02455 } else if (srh->num_default_unknown() < MAX_ROUTE_ERRORS) {
02456 fe = srh->unknown_flows() + srh->num_flow_unknown();
02457 srh->num_flow_unknown()++;
02458 } else {
02459 trace("SYFU %.5f _%s_ dumping maximally nested Flow error %d -> %d",
02460 Scheduler::instance().clock(), net_id.dump(), p.src.addr, p.dest.addr);
02461
02462 Packet::free(p.pkt);
02463 p.pkt = 0;
02464 return;
02465 }
02466 }
02467
02468 trace("SFErr %.5f _%s_ %d -> %d : %d",
02469 Scheduler::instance().clock(), net_id.dump(), p.src.addr, p.dest.addr,
02470 flowid);
02471
02472 srh->route_reply() = 0;
02473 srh->route_request() = 0;
02474 srh->flow_header() = 0;
02475 srh->flow_timeout() = 0;
02476
02477
02478 iph->daddr() = Address::instance().create_ipaddr(p.src.getNSAddr_t(),RT_PORT);
02479 iph->dport() = RT_PORT;
02480
02481 iph->saddr() = Address::instance().create_ipaddr(net_id.getNSAddr_t(),RT_PORT);
02482 iph->sport() = RT_PORT;
02483 iph->ttl() = 255;
02484
02485
02486 fe->flow_src = p.src.getNSAddr_t();
02487
02488 fe->flow_dst = p.dest.getNSAddr_t();
02489 fe->flow_id = flowid;
02490
02491
02492
02493 p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
02494 p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
02495
02496
02497 cmh->ptype() = PT_DSR;
02498 cmh->size() = IP_HDR_LEN;
02499 cmh->num_forwards() = 0;
02500
02501 cmh->uid() = uidcnt_++;
02502
02503 handlePktWithoutSR(p, false);
02504 assert(p.pkt == 0);
02505 }
02506
02507 void
02508 DSRAgent::xmitFlowFailed(Packet *pkt, const char* reason)
02509 {
02510 hdr_sr *srh = hdr_sr::access(pkt);
02511 hdr_ip *iph = hdr_ip::access(pkt);
02512 hdr_cmn *cmh = hdr_cmn::access(pkt);
02513 int flowidx = flow_table.find(iph->saddr(), iph->daddr(), srh->flow_id());
02514 u_int16_t default_flow;
02515
02516 assert(!srh->num_addrs());
02517
02518 if (!srh->flow_header()) {
02519 if (!flow_table.defaultFlow(iph->saddr(), iph->daddr(), default_flow)) {
02520 SRPacket p(pkt, srh);
02521
02522
02523 p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
02524 p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
02525
02526
02527 sendUnknownFlow(p, true);
02528 return;
02529 }
02530 flowidx = flow_table.find(iph->saddr(), iph->daddr(), default_flow);
02531 }
02532
02533 if (flowidx == -1 ||
02534 flow_table[flowidx].timeout < Scheduler::instance().clock()) {
02535
02536 SRPacket p(pkt, srh);
02537
02538
02539 p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);
02540 p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);
02541
02542
02543 return;
02544 }
02545
02546 cmh->size() -= srh->size();
02547 assert(cmh->size() >= 0);
02548
02549 flow_table[flowidx].sourceRoute.fillSR(srh);
02550 srh->cur_addr() = flow_table[flowidx].hopCount;
02551 assert(srh->addrs()[srh->cur_addr()].addr == (nsaddr_t) net_id.addr);
02552 cmh->size() += srh->size();
02553
02554
02555 srh->cur_addr()++;
02556 xmitFailed(pkt, reason);
02557 }
02558
02559 void
02560 DSRAgent::xmitFailed(Packet *pkt, const char* reason)
02561
02562
02563
02564
02565 {
02566 hdr_sr *srh = hdr_sr::access(pkt);
02567 hdr_ip *iph = hdr_ip::access(pkt);
02568 hdr_cmn *cmh = hdr_cmn::access(pkt);
02569
02570 assert(cmh->size() >= 0);
02571
02572 srh->cur_addr() -= 1;
02573
02574 if (srh->cur_addr() >= srh->num_addrs() - 1)
02575 {
02576 trace("SDFU: route error beyond end of source route????");
02577 fprintf(stderr,"SDFU: route error beyond end of source route????\n");
02578 Packet::free(pkt);
02579 return;
02580 }
02581
02582 if (srh->route_request())
02583 {
02584 trace("SDFU: route error forwarding route request????");
02585 fprintf(stderr,"SDFU: route error forwarding route request????\n");
02586 Packet::free(pkt);
02587 return;
02588 }
02589
02590
02591 ID tell_id(srh->addrs()[0].addr,
02592 (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
02593 ID from_id(srh->addrs()[srh->cur_addr()].addr,
02594 (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
02595 ID to_id(srh->addrs()[srh->cur_addr()+1].addr,
02596 (ID_Type) srh->addrs()[srh->cur_addr()].addr_type);
02597 assert(from_id == net_id || from_id == MAC_id);
02598
02599 trace("SSendFailure %.9f _%s_ %d %d %d:%d %d:%d %s->%s %d %d %d %d %s",
02600 Scheduler::instance().clock(), net_id.dump(),
02601 cmh->uid(), cmh->ptype(),
02602 iph->saddr(), iph->sport(),
02603 iph->daddr(), iph->dport(),
02604 from_id.dump(),to_id.dump(),
02605 God::instance()->hops(from_id.getNSAddr_t(), to_id.getNSAddr_t()),
02606 God::instance()->hops(iph->saddr(),iph->daddr()),
02607 God::instance()->hops(from_id.getNSAddr_t(), iph->daddr()),
02608 srh->num_addrs(), srh->dump());
02609
02610 #ifdef USE_GOD_FEEDBACK
02611 if (God::instance()->hops(from_id.getNSAddr_t(), to_id.getNSAddr_t()) == 1)
02612 {
02613 linkerr_is_wrong++;
02614 trace("SxmitFailed %.5f _%s_ %d->%d god okays #%d",
02615 Scheduler::instance().clock(), net_id.dump(),
02616 from_id.getNSAddr_t(), to_id.getNSAddr_t(), linkerr_is_wrong);
02617 fprintf(stderr,
02618 "xmitFailed on link %d->%d god okays - ignoring & recycling #%d\n",
02619 from_id.getNSAddr_t(), to_id.getNSAddr_t(), linkerr_is_wrong);
02620
02621 srh->cur_addr() += 1;
02622
02623
02624 cmh->direction() = hdr_cmn::DOWN;
02625 ll->recv(pkt, (Handler*) 0);
02626 return;
02627 }
02628 #endif
02629
02630 if(strcmp(reason, "DROP_IFQ_QFULL") != 0) {
02631 assert(strcmp(reason, "DROP_RTR_MAC_CALLBACK") == 0);
02632
02633
02634 route_cache->noticeDeadLink(from_id, to_id,
02635 Scheduler::instance().clock());
02636 flow_table.noticeDeadLink(from_id, to_id);
02637
02638
02639 undeliverablePkt(pkt->copy(), 1);
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650 {
02651 Packet *r, *nr, *queue1 = 0, *queue2 = 0;
02652
02653
02654 while((r = ifq->prq_get_nexthop(to_id.getNSAddr_t()))) {
02655 r->next_ = queue1;
02656 queue1 = r;
02657 }
02658
02659
02660
02661 for(r = queue1; r; r = nr) {
02662 nr = r->next_;
02663 r->next_ = queue2;
02664 queue2 = r;
02665 }
02666
02667
02668 for(r = queue2; r; r = nr) {
02669 nr = r->next_;
02670 undeliverablePkt(r, 1);
02671 }
02672 }
02673 }
02674
02675
02676 if (tell_id == net_id || tell_id == MAC_id)
02677 {
02678 if (verbose)
02679 trace("Sdebug _%s_ not bothering to send route error to ourselves",
02680 tell_id.dump());
02681 Packet::free(pkt);
02682 pkt = 0;
02683 return;
02684 }
02685
02686 if (srh->num_route_errors() >= MAX_ROUTE_ERRORS)
02687 {
02688
02689
02690
02691
02692 trace("SDFU %.5f _%s_ dumping maximally nested error %s %d -> %d",
02693 Scheduler::instance().clock(), net_id.dump(),
02694 tell_id.dump(),
02695 from_id.dump(),
02696 to_id.dump());
02697 Packet::free(pkt);
02698 pkt = 0;
02699 return;
02700 }
02701
02702 link_down *deadlink = &(srh->down_links()[srh->num_route_errors()]);
02703 deadlink->addr_type = srh->addrs()[srh->cur_addr()].addr_type;
02704 deadlink->from_addr = srh->addrs()[srh->cur_addr()].addr;
02705 deadlink->to_addr = srh->addrs()[srh->cur_addr()+1].addr;
02706 deadlink->tell_addr = srh->addrs()[0].addr;
02707 srh->num_route_errors() += 1;
02708
02709 if (verbose)
02710 trace("Sdebug %.5f _%s_ sending into dead-link (nest %d) tell %d %d -> %d",
02711 Scheduler::instance().clock(), net_id.dump(),
02712 srh->num_route_errors(),
02713 deadlink->tell_addr,
02714 deadlink->from_addr,
02715 deadlink->to_addr);
02716
02717 srh->route_error() = 1;
02718 srh->route_reply() = 0;
02719 srh->route_request() = 0;
02720 srh->flow_header() = 0;
02721 srh->flow_timeout() = 0;
02722
02723
02724 iph->daddr() = Address::instance().create_ipaddr(deadlink->tell_addr,RT_PORT);
02725 iph->dport() = RT_PORT;
02726
02727 iph->saddr() = Address::instance().create_ipaddr(net_id.addr,RT_PORT);
02728 iph->sport() = RT_PORT;
02729 iph->ttl() = 255;
02730
02731 cmh->ptype() = PT_DSR;
02732 cmh->size() = IP_HDR_LEN;
02733 cmh->num_forwards() = 0;
02734
02735 cmh->uid() = uidcnt_++;
02736
02737 SRPacket p(pkt, srh);
02738 p.route.setLength(p.route.index()+1);
02739 p.route.reverseInPlace();
02740 p.dest = tell_id;
02741 p.src = net_id;
02742
02743
02744 sendOutPacketWithRoute(p, true);
02745 }
02746
02747 void
02748 XmitFailureCallback(Packet *pkt, void *data)
02749 {
02750 DSRAgent *agent = (DSRAgent *)data;
02751 agent->xmitFailed(pkt);
02752 }
02753
02754 void
02755 XmitFlowFailureCallback(Packet *pkt, void *data)
02756 {
02757 DSRAgent *agent = (DSRAgent *)data;
02758 agent->xmitFlowFailed(pkt);
02759 }
02760
02761 #if 0
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782 struct RtHoldoffData: public EventData {
02783 RtHoldoffData(DSRAgent *th, Packet *pa, int ind):t(th), p(pa), index(ind)
02784 {}
02785 DSRAgent *t;
02786 Packet *p;
02787 int index;
02788 };
02789
02790 void
02791 RouteReplyHoldoffCallback(Node *node, Time time, EventData *data)
02792
02793
02794 {
02795 Packet *p = ((RtHoldoffData *)data)->p;
02796 DSRAgent *t = ((RtHoldoffData *)data)->t;
02797 int index = ((RtHoldoffData *)data)->index;
02798
02799 RtRepHoldoff *entry = &(t->rtrep_holdoff[index]);
02800 assert((entry->requestor == p->dest));
02801
02802
02803
02804 if ((lsnode_require_use && entry->best_length != -1)
02805 || (!lsnode_require_use && entry->best_length > entry->our_length))
02806 {
02807 world_statistics.sendingSrcRtFromCache(t,time,p);
02808 t->sendPacket(t,time,p);
02809 }
02810 else
02811 {
02812 delete p;
02813 }
02814 entry->requestor = invalid_addr;
02815 entry->requested_dest = invalid_addr;
02816 delete data;
02817 t->num_heldoff_rt_replies--;
02818 }
02819
02820 void
02821 DSRAgent::scheduleRouteReply(Time t, Packet *new_p)
02822
02823
02824 {
02825 for (int c = 0; c < RTREP_HOLDOFF_SIZE; c ++)
02826 if (rtrep_holdoff[c].requested_dest == invalid_addr) break;
02827 assert(c < RTREP_HOLDOFF_SIZE);
02828
02829 Path *our_route = &(new_p->data.getRoute().source_route);
02830 rtrep_holdoff[c].requested_dest = (*our_route)[our_route->length() - 1];
02831 rtrep_holdoff[c].requestor = new_p->dest;
02832 rtrep_holdoff[c].best_length = MAX_ROUTE_LEN + 1;
02833 rtrep_holdoff[c].our_length = our_route->length();
02834
02835 Time send_time = t +
02836 (Time) (our_route->length() - 1) * rt_rep_holdoff_period
02837 + U(0.0, rt_rep_holdoff_period);
02838 RegisterCallback(this,&RouteReplyHoldoffCallback, send_time,
02839 new RtHoldoffData(this,new_p,c));
02840 num_heldoff_rt_replies++;
02841 }
02842
02843 void
02844 DSRAgent::snoopForRouteReplies(Time t, Packet *p)
02845
02846
02847 {
02848 for (int c = 0 ; c <RTREP_HOLDOFF_SIZE ; c ++)
02849 {
02850 RtRepHoldoff *entry = &(rtrep_holdoff[c]);
02851
02852
02853
02854
02855 if (entry->requestor == p->dest
02856 && (p->type == ::route_reply || p->data.sourceRoutep()))
02857 {
02858 Path *srcrt = &(p->data.getRoute().source_route);
02859 if (!(entry->requested_dest == (*srcrt)[srcrt->length()-1]))
02860 continue;
02861 if (entry->best_length > srcrt->length())
02862 entry->best_length = srcrt->length();
02863 }
02864 else if (entry->requestor == p->src
02865 && entry->requested_dest == p->dest)
02866 {
02867 if (p->route.length() <= entry->our_length)
02868 {
02869 entry->best_length = -1;
02870 }
02871 }
02872 else
02873 continue;
02874 }
02875 }
02876
02877 #endif //0
02878
02879
02880
02881
02882
02883
02884
02885