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

📄 tcp-session.cc

📁 Ns2 TCP 协议改进 版本 提高goodput
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1997 Regents of the University of California. * 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 the Daedalus Research * 	Group at the University of California Berkeley. * 4. Neither the name of the University nor of the Research Group may be *    used to endorse or promote products derived from this software without *    specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 THE REGENTS 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. * * $Header: /nfs/jade/vint/CVSROOT/ns-2/tcp/tcp-session.cc,v 1.18 2000/09/01 03:04:07 haoboy Exp $ */#include <stdlib.h>#include <math.h>#include "ip.h"#include "flags.h"#include "random.h"#include "template.h"#include "nilist.h"#include "tcp.h"#include "tcp-int.h"#include "tcp-session.h"/* * We separate TCP functionality into two parts: that having to do with  * providing a reliable, ordered byte-stream service, and that having to do with * congestion control and loss recovery. The former is done on a per-connection * basis and is implemented as part of IntTcpAgent ("integrated TCP"). The  * latter is done in an integrated fashion across multiple TCP connections, and * is implemented as part of TcpSessionAgent ("TCP session"). TcpSessionAgent is * derived from CorresHost ("correspondent host"), which keeps track of the  * state of all TCP (TCP/Int) connections to a host that it is corresponding  * with. * * The motivation for this separation of functionality is to make an ensemble of * connection more well-behaved than a set of independent TCP connections. * The packet loss rate is cut down and the chances of losses being recovered  * via data-driven techniques (rather than via timeouts) is improved. At the  * same time, we do not introduce any unnecessary coupling between the  * logically-independent byte-streams that the set of connections represents.  * This is in contrast to the coupling that is inherent in the multiplexing at  * the application layer of multiple byte-streams onto a single TCP connection. * * For questions/comments, please contact: *   Venkata N. Padmanabhan (padmanab@cs.berkeley.edu) *   http://www.cs.berkeley.edu/~padmanab */static class TcpSessionClass : public TclClass {public:	TcpSessionClass() : TclClass("Agent/TCP/Session") {}	TclObject* create(int, const char*const*) {		return (new TcpSessionAgent()); 	}} class_tcpsession;TcpSessionAgent::TcpSessionAgent() : CorresHost(), 	rtx_timer_(this), burstsnd_timer_(this), sessionSeqno_(0),	last_send_time_(-1), curConn_(0), numConsecSegs_(0), 	schedDisp_(FINE_ROUND_ROBIN), wtSum_(0), dynWtSum_(0) {	bind("ownd_", &ownd_);	bind("owndCorr_", &owndCorrection_);	bind_bool("proxyopt_", &proxyopt_);	bind_bool("fixedIw_", &fixedIw_);	bind("schedDisp_", &schedDisp_);	bind_bool("disableIntLossRecov_", &disableIntLossRecov_);	sessionList_.append(this);}intTcpSessionAgent::command(int argc, const char*const* argv){	if (argc == 2) {		if (!strcmp(argv[1], "resetwt")) {			Islist_iter<IntTcpAgent> conn_iter(conns_);			IntTcpAgent *tcp;			while ((tcp = conn_iter()) != NULL) 				tcp->wt_ = 1;			wtSum_ = conn_iter.count();			return (TCL_OK);		}	}	return (CorresHost::command(argc, argv));}voidSessionRtxTimer::expire(Event*){	a_->timeout(TCP_TIMER_RTX);}voidSessionResetTimer::expire(Event*){	a_->timeout(TCP_TIMER_RESET);}voidSessionBurstSndTimer::expire(Event*){	a_->timeout(TCP_TIMER_BURSTSND);}voidTcpSessionAgent::reset_rtx_timer(int /*mild*/, int backoff){	if (backoff)		rtt_backoff();	set_rtx_timer();	rtt_active_ = 0;}voidTcpSessionAgent::set_rtx_timer(){	if (rtx_timer_.status() == TIMER_PENDING)		rtx_timer_.cancel();	if (reset_timer_.status() == TIMER_PENDING)		reset_timer_.cancel();	if (fs_enable_ && fs_mode_)		reset_timer_.resched(rtt_exact_timeout());	else		rtx_timer_.resched(rtt_timeout());}voidTcpSessionAgent::cancel_rtx_timer(){	rtx_timer_.force_cancel();	reset_timer_.force_cancel();}voidTcpSessionAgent::cancel_timers(){	rtx_timer_.force_cancel();	reset_timer_.force_cancel();	burstsnd_timer_.force_cancel();	delsnd_timer_.force_cancel();}intTcpSessionAgent::fs_pkt() {	return (fs_enable_ && fs_mode_ && sessionSeqno_-1 >= fs_startseq_ &&		sessionSeqno_-1 < fs_endseq_);}voidTcpSessionAgent::rtt_update_exact(double tao){	double g = 1/8; /* gain used for smoothing rtt */	double h = 1/4; /* gain used for smoothing rttvar */	double delta;	if (t_exact_srtt_ != 0) {		delta = tao - t_exact_srtt_;		if (delta < 0)			delta = -delta;		/* update the fine-grained estimate of the smoothed RTT */		if (t_exact_srtt_ != 0) 			t_exact_srtt_ = g*tao + (1-g)*t_exact_srtt_;		else			t_exact_srtt_ = tao;		/* update the fine-grained estimate of mean deviation in RTT */		delta -= t_exact_rttvar_;		t_exact_rttvar_ += h*delta;	}	else {		t_exact_srtt_ = tao;		t_exact_rttvar_ = tao/2;	}}	voidTcpSessionAgent::newack(Packet *pkt) {	double now = Scheduler::instance().clock();	Islist_iter<Segment> seg_iter(seglist_);	hdr_tcp *tcph = hdr_tcp::access(pkt);	hdr_flags *fh = hdr_flags::access(pkt);	if (!fh->no_ts_) {		/* if the timestamp option is being used */		if (ts_option_) {			rtt_update(now - tcph->ts_echo());			rtt_update_exact(now - tcph->ts_echo());		}		/* if segment being timed just got acked */		if (rtt_active_ && rtt_seg_ == NULL) {			t_backoff_ = 1;			rtt_active_ = 0;			if (!ts_option_)				rtt_update(now - rtt_ts_);		}	}	if (seg_iter.count() > 0)		set_rtx_timer();	else		cancel_rtx_timer();}voidTcpSessionAgent::timeout(int tno){	if (tno == TCP_TIMER_BURSTSND)		send_much(NULL,0,0);	else if (tno == TCP_TIMER_RESET) {		Islist_iter<Segment> seg_iter(seglist_);		Segment *curseg;		Islist_iter<IntTcpAgent> conn_iter(conns_);		IntTcpAgent *curconn;		fs_mode_ = 0;		if (seg_iter.count() == 0 && !slow_start_restart_) {			return;		}		recover_ = sessionSeqno_ - 1;		last_cwnd_action_ = CWND_ACTION_TIMEOUT;		ownd_ = 0;		owndCorrection_ = 0;		while ((curconn = conn_iter()) != NULL) {			curconn->maxseq_ = curconn->highest_ack_;			curconn->t_seqno_ = curconn->highest_ack_ + 1;			curconn->recover_ = curconn->maxseq_;			curconn->last_cwnd_action_ = CWND_ACTION_TIMEOUT;		}		while ((curseg = seg_iter()) != NULL) {			/* XXX exclude packets sent "recently"? */			curseg->size_ = 0;		}		/* 		 * If first pkt sent before fast start has not gotten through, 		 * treat this as a regular rtx timeout. Otherwise, close cwnd		 * and reset timer but don't back off timer.		 */		if (connWithPktBeforeFS_) {			connWithPktBeforeFS_ = NULL;			timeout(TCP_TIMER_RTX);		}		else {			slowdown(CLOSE_CWND_INIT);			reset_rtx_timer(0,0);			send_much(NULL, 0, TCP_REASON_TIMEOUT);		}	}	else if (tno == TCP_TIMER_RTX) {		Islist_iter<Segment> seg_iter(seglist_);		Segment *curseg;		Islist_iter<IntTcpAgent> conn_iter(conns_);		IntTcpAgent *curconn;		if (seg_iter.count() == 0 && !slow_start_restart_) {			return;		}		recover_ = sessionSeqno_ - 1;		last_cwnd_action_ = CWND_ACTION_TIMEOUT;		if (seg_iter.count() == 0 && restart_bugfix_) {			slowdown(CLOSE_CWND_INIT);			reset_rtx_timer(0,0);		}		else {			slowdown(CLOSE_CWND_RESTART|CLOSE_SSTHRESH_HALF);			reset_rtx_timer(0,1);		}		nrexmit_++;		ownd_ = 0;		owndCorrection_ = 0;		while ((curconn = conn_iter()) != NULL) {			curconn->t_seqno_ = curconn->highest_ack_ + 1;			curconn->recover_ = curconn->maxseq_;			curconn->last_cwnd_action_ = CWND_ACTION_TIMEOUT;		}		while ((curseg = seg_iter()) != NULL) {			/* XXX exclude packets sent "recently"? */			curseg->size_ = 0;		}		send_much(NULL, 0, TCP_REASON_TIMEOUT);	}	else

⌨️ 快捷键说明

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