⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsred.cc

📁 区分服务的路由算法
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2000 Nortel Networks * All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by Nortel Networks. * 4. The name of the Nortel Networks may not be used *    to endorse or promote products derived from this software without *    specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY NORTEL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL NORTEL OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Developed by: Farhan Shallwani, Jeremy Ethridge *               Peter Pieda, and Mandeep Baines * Maintainer: Peter Pieda <ppieda@nortelnetworks.com> */#include <stdio.h>#include "ip.h"#include "dsred.h"#include "delay.h"#include "random.h"#include "flags.h"#include "tcp.h"#include "dsredq.h"/*------------------------------------------------------------------------------dsREDClass declaration.     Links the new class in the TCL heirarchy.  See "Notes And Documentation for ns-2."------------------------------------------------------------------------------*/static class dsREDClass : public TclClass {public:	dsREDClass() : TclClass("Queue/dsRED") {}	TclObject* create(int, const char*const*) {		return (new dsREDQueue);	}} class_dsred;/*------------------------------------------------------------------------------dsREDQueue() Constructor.    Initializes the queue.  Note that the default value assigned to numQueues in tcl/lib/ns-default.tcl must be no greater than MAX_QUEUES (the physical queue array size).------------------------------------------------------------------------------*/dsREDQueue::dsREDQueue() : de_drop_(NULL), link_(NULL)   {	bind("numQueues_", &numQueues_);	bind_bool("ecn_", &ecn_);	int i;	numPrec = MAX_PREC;   schedMode = schedModeRR;    for(i=0;i<MAX_QUEUES;i++){	queueMaxRate[i] = 0;	queueWeight[i]=1;    }		    wfq_event = 0;    v_time = sum = 0;    last_vt_update = 0;    idle = 1;    queuesDone = MAX_QUEUES;    phbEntries = 0;		// Number of entries in PHB table    reset();}/*------------------------------------------------------------------------------void edrop(Packet* pkt)    This method is used so that flowmonitor can monitor early drops.------------------------------------------------------------------------------*/void dsREDQueue::reset() {	int i;	qToDq = 0;		// q to be dequed, initialized to 0	    for(i=0;i<MAX_QUEUES;i++){	queueAvgRate[i] = 0.0;	queueArrTime[i] = 0.0;	slicecount[i]=0;	pktcount[i]=0;	wirrTemp[i]=0;	wirrqDone[i]=0;	finish_t[i]=0.0;	B[i]=0;    }        stats.drops = 0;    stats.edrops = 0;    stats.pkts = 0;    for(i=0;i<MAX_CP;i++){	stats.drops_CP[i]=0;	stats.edrops_CP[i]=0;	stats.pkts_CP[i]=0;    }    for (i = 0; i < MAX_QUEUES; i++)	redq_[i].qlim = limit();	// Compute the "packet time constant" if we know the	// link bandwidth.  The ptc is the max number of (avg sized)	// pkts per second which can be placed on the link.	if (link_)	    for (int i = 0; i < MAX_QUEUES; i++)		redq_[i].setPTC(link_->bandwidth());		Queue::reset();}/*------------------------------------------------------------------------------void edrop(Packet* pkt)    This method is used so that flowmonitor can monitor early drops.------------------------------------------------------------------------------*/void dsREDQueue::edrop(Packet* p){	if (de_drop_ != 0){		de_drop_->recv(p);	}	else {		drop(p);	}}/*------------------------------------------------------------------------------void applyTSWMeter(Packet *pkt)Pre: policy's variables avgRate, arrivalTime, and winLen hold valid values; and  pkt points to a newly-arrived packet.Post: Adjusts policy's TSW state variables avgRate and arrivalTime (also called  tFront) according to the specified packet.Note: See the paper "Explicit Allocation of Best effor Delivery Service" (David  Clark and Wenjia Fang), Section 3.3, for a description of the TSW Tagger.------------------------------------------------------------------------------*/void dsREDQueue::applyTSWMeter(Packet *pkt) {	double now, bytesInTSW, newBytes;	hdr_cmn* hdr = hdr_cmn::access(pkt);	double winLen = 1.0;	bytesInTSW = queueAvgRate[qToDq] * winLen;	newBytes = bytesInTSW + (double) hdr->size();	now = Scheduler::instance().clock();	queueAvgRate[qToDq] = newBytes / (now - queueArrTime[qToDq] + winLen);	queueArrTime[qToDq] = now;	}/*------------------------------------------------------------------------------void enque(Packet* pkt)     The following method outlines the enquing mechanism for a Diffserv router.This method is not used by the inheriting classes; it only serves as an outline.------------------------------------------------------------------------------*/void dsREDQueue::enque(Packet* pkt) {   int codePt, queue, prec;   hdr_ip* iph = hdr_ip::access(pkt);   codePt = iph->prio();	//extracting the marking done by the edge router   int ecn = 0;   int enqueued;   static double lastu[2]={0,0};   double now;   //looking up queue and prec numbers for that codept   lookupPHBTable(codePt, &queue, &prec);	   // code added for ECN support   //hdr_flags* hf = (hdr_flags*)(pkt->access(off_flags_));   // Changed for the latest version instead of 2.1b6   hdr_flags* hf = hdr_flags::access(pkt);   // WFQ packet size   hdr_cmn *hdr = hdr_cmn::access(pkt);   int size = hdr->size();	now = Scheduler::instance().clock();      if (ecn_ && hf->ect()) ecn = 1;    stats.pkts_CP[codePt]++;    stats.pkts++;    enqueued=0;   switch(redq_[queue].enque(pkt, prec, ecn)) {      case PKT_ENQUEUED:          enqueued=1;         break;      case PKT_DROPPED:         stats.drops_CP[codePt]++;	 stats.drops++;         drop(pkt);         break;      case PKT_EDROPPED:	 stats.edrops_CP[codePt]++;	 stats.edrops++;         edrop(pkt);         break;      case PKT_MARKED:         hf->ce() = 1; 	// mark Congestion Experienced bit		          enqueued=1;         break;			      default:          printf("Error !!!\n", now);         break;   }   if( schedMode == schedModeWFQ && enqueued) {    // virtual time update    // formula 10 in "virtual time implementation" paragraph	if(idle) {		v_time=0;		last_vt_update=now;		idle=0;	} else {		v_time=v_time+(now-last_vt_update)/sum;		last_vt_update=now;	}    // finish time computation    // implements formula 11 	finish_t[queue] = (finish_t[queue] > v_time ? 			finish_t[queue]:v_time)			+(double)size/queueWeight[queue]/(link_->bandwidth()/8.0);    // 1/(link_->bandwidth()/8) - real processing time of entire packet    // update sum and B	if( (B[queue]++) ==0 )		sum=sum+queueWeight[queue];	if ( fabs(sum) < 1.0/1000.0 ) sum=0;    // insertion in both lists	PGPS_queueID_l.insert_order(queue,finish_t[queue],queue);	 GPS_queueID_l.insert_order(queue,finish_t[queue],queue);    // schedule next departure in the GPS reference system	if(wfq_event!=0) {		Scheduler::instance().cancel(wfq_event);		delete wfq_event;	} 	scheduleWFQ();   } }/*------------------------------------------------------------------------------Packet* deque()     This method implements the dequing mechanism for a Diffserv router.------------------------------------------------------------------------------*/Packet* dsREDQueue::deque() {    Packet *p;    int queue, prec;	// Select queue to deque in a round robin manner:	selectQueueToDeque();	// Dequeue a packet from the underlying queue:	p = redq_[qToDq].deque();	if (p != 0) {	    pktcount[qToDq]+=1;	    if (schedMode==schedModePRI && queueMaxRate[qToDq]) applyTSWMeter(p);      /* There was a packet to be dequed;         find the precedence level (or virtual queue)         to which this packet was attached:      */	    lookupPHBTable(getCodePt(p), &queue, &prec);      // update state variables for that "virtual" queue	    redq_[qToDq].updateREDStateVar(prec);	}	// Return the dequed packet:		return(p);}/*------------------------------------------------------------------------------int getCodePt(Packet *p)     This method, when given a packet, extracts the code point marking from its header.------------------------------------------------------------------------------*/int dsREDQueue::getCodePt(Packet *p) {	hdr_ip* iph = hdr_ip::access(p);	return(iph->prio());}/*------------------------------------------------------------------------------void selectQueueToDeque(void)     This method determines the next queue in line to be dequed.------------------------------------------------------------------------------*/void dsREDQueue::selectQueueToDeque() {   // If the queue to be dequed has no elements, look for the next queue in line:   int i = 0;    static int cnt=0;   if(schedMode==schedModeRR){		qToDq = ((qToDq + 1) % numQueues_);      while ((i < numQueues_) && (redq_[qToDq].getRealLength() == 0)) {			qToDq = ((qToDq + 1) % numQueues_);			         i++;      }   }   else if (schedMode==schedModeWRR) {      if(wirrTemp[qToDq]<=0){  	      qToDq = ((qToDq + 1) % numQueues_);     	   wirrTemp[qToDq] = queueWeight[qToDq] - 1;		} else {			wirrTemp[qToDq] = wirrTemp[qToDq] -1;		}			      while ((i < numQueues_) && (redq_[qToDq].getRealLength() == 0)) {			wirrTemp[qToDq] = 0;  	      qToDq = ((qToDq + 1) % numQueues_);     	   wirrTemp[qToDq] = queueWeight[qToDq] - 1;			i++;		}   }   else if (schedMode==schedModeWIRR) {      qToDq = ((qToDq + 1) % numQueues_);		while ((i<numQueues_) && ((redq_[qToDq].getRealLength()==0) || (wirrqDone[qToDq]))) {			if (!wirrqDone[qToDq]) {				queuesDone++;				wirrqDone[qToDq]=1;			}  	      qToDq = ((qToDq + 1) % numQueues_);			i++;		}      if (wirrTemp[qToDq] == 1) {  	       queuesDone +=1;          wirrqDone[qToDq]=1;      }  	   wirrTemp[qToDq]-=1;      if(queuesDone >= numQueues_) {          queuesDone = 0;          for(i=0;i<numQueues_;i++) {  	          wirrTemp[i] = queueWeight[i];     	       wirrqDone[i]=0;          }   	      }   }	else if (schedMode==schedModeWFQ) {	       qToDq = PGPS_queueID_l.get_data_min();	       PGPS_queueID_l.extract();	          }	else if (schedMode==schedModePRI) {		qToDq = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -