📄 cbrpagent.cc
字号:
/* cbrp.cc */extern "C" {#include <stdarg.h>#include <float.h>};#include "cbrpagent.h"#include "priqueue.h"#include <random.h>#include <cmu/cmu-trace.h>#include <cmu/marshall.h>#include <packet.h>#include <cmu/mac-802_11.h>#define CBRP_ALMOST_NOW 0.1 // jitter used for events that should be effectively // instantaneous but are jittered to prevent // synchronization#define CBRP_MIN_TUP_PERIOD 1.0 // minimum time between triggered updates#define CBRP_IP_DEF_TTL 32 // default TTTL#define MAX_LOCAL_REPAIR_TIMES 5static const int verbose_srr = 0;//the following codes are from DSR's implementation -JinyangTime cbrp_arp_timeout = 30.0e-3; // (sec) arp request timeoutTime cbrp_rt_rq_period = 0.5; // (sec) length of one backoff periodTime cbrp_rt_rq_max_period = 10.0; // (sec) maximum time between rt reqsTime cbrp_max_err_hold = 1.0; // (sec)/*************** selectors ******************/bool cbrp_shortening_route_if_possible = true;bool cbrp_local_repair = true;bool cbrp_snoop_forwarded_errors = true; //same as DSR's snoop error//with CBRP, you do get much benefit from snooping other nodes' source//routes as DSR, netherless, we include this for people to try out themselvesbool cbrp_snoop_source_routes = false;// should we only respond to the first route request we receive from a host?bool cbrp_reply_only_to_first_rtreq = false;// should we take the data from the last route error msg sent to us// and propagate it around on the next propagating route request we do?// this is aka grat route error propagation DSR uses this // to check invalid entries in route cache. As most of route replies in DSr// comes from route cache, keeping route cache as updated as possible is // crutial to DSR's performance. In CBRP, most route replies comes from //destination node itself and hence does not depend too much on route cache.bool cbrp_propagate_last_error = false;// Should CBRP save the packet if the Local Repair procedure fails?bool cbrp_salvage_with_cache = true;// should we listen to a promiscuous tap?// Unlike DSR, most of CBRP's RREP comes from destination node instead of// cache and hence doing eavesdropping does no significant improvements.bool cbrp_use_tap = false;// CBRP does not use cache to reply when progagating RREQ.bool cbrp_reply_from_cache_on_propagating = false;// Used only when a node is eavesdropping. bool cbrpagent_reply_from_cache_uninvited = false;// Returns a random number between 0 and max, from dmaltzstatic inline double jitter (double max, int be_random_){ return (be_random_ ? Random::uniform(max) : 0);}#ifdef CBRP_DEBUGstatic char*return_reply_path(Packet *p, int off_cbrp_){ hdr_cbrp *cbrph = (hdr_cbrp *)p->access(off_cbrp_); static char buf[100]; char *ptr = buf; char *rtn_buf = ptr; int len = cbrph->route_reply_len(); if (len== 0) { sprintf(rtn_buf,"[<empty path>]"); return rtn_buf; } *ptr++ = '['; for (int c = 0 ; c < len ; c ++) { ptr += sprintf(ptr,"%d ",cbrph->reply_addrs()[c].addr); } *ptr++ = ']'; *ptr++ = '\0'; return rtn_buf; }static char*return_RREQ_forward_nodes(Packet *p, int off_cbrp_){ hdr_cbrp *cbrph = (hdr_cbrp *)p->access(off_cbrp_); static char buf[100]; char *ptr = buf; char *rtn_buf = ptr; int len = cbrph->num_forwarders(); if (len== 0) { sprintf(rtn_buf,"[<empty forwarders>]"); return rtn_buf; } *ptr++ = '['; for (int c = 0 ; c < len ;c+=2) { ptr += sprintf(ptr,"%d(%d) ",cbrph->forwarders[c].which_head,cbrph->forwarders[c].which_gateway); } *ptr++ = ']'; *ptr++ = '\0'; return rtn_buf; }#endif //CBRP_DEBUG//the below two functions are from DSR's implementation -Jinyang :)void CBRP_Agent:: trace (char *fmt,...){ va_list ap; if (!logtarget) return; va_start (ap, fmt); vsprintf (logtarget->buffer (), fmt, ap); logtarget->dump (); va_end (ap);}void CBRP_Agent::tracepkt (Packet * p, double now, int me, const char *type){ char buf[1024]; unsigned char *walk = p->accessdata (); int ct = *(walk++); int seq, dst, met; snprintf (buf, 1024, "V%s %.5f _%d_ [%d]:", type, now, me, ct); while (ct--) { dst = *(walk++); met = *(walk++); seq = *(walk++); seq = seq << 8 | *(walk++); seq = seq << 8 | *(walk++); seq = seq << 8 | *(walk++); snprintf (buf, 1024, "%s (%d,%d,%d)", buf, dst, met, seq); } // Now do trigger handling. //trace("VTU %.5f %d", now, me); if (verbose_) trace ("%s", buf);}voidCBRP_Agent::recv(Packet * p, Handler *){ hdr_ip *iph = (hdr_ip *) p->access (off_ip_); hdr_cmn *cmh = (hdr_cmn *) p->access (off_cmn_); hdr_cbrp *cbrph = (hdr_cbrp*)p->access(off_cbrp_); /* * Must be a packet I'm originating... */ if(iph->src_ == myaddr_ && cmh->num_forwards() == 0) { iph->ttl_ = CBRP_IP_DEF_TTL; } /* * Packet I'm forwarding... */ else { /* * Check the TTL. If it is zero, then discard. */ if(--iph->ttl_ == 0) { drop(p, DROP_RTR_TTL); return; } } if ((iph->src_ != myaddr_) && (!cbrph->valid())) { // process a BROADCAST pkt.. ntable->processUpdate(p); } else { // process a CBRP source route pkt, RREP, RREQ, ERR pkt. forwardSRPacket(p); }}voidCBRP_Agent::tap(const Packet *packet)/* CBRP does not need promiscuous mode, this is just for interested party to test out The implementation is mostly taken from DSR -Jinyang*/{ hdr_cbrp *cbrph = (hdr_cbrp*) ((Packet *)packet)->access(off_cbrp_); hdr_ip *iph = (hdr_ip*)((Packet *)packet)->access(off_ip_); hdr_cmn *cmh = (hdr_cmn*)((Packet *)packet)->access(off_cmn_); if (!cbrp_use_tap) return; if (!cbrph->valid()) return; // can't do anything with it // don't trouble me with packets I'm about to receive anyway /* this change added 5/13/98 -dam */ ID next_hop(cbrph->addrs[cbrph->cur_addr()].addr, ::IP); if (next_hop == net_id || next_hop == MAC_id) return; CBRP_Packet p((Packet *) packet, cbrph); p.dest = ID(iph->dst(),::IP); p.src = ID(iph->src(),::IP); if (p.src == net_id) return; /* snoop on the errori */ if (cbrph->route_error()) { if (verbose_) trace("Sdebug _%s_ tap saw error %d", net_id.dump(), cmh->uid()); processBrokenRouteError(p); } if (cbrph->route_reply()) { Path reply_path(cbrph->reply_addrs(), cbrph->route_reply_len()); reply_path.reverseInPlace(); if(verbose_) trace("Sdebug _%s_ tap saw route reply %d %s", net_id.dump(), cmh->uid(), reply_path.dump()); route_cache->noticeRouteUsed(reply_path, Scheduler::instance().clock(), p.src); return; } if (cbrph->route_request() && ((unsigned long)iph->dst()) != IP_BROADCAST ) { if (cbrpagent_reply_from_cache_uninvited) { Packet *p_copy = p.pkt->copy(); p.pkt = p_copy; //this copying is because replyFromRouteCache will free the pkt which we dont want replyFromRouteCache(p); } }else if (cbrph->route_request() && ((unsigned long)iph->dst()) == IP_BROADCAST) { return; } // the logic is wrong for shortening rtreq's anyway, cur_addr always = 0 if (cbrp_snoop_source_routes) { if (verbose_) trace("Sdebug _%s_ tap saw route use %d %s", net_id.dump(), cmh->uid(), p.route.dump()); route_cache->noticeRouteUsed(p.route, Scheduler::instance().clock(), net_id); }}static class CBRPClass:public TclClass{ public: CBRPClass ():TclClass ("Agent/CBRP") { } TclObject *create (int, const char *const *) { return (new CBRP_Agent ()); }} class_cbrp;CBRP_Agent::CBRP_Agent (): Agent (PT_CBRP), ll_queue (0), myaddr_ (0), be_random_ (1), use_mac_ (0), verbose_ (1), trace_wst_ (0), send_buf_timer(this),request_table(128),route_cache(NULL) { ntable = new NeighborTable(this); route_cache = makeRouteCache(); route_request_num = 1; target_ = 0; logtarget = 0; bind("off_CBRP_", &off_cbrp_); bind("off_ll_", &off_ll_); bind("off_mac_", &off_mac_); bind("off_ip_", &off_ip_); route_error_held = false; bind ("use_mac_", &use_mac_); bind ("be_random_", &be_random_); bind ("verbose_", &verbose_); bind ("trace_wst_", &trace_wst_); bind ("no_of_clusters_", &no_of_clusters_); }voidCBRP_Agent::startUp(){ // kick off periodic advertisments ntable->startUp();}/* This command function is mainly taken from DSR implementation */int CBRP_Agent::command (int argc, const char *const *argv){ TclObject *obj; if (argc == 2) { if (strcmp (argv[1], "startcbrp") == 0) { startUp(); send_buf_timer.sched(BUFFER_CHECK + BUFFER_CHECK * Random::uniform(1.0)); return (TCL_OK); } else if (strcmp (argv[1], "testinit") == 0) { testinit(); return (TCL_OK); } else if (strcmp (argv[1], "reset") == 0) { Terminate(); return Agent::command(argc, argv); } else if (strcasecmp(argv[1], "check-cache") == 0) { return route_cache->command(argc, argv); } else if (strcasecmp (argv[1], "ll-queue") == 0) { if (!(ll_queue = (PriQueue *) TclObject::lookup (argv[2]))) { fprintf (stderr, "CBRP_Agent: ll-queue lookup of %s failed\n", argv[2]); return TCL_ERROR; } return TCL_OK; } } else if (argc == 3) { if (strcasecmp(argv[1], "ip-addr") == 0) { net_id = ID(atoi(argv[2]), ::IP); myaddr_ = net_id.addr; //myadd_ is the IP addr shortform route_cache->net_id = net_id; return TCL_OK; } else if(strcasecmp(argv[1], "mac-addr") == 0) { MAC_id = ID(atoi(argv[2]), ::MAC); route_cache->MAC_id = MAC_id; return TCL_OK; } if( (obj = TclObject::lookup(argv[2])) == 0) { fprintf(stderr, "CBRP_Agent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } if (strcasecmp (argv[1], "log-target") == 0) { logtarget = (Trace *)obj; return route_cache->command(argc, argv); } else if (strcasecmp(argv[1], "install-tap") == 0) { Mac *m = (Mac*) obj; m->installTap(this); return TCL_OK; } } else if (argc == 4) { if (strcasecmp(argv[1], "add-ll") == 0) { if( (obj = TclObject::lookup(argv[2])) == 0) { fprintf(stderr, "CBRP_Agent: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } ll = (NsObject*) obj; if( (obj = TclObject::lookup(argv[3])) == 0) { fprintf(stderr, "CBRP_Agent: %s lookup of %s failed\n", argv[1], argv[3]); return TCL_ERROR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -