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

📄 tfrc.cc

📁 Ns2 TCP 协议改进 版本 提高goodput
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1999  International Computer Science Institute * 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 ACIRI, the AT&T  *      Center for Internet Research at ICSI (the International Computer *      Science Institute). * 4. Neither the name of ACIRI nor of ICSI may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICSI 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 ICSI 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. */#include <stdlib.h>#include <sys/types.h>#include <math.h> #include "tfrc.h"#include "formula.h"#include "flags.h"int hdr_tfrc::offset_;int hdr_tfrc_ack::offset_;static class TFRCHeaderClass : public PacketHeaderClass {public:	TFRCHeaderClass() : PacketHeaderClass("PacketHeader/TFRC",					      sizeof(hdr_tfrc)) {		bind_offset(&hdr_tfrc::offset_);	}} class_tfrchdr;static class TFRC_ACKHeaderClass : public PacketHeaderClass {public:	TFRC_ACKHeaderClass() : PacketHeaderClass("PacketHeader/TFRC_ACK",						  sizeof(hdr_tfrc_ack)) {		bind_offset(&hdr_tfrc_ack::offset_);	}} class_tfrc_ackhdr;static class TfrcClass : public TclClass {public:  	TfrcClass() : TclClass("Agent/TFRC") {}  	TclObject* create(int, const char*const*) {    		return (new TfrcAgent());  	}} class_tfrc;TfrcAgent::TfrcAgent() : Agent(PT_TFRC), send_timer_(this), 	 NoFeedbacktimer_(this), rate_(0), oldrate_(0), maxrate_(0){	bind("packetSize_", &size_);	bind("rate_", &rate_);	bind("df_", &df_);	bind("tcp_tick_", &tcp_tick_);	bind("ndatapack_", &ndatapack_);	bind("ndatabytes_", &ndatabytes_);	bind("true_loss_rate_", &true_loss_rate_);	bind("srtt_init_", &srtt_init_);	bind("rttvar_init_", &rttvar_init_);	bind("rtxcur_init_", &rtxcur_init_);	bind("rttvar_exp_", &rttvar_exp_);	bind("T_SRTT_BITS", &T_SRTT_BITS);	bind("T_RTTVAR_BITS", &T_RTTVAR_BITS);	bind("InitRate_", &InitRate_);	bind("overhead_", &overhead_);	bind("ssmult_", &ssmult_);	bind("bval_", &bval_);	bind("ca_", &ca_);	bind_bool("printStatus_", &printStatus_);	bind_bool("conservative_", &conservative_);	bind_bool("ecn_", &ecn_);	bind("minrto_", &minrto_);	bind("maxHeavyRounds_", &maxHeavyRounds_);	bind("SndrType_", &SndrType_); 	bind("scmult_", &scmult_);	bind_bool("oldCode_", &oldCode_);	bind("rate_init_", &rate_init_);	bind("rate_init_option_", &rate_init_option_);	bind_bool("slow_increase_", &slow_increase_); 	bind_bool("ss_changes_", &ss_changes_);	bind_bool("voip_", &voip_);	bind("voip_max_pkt_rate_", &voip_max_pkt_rate_);	bind("fsize_", &fsize_);	bind_bool("useHeaders_", &useHeaders_);	bind("headersize_", &headersize_);	seqno_ = -1;	maxseq_ = 0;	datalimited_ = 0;	last_pkt_time_ = 0.0;	bind("maxqueue_", &maxqueue_);	maxqueue_ = MAXSEQ;}/* * Must convert bytes into packets.  * If nbytes == -1, this corresponds to infinite send.  We approximate * infinite by a very large number (MAXSEQ). * For simplicity, when bytes are converted to packets, fractional packets  * are always rounded up.   */void TfrcAgent::sendmsg(int nbytes, const char* /*flags*/){        if (nbytes == -1 && maxseq_ < MAXSEQ)		advanceby(MAXSEQ - maxseq_);        else if (size_ > 0) {		int npkts = int(nbytes/size_);		npkts += (nbytes%size_ ? 1 : 0);		// maxqueue was added by Tom Phelan, to control the		//   transmit queue from the application.		if ((maxseq_ - seqno_) < maxqueue_) {			advanceby(npkts);		}	}}void TfrcAgent::advanceby(int delta){  	maxseq_ += delta;		if (seqno_ == -1) {		// if no packets hve been sent so far, call start.   		start(); 	} else if (datalimited_ && maxseq_ > seqno_) {		// We were data-limited - send a packet now!		// The old code always waited for a timer to expire!!		datalimited_ = 0;		if (!oldCode_) {			sendpkt();		}	}} int TfrcAgent::command(int argc, const char*const* argv){	if (argc==2) {		// are we an infinite sender?		if ( (strcmp(argv[1],"start")==0) && (SndrType_ == 0)) {			start();			return TCL_OK;		}		if (strcmp(argv[1],"stop")==0) {			stop();			return TCL_OK;		}	}  	if ((argc == 3) && (SndrType_ == 1)) {		// or do we need an FTP type app?     	if (strcmp(argv[1], "advance") == 0) {            	int newseq = atoi(argv[2]);		// THIS ISN"T USED.		// newseq: new sequence		// seqno_: next sequence to be sent		// maxseq_: max seq_  produced by app so far.            	if (newseq > maxseq_)                 	advanceby(newseq - maxseq_);            	return (TCL_OK);    	}    	if (strcmp(argv[1], "advanceby") == 0) {      		advanceby(atoi(argv[2]));      		return (TCL_OK);    		}	}	return (Agent::command(argc, argv));}void TfrcAgent::start(){	seqno_=0;					rate_ = InitRate_;	delta_ = 0;	oldrate_ = rate_;  	rate_change_ = SLOW_START;	UrgentFlag = 1;	rtt_=0;	 	sqrtrtt_=1;	rttcur_=1;	tzero_ = 0;	last_change_=0;	maxrate_ = 0; 	ss_maxrate_ = 0;	ndatapack_=0;	ndatabytes_ = 0;	true_loss_rate_ = 0;	active_ = 1; 	round_id = 0;	heavyrounds_ = 0;	t_srtt_ = int(srtt_init_/tcp_tick_) << T_SRTT_BITS;	t_rttvar_ = int(rttvar_init_/tcp_tick_) << T_RTTVAR_BITS;	t_rtxcur_ = rtxcur_init_;	rcvrate = 0 ;	first_pkt_rcvd = 0 ;	// send the first packet	sendpkt();	// ... at initial rate	send_timer_.resched(size_/rate_);	// ... and start timer so we can cut rate 	// in half if we do not get feedback	NoFeedbacktimer_.resched(2*size_/rate_); }void TfrcAgent::stop(){	active_ = 0;	send_timer_.force_cancel();}void TfrcAgent::nextpkt(){	double next = -1;	double xrate = -1; 	if (SndrType_ == 0) {		sendpkt();	}	else {		if (maxseq_ > seqno_) {			sendpkt();		} else			datalimited_ = 1;	}		// If slow_increase_ is set, then during slow start, we increase rate	// slowly - by amount delta per packet 	if (slow_increase_ && (!ss_changes_ || round_id > 2) 	    && (rate_change_ == SLOW_START) 		       && (oldrate_+SMALLFLOAT< rate_)) {		oldrate_ = oldrate_ + delta_;		xrate = oldrate_;	} else {		if (ca_) 			xrate = rate_ * sqrtrtt_/sqrt(rttcur_);		else			xrate = rate_;	}	if (xrate > SMALLFLOAT) {		next = size_/xrate;		if (voip_) {	  	    	double min_interval = 1.0/voip_max_pkt_rate_;		    	if (next < min_interval)				next = min_interval;		}		//		// randomize between next*(1 +/- woverhead_) 		//		next = next*(2*overhead_*Random::uniform()-overhead_+1);		if (next > SMALLFLOAT)			send_timer_.resched(next);	}}void TfrcAgent::update_rtt (double tao, double now) {	/* the TCP update */	t_rtt_ = int((now-tao) /tcp_tick_ + 0.5);	if (t_rtt_==0) t_rtt_=1;	if (t_srtt_ != 0) {		register short rtt_delta;		rtt_delta = t_rtt_ - (t_srtt_ >> T_SRTT_BITS);    		if ((t_srtt_ += rtt_delta) <= 0)    			t_srtt_ = 1;		if (rtt_delta < 0)			rtt_delta = -rtt_delta;	  	rtt_delta -= (t_rttvar_ >> T_RTTVAR_BITS);	  	if ((t_rttvar_ += rtt_delta) <= 0)  			t_rttvar_ = 1;	} else {		t_srtt_ = t_rtt_ << T_SRTT_BITS;				t_rttvar_ = t_rtt_ << (T_RTTVAR_BITS-1);		}	t_rtxcur_ = (((t_rttvar_ << (rttvar_exp_ + (T_SRTT_BITS - T_RTTVAR_BITS))) + t_srtt_)  >> T_SRTT_BITS ) * tcp_tick_;	tzero_=t_rtxcur_; 	if (tzero_ < minrto_)   		tzero_ = minrto_;

⌨️ 快捷键说明

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