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

📄 tcp-session.cc

📁 Ns2 TCP 协议改进 版本 提高goodput
💻 CC
📖 第 1 页 / 共 2 页
字号:
		printf("TcpSessionAgent::timeout(): ignoring unknown timer %d\n", tno);}Segment* TcpSessionAgent::add_pkts(int size, int seqno, int sessionSeqno, int daddr, 			  int dport, int sport, double ts, IntTcpAgent *sender){	/*	 * set rtx timer afresh either if it is not set now or if there are no 	 * data packets outstanding at this time	 */	if (!(rtx_timer_.status() == TIMER_PENDING) || seglist_.count() == 0)		set_rtx_timer();	last_seg_sent_ = CorresHost::add_pkts(size, seqno, sessionSeqno, daddr, dport, sport, ts, sender);	return last_seg_sent_;}		voidTcpSessionAgent::add_agent(IntTcpAgent *agent, int size, double winMult, 			   int winInc, int ssthresh){	CorresHost::add_agent(agent,size,winMult,winInc,ssthresh);	wtSum_ += agent->wt_;	reset_dyn_weights();}intTcpSessionAgent::window(){	if (maxcwnd_ == 0)		return (int(cwnd_));	else		return (int(min(cwnd_,maxcwnd_)));}voidTcpSessionAgent::set_weight(IntTcpAgent *tcp, int wt){	wtSum_ -= tcp->wt_;	tcp->wt_ = wt;	wtSum_ += tcp->wt_;}			voidTcpSessionAgent::reset_dyn_weights(){	IntTcpAgent *tcp;	Islist_iter<IntTcpAgent> conn_iter(conns_);	while ((tcp = conn_iter()) != NULL)		tcp->dynWt_ = tcp->wt_;	dynWtSum_ = wtSum_;}IntTcpAgent *TcpSessionAgent::who_to_snd(int how){	int i = 0;	switch (how) {	/* fine-grained interleaving of connections (per pkt) */	case FINE_ROUND_ROBIN: { 		IntTcpAgent *next;		int wtOK = 0;		if (dynWtSum_ == 0) 			reset_dyn_weights();		do {			wtOK = 0;			if ((next = (*connIter_)()) == NULL) {				connIter_->set_cur(connIter_->get_last());				next = (*connIter_)();			}			i++;			if (next && next->dynWt_>0) {				next->dynWt_--;				dynWtSum_--;				wtOK = 1;			}		} while (next && (!next->data_left_to_send() || !wtOK)			 && (i < connIter_->count()));		if (!next->data_left_to_send())			next = NULL;		return next;	}	/* coarse-grained interleaving across connections (per block of pkts) */	case COARSE_ROUND_ROBIN: {		int maxConsecSegs;		if (curConn_)			maxConsecSegs = (window()*curConn_->wt_)/wtSum_;		if (curConn_ && numConsecSegs_++ < maxConsecSegs && 			curConn_->data_left_to_send())			return curConn_;		else {			numConsecSegs_ = 0;			curConn_ = who_to_snd(FINE_ROUND_ROBIN);			if (curConn_)				numConsecSegs_++;		}		return curConn_;	}	case RANDOM: {		IntTcpAgent *next;				do {			int foo = int(Random::uniform() * nActive_ + 1);						connIter_->set_cur(connIter_->get_last());						for (;foo > 0; foo--)				(*connIter_)();			next = (*connIter_)();		} while (next && !next->data_left_to_send());		return(next);	}	default:		return NULL;	}}voidTcpSessionAgent::send_much(IntTcpAgent* /*agent*/, int force, int reason) {	int npackets = 0;	Islist_iter<Segment> seg_iter(seglist_);	if (reason != TCP_REASON_TIMEOUT &&	    burstsnd_timer_.status() == TIMER_PENDING)		return;	/* no outstanding data and idle time >= t_rtxcur_ */	if ((seg_iter.count() == 0) && (last_send_time_ != -1) &&	    (Scheduler::instance().clock() - last_send_time_ >= t_rtxcur_)) {		if (slow_start_restart_ && restart_bugfix_)			slowdown(CLOSE_CWND_INIT);		else if (slow_start_restart_)			slowdown(CLOSE_CWND_RESTART|CLOSE_SSTHRESH_HALF);		else if (fs_enable_) {			if (cwnd_ < ssthresh_)				cwnd_ = int(cwnd_/2);			else				cwnd_ -= 1;			fs_startseq_ = sessionSeqno_ + 1;			fs_endseq_ = sessionSeqno_ + window();			fs_mode_ = 1;		}	}	while (ok_to_snd(size_)) {		{			IntTcpAgent *sender = who_to_snd(schedDisp_);			if (sender) {				/*				 * remember the connection over which the first				 * packet just before fast start is sent				 */				if (fs_enable_ && fs_mode_ && 				    sessionSeqno_ == fs_startseq_)					connWithPktBeforeFS_ = sender;				/* if retransmission */				/* XXX we pick random conn even if rtx timeout */				if (sender->t_seqno_ < sender->maxseq_) {					int i = 				findSessionSeqno(sender, sender->t_seqno_);					removeSessionSeqno(i);					sender->send_one(i);				}				else {					sender->send_one(sessionSeqno_++);					if (!rtt_active_) {						rtt_active_ = 1;						rtt_seg_ = last_seg_sent_;					}				}				npackets++;			}			else				break;		}		reason = 0;		force = 0;		if (maxburst_ && npackets == maxburst_) {			if (ok_to_snd(size_))				burstsnd_timer_.resched(t_exact_srtt_*maxburst_/window());			break;		}	}	if (npackets > 0)		last_send_time_ = Scheduler::instance().clock();}voidTcpSessionAgent::recv(IntTcpAgent *agent, Packet *pkt, int amt_data_acked){	hdr_tcp *tcph = hdr_tcp::access(pkt);	if (hdr_flags::access(pkt)->ecnecho() && ecn_)		quench(1, agent, tcph->seqno());	clean_segs(size_, pkt, agent, sessionSeqno_,amt_data_acked);	/* XXX okay to do this after clean_segs? */	/* if new data acked and this is not a partial ack */	if (amt_data_acked > 0 && (tcph->seqno() >= agent->recover_ ||	   agent->last_cwnd_action_ != CWND_ACTION_DUPACK /* XXX 1*/) 	    && !dontIncrCwnd_) {		int i = count_bytes_acked_ ? amt_data_acked:1;		while (i-- > 0)			opencwnd(size_,agent);	}	dontIncrCwnd_ = 0;	if (amt_data_acked > 0) {		if (fs_enable_ && fs_mode_ && connWithPktBeforeFS_ == agent)			connWithPktBeforeFS_ = NULL;		newack(pkt);	}	Packet::free(pkt);	send_much(NULL,0,0);}	voidTcpSessionAgent::setflags(Packet *pkt){	hdr_flags *hf = hdr_flags::access(pkt);	if (ecn_)		hf->ect() = 1;}intTcpSessionAgent::findSessionSeqno(IntTcpAgent *sender, int seqno){	Islist_iter<Segment> seg_iter(seglist_);	Segment *cur;	int min = sessionSeqno_;		while ((cur = seg_iter()) != NULL) {		if (sender == cur->sender_ && cur->seqno_ >= seqno && 		    cur->sessionSeqno_ < min)			min = cur->sessionSeqno_;	}	if (min == sessionSeqno_) {		printf("In TcpSessionAgent::findSessionSeqno: search unsuccessful\n");		min = sessionSeqno_ - 1;	}	return (min);}voidTcpSessionAgent::removeSessionSeqno(int sessionSeqno) {	Islist_iter<Segment> seg_iter(seglist_);	Segment *cur, *prev=NULL;		while ((cur = seg_iter()) != NULL) {		if (cur->sessionSeqno_ == sessionSeqno) {			seglist_.remove(cur, prev);			adjust_ownd(cur->size_);			return;		}		prev = cur;	}	printf("In removeSessionSeqno(): unable to find segment with sessionSeqno = %d\n", sessionSeqno);}voidTcpSessionAgent::quench(int how, IntTcpAgent *sender, int seqno){	int i = findSessionSeqno(sender,seqno);	if (i > recover_) {		recover_ = sessionSeqno_ - 1;		last_cwnd_action_ = CWND_ACTION_ECN;		sender->recover_ = sender->maxseq_;		sender->last_cwnd_action_ = CWND_ACTION_ECN;		closecwnd(how,sender);	}}voidTcpSessionAgent::traceVar(TracedVar* v){	double curtime;	Scheduler& s = Scheduler::instance();	char wrk[500];	int n;		curtime = &s ? s.clock() : 0;	if (!strcmp(v->name(), "ownd_") || !strcmp(v->name(), "owndCorr_")) {		if (!strcmp(v->name(), "ownd_"))			sprintf(wrk,"%-8.5f %-2d %-2d %-2d %-2d %s %-6.3f", 				curtime, addr(), port(), daddr(), dport(),				v->name(), double(*((TracedDouble*) v))); 		else if (!strcmp(v->name(), "owndCorr_"))			sprintf(wrk,"%-8.5f %-2d %-2d %-2d %-2d %s %d", 				curtime, addr(), port(), daddr(), dport(),				v->name(), int(*((TracedInt*) v))); 		n = strlen(wrk);		wrk[n] = '\n';		wrk[n+1] = 0;		if (channel_)			(void)Tcl_Write(channel_, wrk, n+1);		wrk[n] = 0;	}	else		TcpAgent::traceVar(v);}			

⌨️ 快捷键说明

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