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

📄 dsredq.cc.svn-base

📁 diff serve for ns-2, work for version 2.29
💻 SVN-BASE
字号:
/* Copyright (C) 2001-2006  Sergio Andreozzi * * This file is part of DiffServ4NS, a set of improvements to * the Network Simulator 2 for DiffServ simulations. * * Project Homepage: http://diffserv4ns.sourceforge.net/ * * DiffServ4NS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * DiffServ4NS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with DiffServ4NS; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA * GNU License: http://www.gnu.org/licenses/gpl.txt *  * The above copyright applies to the following changes and additions to the official * NS2 (http://nsnam.cvs.sourceforge.net/nsnam/ns-2/): * *  - marking: possibility to define mark rules based on source node,  *             destination node, transport protocol type and application type *  - new schedulers: WFQ, WF2Q+, SCFQ, SFQ, LLQ *  - new policy: possibility to define a DSCP based rate limiter *  - new monitoring possibilities: *     - For UDP-based traffic *        + Average, instantaneous, minimum and frequency distributed OWD *        + Average, instantaneous, minimum and frequency distributed IPDV *     - For TCP-based traffic *        + TCP Goodput on a DSCP basis *        + TCP Round-Trip Time on a DSCP basis, both instantaneous value  *          and frequency distribution *        + TCP Window Size on a DSCP basis, both instantaneous value  *          and frequency distribution *     - per-hop parameters: *        + Instantaneous and average queue length on a queue basis  *          or on a queue and drop precedence level basis *        + Maximum burstiness for queue 0 *        + Departure rate on a queue basis or on a queue and drop level  *          precedence basis *        + Received packets, transmitted packets, dropped packets due to droppers  *          and dropped packets due to buffer overflow,  *          all on a DSCP basis and for both absolute and percentage values * ***************************************************************************************  *//* * 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 "random.h"#include "dsredq.h"/*------------------------------------------------------------------------------redQueue() Constructor.     Initializes virtual queue parameters.------------------------------------------------------------------------------*/redQueue::redQueue() {	numPrec = MAX_PREC;	qlen=0;	qMaxBur=0;	mredMode = rio_c;	//underlying physical queue	q_ = new PacketQueue();	}/*------------------------------------------------------------------------------void config(int prec, const char*const* argv)    Configures a virtual queue according to values supplied by the user.------------------------------------------------------------------------------*/void redQueue::config(int prec, int argc, const char*const* argv) {	if ( mredMode == dropTail ) {		qParam_[prec].edp_.th_min =  (int)strtol(argv[4], NULL, 10);		return;	}//	qParam_[prec].qlen = 0;        if (argc > 4) {		qParam_[prec].edp_.th_min = (int)strtod(argv[4], NULL);		qParam_[prec].edp_.th_max = (int)strtod(argv[5], NULL);		qParam_[prec].edp_.max_p_inv = 1.0 / atof(argv[6]);        }	qParam_[prec].edp_.q_w = 0.002;  //      double init_v_ave = 0.0;//	qParam_[prec].edv_.v_ave = init_v_ave;//	qParam_[prec].idle_ = 1;	if (&Scheduler::instance() != NULL)		qParam_[prec].idletime_ = Scheduler::instance().clock();	else		qParam_[prec].idletime_ = 0.0;}/*------------------------------------------------------------------------------void initREDStateVar(void)    Initializes each virtual queue in one physical queue.------------------------------------------------------------------------------*/void redQueue::initREDStateVar(void) {	for (int i = 0; i < numPrec; i++) {		qParam_[i].idle_ = 1;		if (&Scheduler::instance() != NULL)			qParam_[i].idletime_ = Scheduler::instance().clock();		else			qParam_[i].idletime_ = 0.0;	}}/*------------------------------------------------------------------------------void updateREDStateVar(int prec)    Updates a virtual queue's state variables after dequing.------------------------------------------------------------------------------*/void redQueue::updateREDStateVar(int prec) {   int idle = 1;   int i;   double now = Scheduler::instance().clock();   qParam_[prec].qlen--;		// decrement virtual queue length			   if (qParam_[prec].qlen == 0)   {      if (mredMode == rio_c) {         for(i=0; i<prec; i++) if (qParam_[i].qlen != 0) idle = 0;         if (idle) {            for (i=prec;i<numPrec;i++) {               if (qParam_[i].qlen == 0) {                  qParam_[i].idle_ = 1;                  qParam_[i].idletime_ = now;               } else break;            }			         }      } else if (mredMode == rio_d) {         qParam_[prec].idle_ = 1;         qParam_[prec].idletime_ = now;      } else if (mredMode == wred) { //wred         qParam_[0].idle_ = 1;         qParam_[0].idletime_ = now;      }			   }}/*------------------------------------------------------------------------------void enque(Packet *pkt, int prec, int ecn)    Enques a packet associated with one of the precedence levels of thephysical queue.------------------------------------------------------------------------------*/int redQueue::enque(Packet *pkt, int prec, int ecn) {   int m = 0;   double now, u;	double pa,pb;   if ((mredMode == dropTail)&&(qParam_[prec].edp_.th_min==-1))  // to avoid in some case to get PKT_DROPPED		return PKT_EDROPPED;  				 // it would be meaningless!											   if (q_->length() > (qlim-1)) return PKT_DROPPED;   now = Scheduler::instance().clock();   //now determining the avg for that queue	if (mredMode == dropTail) {		//printf("prec: %d limit: %d\n",prec,qParam_[prec].edp_.th_min);		//if (qParam_[prec].edp_.th_min==-1) return PKT_EDROPPED;		if (q_->length() >= qParam_[0].edp_.th_min) {			return PKT_EDROPPED;		} else {		   q_->enque(pkt);	      	   qlen++; 		   qParam_[prec].qlen++;		   qMaxBur=(qMaxBur>qlen?qMaxBur:qlen);	      return PKT_ENQUEUED;				}	} else if (mredMode == rio_c) {      for (int i = prec; i < numPrec; i++) {	         m = 0;         if (qParam_[i].idle_) {            qParam_[i].idle_ = 0;            m = int(qParam_[i].edp_.ptc * (now - qParam_[i].idletime_));         }         calcAvg(i, m+1);      }   } else if (mredMode == rio_d) {      if (qParam_[prec].idle_) {         qParam_[prec].idle_ = 0;         m = int(qParam_[prec].edp_.ptc * (now - qParam_[prec].idletime_));      }	      calcAvg(prec, m+1);   } else { //wred      if (qParam_[0].idle_) {         qParam_[0].idle_ = 0;         m = int(qParam_[0].edp_.ptc * (now - qParam_[0].idletime_));      }	      calcAvg(0, m+1);   }   // enqueu packet if we are using ecn   if (ecn) {      q_->enque(pkt);	      qlen++;      qMaxBur=(qMaxBur>qlen?qMaxBur:qlen);      //virtually, this new packet is queued in one of the multiple queues,      //thus increasing the length of that virtual queue      qParam_[prec].qlen++;   }   //if the avg is greater than the min threshold,   //there can be only two cases.....   if (qParam_[prec].edv_.v_ave > qParam_[prec].edp_.th_min) {      //either the avg is less than the max threshold      if (qParam_[prec].edv_.v_ave <= qParam_[prec].edp_.th_max) {         //in which case determine the probabilty for dropping the packet,							qParam_[prec].edv_.count++;         qParam_[prec].edv_.v_prob = (1/qParam_[prec].edp_.max_p_inv) *                                     (qParam_[prec].edv_.v_ave-qParam_[prec].edp_.th_min) /                                     (qParam_[prec].edp_.th_max-qParam_[prec].edp_.th_min);         pb = qParam_[prec].edv_.v_prob;			pa = pb/(1.0 - qParam_[prec].edv_.count*pb);         //now determining whether to drop the packet or not         u = Random::uniform(0.0, 1.0);         //drop it			if (u <= pa) {	            if (ecn) return PKT_MARKED;            return PKT_EDROPPED;         }      } else { //if avg queue is greater than max. threshold			qParam_[prec].edv_.count = 0;         if (ecn) return PKT_MARKED;         		return PKT_EDROPPED;      }   }	qParam_[prec].edv_.count = -1;   // if ecn is on, then the packet has already been enqueued   if(ecn) return PKT_ENQUEUED;   //if the packet survives the above conditions it   //is finally queued in the underlying queue   q_->enque(pkt);   //virtually, this new packet is queued in one of the multiple queues,   //thus increasing the length of that virtual queue   qParam_[prec].qlen++;   qlen++;   qMaxBur=(qMaxBur>qlen?qMaxBur:qlen);   return PKT_ENQUEUED;}/*------------------------------------------------------------------------------]Packet* deque()    Deques a packet from the physical queue.------------------------------------------------------------------------------*/Packet* redQueue::deque() {	qlen--;	return(q_->deque());}/*------------------------------------------------------------------------------void calcAvg(int prec, int m)    This method calculates avg queue length, given the prec number, m (a valueused to adjust the queue size appropriately during idle times).    If mredMode is rio_c, each virtual queue size is calculatedindependently.  If it is true, the calculated size of queue n includes the sizesof all virtual queues up to and including n.------------------------------------------------------------------------------*/void redQueue::calcAvg(int prec, int m) {	float f;	int i;	f = qParam_[prec].edv_.v_ave;	while (--m >= 1) {		f *= 1.0 - qParam_[prec].edp_.q_w;	}	f *= 1.0 - qParam_[prec].edp_.q_w;	if (mredMode == rio_c)		for (i = 0; i <= prec; i ++)			f += qParam_[i].edp_.q_w * qParam_[i].qlen;	else if (mredMode == rio_d)		f += qParam_[prec].edp_.q_w * qParam_[prec].qlen;   else //wred      f += qParam_[prec].edp_.q_w * q_->length();		   if (mredMode == wred)      for (i = 0; i < numPrec; i ++)			qParam_[i].edv_.v_ave = f;   else //rio_c, rio_d      qParam_[prec].edv_.v_ave = f;}/*------------------------------------------------------------------------------double getWeightedLength()    Returns the weighted RED queue length for the entire physical queue, inpackets.------------------------------------------------------------------------------*/double redQueue::getWeightedLength() {	double sum = 0.0;	if (mredMode == rio_c)		return qParam_[numPrec-1].edv_.v_ave;	else {		for (int prec = 0; prec < numPrec; prec++)			sum += qParam_[prec].edv_.v_ave;		return(sum);	}}/*------------------------------------------------------------------------------int getRealLength(void)    Returns the length of the physical queue, in packets.------------------------------------------------------------------------------*/int redQueue::getRealLength(void) {	return(q_->length());}/* only for debugging*/void redQueue::getPTC() {	printf("PTC %f\n",qParam_[0].edp_.ptc);	printf("PTC %f\n",qParam_[1].edp_.ptc);	printf("PTC %f\n",qParam_[2].edp_.ptc);}/*------------------------------------------------------------------------------void setPTC(int outLinkBW)    Sets the packet time constant, given the outgoing link bandwidth from therouter.------------------------------------------------------------------------------*/void redQueue::setPTC(double outLinkBW) {	for (int i = 0; i < MAX_PREC; i++)	{	qParam_[i].edp_.ptc = outLinkBW/(8.0*qParam_[i].edp_.mean_pktsize);		//printf("PTC per %d = %f\n",i,qParam_[i].edp_.ptc);}}/*------------------------------------------------------------------------------void setMPS(int mps)    Sets the mean packet size for each of the virtual queues.------------------------------------------------------------------------------*/void redQueue::setMPS(int mps) {	for (int i = 0; i < MAX_PREC; i++)		qParam_[i].edp_.mean_pktsize = mps;}

⌨️ 快捷键说明

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