📄 tcp-westwood-nr.cc
字号:
double sample_bwe_new=sample_bwe; double sample_bwe_old=last_bwe_sample_; double ack_delta=ack_interv; int Num_cicli; if (total_time_ < tau_/4.0) { Num_cicli = 0; ack_interv=total_time_; } else { Num_cicli = (int)(floor(((4.0*total_time_)/tau_))); ack_interv = total_time_-0.25*tau_*((double)(Num_cicli)); } int i1; for (i1=0;i1<(Num_cicli); i1++) { //if (m<0) { //sample_bwe=sample_bwe_old+m*pow((i1*tau_/4.0),interp_type_); // } current_bwe_ = current_bwe_*(7.0/9.0)+(sample_bwe+last_bwe_sample_)/9.0; last_bwe_sample_ = sample_bwe; } if (ack_interv>0) { current_bwe_ = current_bwe_ * (2.0*tau_-ack_interv)/(2.0*tau_+ack_interv) + ack_interv*(sample_bwe_new+last_bwe_sample_)/(2.0*tau_+ack_interv); last_bwe_sample_ = sample_bwe_new; } total_time_=0.0; total_size_=0.0; } break; case 5: total_size_ = total_size_ + acked_size; total_time_ = total_time_ + ack_interv; if (((rtt_estimate >0)&&(total_time_>rtt_estimate))) { sample_bwe = total_size_/total_time_; current_bwe_=current_bwe_ * fr_alpha_ + sample_bwe*(1.0 - fr_alpha_); last_bwe_sample_ = sample_bwe; total_time_=0; total_size_=0; } break; case 6: total_size_ = total_size_ + acked_size; total_time_ = total_time_ + ack_interv; if (((rtt_estimate >0)&&(total_time_>rtt_estimate))) { sample_bwe = total_size_/total_time_; double sample_bwe1; sample_bwe1=0.5*(sample_bwe+last_bwe_sample_); current_bwe_=current_bwe_*fr_alpha_ + sample_bwe1*(1.0 - fr_alpha_); last_bwe_sample_ = sample_bwe; total_time_=0; total_size_=0; } break;case 7: total_size_ = total_size_ + acked_size; total_time_ = total_time_ + ack_interv; if (((rtt_estimate >0)&&(total_time_>rtt_estimate))) { sample_bwe = total_size_/total_time_; double m=(sample_bwe-last_bwe_sample_)/pow(total_time_,interp_type_); double sample_bwe_new=sample_bwe; double sample_bwe_old=last_bwe_sample_; double ack_delta=ack_interv; int Num_cicli; if (total_time_ < tau_/4.0) { Num_cicli = 0; ack_interv=total_time_; } else { Num_cicli = (int)(floor(((4.0*total_time_)/tau_))); ack_interv = total_time_-0.25*tau_*((double)(Num_cicli)); } int i1; for (i1=0;i1<(Num_cicli); i1++) { sample_bwe=sample_bwe_old+m*pow((i1*tau_/4.0),interp_type_); current_bwe_ = current_bwe_*(7.0/9.0)+2.0*(sample_bwe)/9.0; last_bwe_sample_ = sample_bwe; } if (ack_interv>0) { current_bwe_ = current_bwe_ * (2.0*tau_-ack_interv)/(2.0*tau_+ack_interv) + 2.0*ack_interv*(sample_bwe_new)/(2.0*tau_+ack_interv); last_bwe_sample_ = sample_bwe_new; } total_time_=0; total_size_=0; }break; case 8: sample_bwe = acked_size/ack_interv; fr_alpha_=exp((-1.0*ack_interv/tau_)); current_bwe_=current_bwe_*fr_alpha_ + sample_bwe*(1.0 - fr_alpha_); last_bwe_sample_ = sample_bwe;break; case 9: total_size_ = total_size_ + acked_size; total_time_ = total_time_ + ack_interv; if (((rtt_estimate >0)&&(total_time_>rtt_estimate))) { sample_bwe = total_size_/total_time_; fr_alpha_=exp((-1.0*total_time_/tau_)); current_bwe_=current_bwe_*fr_alpha_ + sample_bwe*(1.0 - fr_alpha_); last_bwe_sample_ = sample_bwe; total_time_=0; total_size_=0; } break;case 10: total_size_ = total_size_ + acked_size; total_time_ = total_time_ + ack_interv; double ci; if (((rtt_estimate >0)&&(total_time_>rtt_estimate))) { //ci=cwnd_-(current_bwe_*min_rtt_estimate)/(8.0*(double)size_); if (qest_ > fr_a_) sample_bwe = total_size_/total_time_; else sample_bwe = last_bwe_sample_; fr_alpha_=exp((-1.0*total_time_/tau_)); current_bwe_=current_bwe_*fr_alpha_ + sample_bwe*(1.0 - fr_alpha_); last_bwe_sample_ = sample_bwe; total_time_=0; total_size_=0; }} // end of filter_type switchdouble sstemp=(((current_bwe_*(min_rtt_estimate))/((double)(size_*8.0))));//double sstemp1=0.9*qest_+(((current_bwe_*(min_rtt_estimate))/((double)(size_*8.0))));#ifdef MYDEBUG hdr_ip *iph = hdr_ip::access(pkt); char *src_portaddr = Address::instance().print_portaddr(iph->sport()); printf("sc%s: ack. no. %d at time %f, bwe=%f, cwnd = %d, ssthresh_ = %d\n", src_portaddr, tcph->seqno_, fr_now, current_bwe_/1000000, (int)cwnd_, (int)ssthresh_); printf("sc%s: now = %f, acked_size = %d, rxdiff = %f, last_ack_ = %d\n", src_portaddr, fr_now, acked_size, (fr_now - lastackrx_), last_ack_); printf("sc%s: unaccounted_ = %d, fr_a_= %f, min_rtt_estimate = %f\n", src_portaddr, unaccounted_, fr_a_, min_rtt_estimate);#endif#ifdef MYDEBUG_RTT double f = t_rtt_ * tcp_tick_; printf("source %s: %f cwnd=%d bwe=%f rtt=%f\n", src_portaddr, fr_now, (int)cwnd_, current_bwe_/1000000, f); #endif #ifdef MYREPORT hdr_ip *iph = hdr_ip::access(pkt); char *src_portaddr = Address::instance().print_portaddr(iph->src()); printf("%s %f %d %f %d\n", src_portaddr, fr_now, (int)cwnd_, current_bwe_/1000000, (int)ssthresh_); #endif lastackrx_ = fr_now;}/////// recv()void WestwoodNRTcpAgent::recv(Packet *pkt, Handler* h){ // START BWE COMPUTATION bwe_computation(pkt); //double cwndapp,sstreshapp; //cwndapp=cwnd_; //sstreshapp=ssthresh_; NewRenoTcpAgent::recv(pkt,h); /*if ((cwnd_>cwndapp)&&(cwndapp<sstreshapp)) { cwnd_=cwnd_+openadd_; //a more aggressive slow start send_much(0, 0, maxburst_); }*/}/////////////////// Added by MV// these where originally in TcpAgent()/////// slowdown()voidWestwoodNRTcpAgent::slowdown(int how){ double win, halfwin, decreasewin; int slowstart = 0; double fr_now = Scheduler::instance().clock(); // we are in slowstart for sure if cwnd < ssthresh if (cwnd_ < ssthresh_) slowstart = 1; // we are in slowstart - need to trace this event trace_event("SLOW_START"); if (precision_reduce_) { halfwin = windowd() / 2; if (wnd_option_ == 6) { /* binomial controls */ decreasewin = windowd() - (1.0-decrease_num_)*pow(windowd(),l_parameter_); } else decreasewin = decrease_num_ * windowd(); win = windowd(); } else { int temp; temp = (int)(window() / 2); halfwin = (double) temp; if (wnd_option_ == 6) { /* binomial controls */ temp = (int)(window() - (1.0-decrease_num_)*pow(window(),l_parameter_)); } else temp = (int)(decrease_num_ * window()); decreasewin = (double) temp; win = (double) window(); } if (how & CLOSE_SSTHRESH_HALF) // For the first decrease, decrease by half // even for non-standard values of decrease_num_. if (first_decrease_ == 1 || slowstart || last_cwnd_action_ == CWND_ACTION_TIMEOUT) { // Do we really want halfwin instead of decreasewin // after a timeout? ssthresh_ = (int) halfwin; } else { ssthresh_ = (int) decreasewin; } else if (how & THREE_QUARTER_SSTHRESH) if (ssthresh_ < 3*cwnd_/4) ssthresh_ = (int)(3*cwnd_/4); if (how & CLOSE_CWND_HALF) // For the first decrease, decrease by half // even for non-standard values of decrease_num_. if (first_decrease_ == 1 || slowstart || decrease_num_ == 0.5) { cwnd_ = halfwin; } else cwnd_ = decreasewin; else if (how & CWND_HALF_WITH_MIN) { // We have not thought about how non-standard TCPs, with // non-standard values of decrease_num_, should respond // after quiescent periods. cwnd_ = decreasewin; if (cwnd_ < 1) cwnd_ = 1; } /// else if (how & CLOSE_FASTER) { // TCP Westwood // this might be critical what with the coarseness of the timer; // keep in mind that TCP computes the timeout as // (#of ticks) * (tick_duration) // We need to do away with the coarseness... double rtt_estimate = t_rtt_ * tcp_tick_; if ((rtt_estimate <= min_rtt_estimate)&&(rtt_estimate > 0)) { min_rtt_estimate = rtt_estimate; } double sstemp=(((current_bwe_*(min_rtt_estimate))/((double)(size_*8.0)))); if (sstemp < 2) sstemp = 2; ssthresh_ = (int)(sstemp); cwnd_ = 2; }//printf("set timeout = %f%f\n", fr_now,ssthresh_); else if (how & CLOSE_CWND_RESTART) cwnd_ = int(wnd_restart_); else if (how & CLOSE_CWND_INIT) cwnd_ = int(wnd_init_); else if (how & CLOSE_CWND_ONE) cwnd_ = 1; else if (how & CLOSE_CWND_HALF_WAY) { // cwnd_ = win - (win - W_used)/2 ; cwnd_ = W_used + decrease_num_ * (win - W_used); if (cwnd_ < 1) cwnd_ = 1; } if (ssthresh_ < 2) ssthresh_ = 2; if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE)) cong_action_ = TRUE; fcnt_ = count_ = 0; if (first_decrease_ == 1) first_decrease_ = 0;}/////// newack()/* * Process a packet that acks previously unacknowleged data. */void WestwoodNRTcpAgent::newack(Packet* pkt){ hdr_tcp *tcph = hdr_tcp::access(pkt); myseqno_ = tcph->seqno_; //call parent newack NewRenoTcpAgent::newack(pkt);}///// // delay_bind_dispatch()//Westwood bindsintWestwoodNRTcpAgent::delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer){ if (delay_bind(varName, localName, "lastackno_", &lastackno_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "lastackrx_", &lastackrx_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "fr_alpha_", &fr_alpha_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "filter_type_", &filter_type_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "tau_", &tau_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "mss_", &mss_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "current_bwe_", ¤t_bwe_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "last_bwe_sample_", &last_bwe_sample_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "unaccounted_", &unaccounted_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "fr_a_", &fr_a_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "min_rtt_estimate", &min_rtt_estimate, tracer)) return TCL_OK; if (delay_bind(varName, localName, "myseqno_", &myseqno_, tracer)) return TCL_OK; // these where originally in NewRenoTcpAgent() if (delay_bind(varName, localName, "newreno_changes_", &newreno_changes_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "newreno_changes1_", &newreno_changes1_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "exit_recovery_fix_", &exit_recovery_fix_, tracer)) return TCL_OK; if (delay_bind(varName, localName, "partial_window_deflation_", &partial_window_deflation_, tracer)) return TCL_OK; return NewRenoTcpAgent::delay_bind_dispatch(varName, localName, tracer);}/* tickoff is the time since the clock last ticked when * the packet we are using to compute the RTT was sent *//* t_rtt_ is the number of ticks that have occurred so far, * starting from the tick BEFORE the packet was sent */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -