📄 insignia.cc
字号:
/* * File : C++ code for a INSIGNIA in NS-2 * * Author : Gahng-Seop Ahn (ahngang@comet.columbia.edu), * INSIGNIA Project (insignia@comet.columbia.edu) * * Modified : May 9, 2000 * */#include "insignia.h"static class InsigniaHeaderClass : public PacketHeaderClass {public: InsigniaHeaderClass() : PacketHeaderClass("PacketHeader/INSIGNIA", sizeof(hdr_insignia)) {}} class_insignia_hdr;static class InsigniaClass : public TclClass {public: InsigniaClass() : TclClass("Agent/INSIGNIA") {} TclObject* create(int, const char*const*) { return (new INSIGNIA()); }} class_insignia;INSIGNIA::INSIGNIA() : Agent(PT_INSIGNIA){ bind("off_ip_", &off_ip_); bind("off_cmn_", &off_cmn_); bind("off_insignia_", &off_insignia_); bind("off_mac_", &off_mac_); tap_ = 0; fp = 0; rsv_tail = 0; bwm_tail = 0; neighbor_bw = 0; for (int i = 0; i < 10; i++) { port[i] = 0;}}intINSIGNIA::command(int argc, const char*const* argv){ TclObject *obj; if (argc == 2) { if (strcasecmp (argv[1], "reset") == 0) { terminate(); return Agent::command(argc, argv); } } if (argc == 3) { if (strcasecmp (argv[1], "ip-addr") == 0) { net_id = atoi(argv[2]); return TCL_OK; } if (strcasecmp (argv[1], "mac-addr") == 0) { mac_id = atoi(argv[2]); return TCL_OK; } if (strcasecmp (argv[1], "ins_sum") == 0) { ins_sum = strcmp(argv[2], "OFF"); return TCL_OK; } if (strcasecmp (argv[1], "ins_tr") == 0) { ins_tr = strcmp(argv[2], "OFF"); return TCL_OK; } if (strcasecmp (argv[1], "ins_dir") == 0) { strcpy(ins_dir, argv[2]); return TCL_OK; } if ( (obj = TclObject::lookup(argv[2])) == 0) { printf("INSIGNIA: %s lookup of %s failed\n", argv[1], argv[2]); return TCL_ERROR; } if (strcasecmp (argv[1], "target") == 0) { target_ = (NsObject *) obj; return TCL_OK; } if (strcasecmp (argv[1], "install-tap-dsr") == 0) { tap_ = (DSRAgent *) obj; return TCL_OK; } if (strcasecmp (argv[1], "install-tap") == 0) { Mac *m = (Mac*) obj; m->installTap(this); return TCL_OK; } if (strcasecmp (argv[1], "queue") == 0) { ifq = (PriQueue *) obj; return TCL_OK; } } if (argc == 9) { if (strcasecmp (argv[1], "flow_spec") == 0) { int i = atoi(argv[2]); port[i] = (flowspec *) malloc(sizeof(flowspec)); port[i]->bqos = atoi(argv[5]); port[i]->eqos = atoi(argv[6]); port[i]->granulity = atoi(argv[7]); port[i]->adpt_pr = atoi(argv[8]); if (port[i]->bqos + port[i]->eqos) { port[i]->min_bw = (u_short) (atof(argv[3]) * 8 / atof(argv[4]) * atof(argv[5]) / (atof(argv[5]) + atof(argv[6])) / 4000); port[i]->max_bw = (u_short) (atof(argv[3]) * 8 / atof(argv[4]) / 4000); } else { port[i]->min_bw = 0; port[i]->max_bw = 0; } port[i]->payload1 = 0; port[i]->payload2 = 0; port[i]->src_ = 0; port[i]->s_bqres = 0; port[i]->s_bqbe = 0; port[i]->s_eqres = 0; port[i]->s_eqbe = 0; port[i]->r_bqres = 0; port[i]->r_bqbe = 0; port[i]->r_eqres = 0; port[i]->r_eqbe = 0; port[i]->delay = 0; port[i]->res_delay = 0; port[i]->be_delay = 0; port[i]->mindelay = 100; port[i]->res_mindelay = 100; port[i]->be_mindelay = 100; port[i]->maxdelay = 0; port[i]->res_maxdelay = 0; port[i]->be_maxdelay = 0; return TCL_OK; } } return Agent::command(argc, argv);}voidINSIGNIA::terminate(){ if (fp && ins_sum) { for (int i = 0; i < 10; i++) { if (port[i] && port[i]->src_) fprint_sum(i); } } if (fp && fclose(fp) == EOF) printf("Error closing %s/node%d", ins_dir, net_id);}voidINSIGNIA::recv(Packet* pkt, Handler* h){ hdr_cmn* cmnh = (hdr_cmn*)pkt->access(off_cmn_); hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_); ctime = Scheduler::instance().clock(); if (!fp && (ins_sum || ins_tr)) { char fname[64]; if (net_id < 10) sprintf(fname, "%s/node0%d", ins_dir, net_id); else sprintf(fname, "%s/node%d", ins_dir, net_id); if ((fp = fopen(fname, "w+")) == 0) { printf("Error opening %s\n", fname); } } if (DATA_PACKET(cmnh->ptype())) { /* recv QOS report */ if (iph->tos_ == RPT && iph->dst_ == net_id) { recv_QOSreport(pkt); Packet::free(pkt); return; } /* insignia src */ if (iph->src_ == net_id) { insigniaSRC(pkt); measureSRC(pkt); } /* insignia dst */ else if (iph->dst_ == net_id) { measureDST(pkt); insigniaDST(pkt, h); } /* insignia hop */ else insigniaHOP(pkt); } target_->recv(pkt, h);}voidINSIGNIA::tap(const Packet *pkt){ hdr_insignia* insh = (hdr_insignia*)((Packet*)pkt)->access(off_insignia_); ctime = Scheduler::instance().clock(); if (insh->srv_mode == RES) local_bw_monitor((Packet*)pkt); if (tap_) tap_->tap(pkt);}/*=========================================================================== insignia handlers---------------------------------------------------------------------------*/voidINSIGNIA::insigniaSRC(Packet *pkt){ hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_); hdr_insignia* insh = (hdr_insignia*)pkt->access(off_insignia_); rsvcache *rsv_cache; /* fill in insignia fields */ insh->min_bw = port[iph->sport()]->min_bw; insh->max_bw = port[iph->sport()]->max_bw; insh->bw_ind = port[iph->sport()]->max_bw; insh->src_time = ctime; if (insh->min_bw + insh->max_bw == 0) return; rsv_cache = lookup_rsvcache(pkt); if (rsv_cache) { if (rsv_cache->backoff) { if (rsv_cache->backoff == 1) { fprint_pkt(pkt); fprintf(fp, "backoff for %d sec", BACKOFF); rsv_cache->backoff = 2; } return; } adaptation(pkt, rsv_cache); if (insh->srv_mode == RES); { if (rsv_cache->msg_type == RU) { rsv_cache->msg_type = BM; insh->msg_type = RU; insh->bw_ind = rsv_cache->bw_ind; } else { insh->msg_type = BM; if (insh->bw_ind > INS_BW - this_bw - neighbor_bw) insh->bw_ind = INS_BW - this_bw - neighbor_bw; } } } else { rsv_cache = admt_ctrl(pkt, rsv_cache); adaptation(pkt, rsv_cache); if (insh->srv_mode == RES) { insh->msg_type = RU; rsv_cache->msg_type = BM; insh->bw_ind = rsv_cache->bw_ind; } }}voidINSIGNIA::insigniaDST(Packet *pkt, Handler *h){ hdr_insignia* insh = (hdr_insignia*)pkt->access(off_insignia_); rsvcache *rsv_cache; if (insh->srv_mode == BE) return; rsv_cache = lookup_rsvcache(pkt); if (rsv_cache) { if (insh->msg_type == RU) { rsv_cache = admt_ctrl(pkt, rsv_cache); } else { rsv_cache->bw_mon = (rsv_cache->bw_mon + insh->bw_ind) / 2; if (ctime >rsv_cache->etime + RPT_PRD) { insh->bw_ind = rsv_cache->bw_mon; insh->max_bw = rsv_cache->rpt_seq; rsv_cache->rpt_seq += 1; rsv_cache->etime = ctime; send_QOSreport(pkt, h); } } } else { rsv_cache = admt_ctrl(pkt, rsv_cache); insh->bw_ind = rsv_cache->bw_ind; insh->max_bw = rsv_cache->rpt_seq; rsv_cache->rpt_seq += 1; rsv_cache->etime = ctime; send_QOSreport(pkt, h); }}voidINSIGNIA::insigniaHOP(Packet *pkt){ hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_); hdr_insignia* insh = (hdr_insignia*)pkt->access(off_insignia_); rsvcache *rsv_cache; if (insh->srv_mode == BE) return; rsv_cache = lookup_rsvcache(pkt); if (rsv_cache) { if (insh->msg_type == RU) { rsv_cache = admt_ctrl(pkt, rsv_cache); } else { if (insh->bw_ind > INS_BW - this_bw - neighbor_bw) insh->bw_ind = INS_BW - this_bw - neighbor_bw; } } else { insh->msg_type = RU; rsv_cache = admt_ctrl(pkt, rsv_cache); if (!rsv_cache) { insh->srv_mode = BE; iph->tos_ = BE; } }}voidINSIGNIA::adaptation(Packet *pkt, rsvcache *rsv_cache){ hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_); hdr_insignia* insh = (hdr_insignia*)pkt->access(off_insignia_); u_short i = iph->sport(); /* decide BQ or EQ. Change in turn with ratio bqos:eqos */ if (port[i]->payload1 < port[i]->bqos) { insh->pl_ind = BQ; port[i]->payload1 += 1; } else { insh->pl_ind = EQ; port[i]->payload1 += 1; port[i]->payload2 += 1; if (port[i]->payload1 >= port[i]->bqos + port[i]->eqos) port[i]->payload1 = 0; if (port[i]->payload2 >= port[i]->granulity) port[i]->payload2 = 0; } if (rsv_cache) { /* insignia bandwidth adaptation */ float numerator = (float) ((rsv_cache->bw_ind - port[i]->min_bw) * port[i]->granulity); float denominator = (float) (port[i]->max_bw - port[i]->min_bw); u_short step = (u_short) (numerator / denominator); rsv_cache->bw_ind = (u_short) (denominator * step / port[i]->granulity + port[i]->min_bw); /* decide RES or BE */ if (insh->pl_ind == BQ) { insh->srv_mode = RES; iph->tos_ = RES; } else { if (step >= port[i]->payload2 + 1) { insh->srv_mode = RES; iph->tos_ = RES; } else { insh->srv_mode = BE; iph->tos_ = BE; } } } else { insh->srv_mode = BE; iph->tos_ = BE; }}rsvcache *INSIGNIA::admt_ctrl(Packet *pkt, rsvcache *rsv_cache){ hdr_ip* iph = (hdr_ip*)pkt->access(off_ip_); hdr_insignia* insh = (hdr_insignia*)pkt->access(off_insignia_); int ins_bw = INS_BW - this_bw - neighbor_bw; if (ins_bw < 0) ins_bw = 0; /* admission control */ if (net_id == iph->dst_) {} // admitted without admt_ctrl else if (ifq->prq_class_length(IFQ_REALTIME) > IFQ_MAXLEN * 0.7 || ins_bw < insh->min_bw) // not admitted { if (ins_tr) { fprint_pkt(pkt); fprintf(fp, "%4dK Reject", ins_bw * 4); if (ifq->prq_class_length(IFQ_REALTIME) > IFQ_MAXLEN * 0.7) fprintf(fp, " ifq_Full"); } return NULL; } else if (ins_bw < insh->bw_ind) // admitted { insh->bw_ind = ins_bw; } if (ins_tr) { if (rsv_cache) { if (rsv_cache->bw_ind != insh->bw_ind) { fprint_pkt(pkt); fprintf(fp, "%4dK Update %3dK to %3dk", ins_bw * 4, rsv_cache->bw_ind * 4, insh->bw_ind * 4); } } else { fprint_pkt(pkt); fprintf(fp, "%4dk Admit %3dk", ins_bw * 4, insh->bw_ind * 4); } } /* update rsv_cache */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -