📄 tcp-session.cc
字号:
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 + -