00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "tcp-fs.h"
00020
00021 void ResetTimer::expire(Event *) {
00022 a_->timeout(TCP_TIMER_RESET);
00023 }
00024
00025 static class TcpFsClass : public TclClass {
00026 public:
00027 TcpFsClass() : TclClass("Agent/TCP/FS") {}
00028 TclObject* create(int, const char*const*) {
00029 return (new TcpFsAgent());
00030 }
00031 } class_tcpfs;
00032
00033 static class RenoTcpFsClass : public TclClass {
00034 public:
00035 RenoTcpFsClass() : TclClass("Agent/TCP/Reno/FS") {}
00036 TclObject* create(int, const char*const*) {
00037 return (new RenoTcpFsAgent());
00038 }
00039 } class_renotcpfs;
00040
00041 static class NewRenoTcpFsClass : public TclClass {
00042 public:
00043 NewRenoTcpFsClass() : TclClass("Agent/TCP/Newreno/FS") {}
00044 TclObject* create(int, const char*const*) {
00045 return (new NewRenoTcpFsAgent());
00046 }
00047 } class_newrenotcpfs;
00048
00049 #ifdef USE_FACK
00050 static class FackTcpFsClass : public TclClass {
00051 public:
00052 FackTcpFsClass() : TclClass("Agent/TCP/Fack/FS") {}
00053 TclObject* create(int, const char*const*) {
00054 return (new FackTcpFsAgent());
00055 }
00056 } class_facktcpfs;
00057 #endif
00058
00059
00060
00061 void
00062 TcpFsAgent::output_helper(Packet *pkt)
00063 {
00064 hdr_tcp *tcph = hdr_tcp::access(pkt);
00065 double now = Scheduler::instance().clock();
00066 double idle_time = now - last_recv_time_;
00067 double timeout = ((t_srtt_ >> 3) + t_rttvar_) * tcp_tick_ ;
00068 maxseq_ = max(maxseq_, highest_ack_);
00069
00070
00071
00072
00073
00074
00075
00076
00077 if ((idle_time > timeout) && (maxseq_ == highest_ack_) && (cwnd_ > 1)){
00078
00079
00080
00081
00082
00083
00084 if (cwnd_ < ssthresh_)
00085 cwnd_ = int(cwnd_/2);
00086 else
00087 cwnd_ -= 1;
00088
00089 fs_startseq_ = highest_ack_+2;
00090 fs_endseq_ = highest_ack_+window()+1;
00091 fs_mode_ = 1;
00092 }
00093
00094 hdr_flags::access(pkt)->fs_ = 0;
00095
00096 if (tcph->seqno() >= fs_startseq_ && tcph->seqno() < fs_endseq_ && fs_mode_) {
00097
00098 if (tcph->seqno() > maxseq_) {
00099 hdr_flags::access(pkt)->fs_ = 1;
00100 }
00101 }
00102 }
00103
00104
00105 void
00106 TcpFsAgent::recv_helper(Packet *)
00107 {
00108 double now = Scheduler::instance().clock();
00109 last_recv_time_ = now;
00110 }
00111
00112
00113 void
00114 TcpFsAgent::send_helper(int maxburst)
00115 {
00116
00117
00118
00119
00120
00121
00122 if (t_seqno_ <= highest_ack_ + window() && t_seqno_ < curseq_) {
00123 burstsnd_timer_.resched(t_exact_srtt_*maxburst/window());
00124 }
00125 }
00126
00127 #ifdef USE_FACK
00128
00129 void
00130 FackTcpFsAgent::send_helper(int maxburst)
00131 {
00132
00133
00134
00135
00136
00137
00138 if ((t_seqno_ <= fack_ + window() - retran_data_) && (!timeout_) && (t_seqno_ < curseq_)) {
00139 burstsnd_timer_.resched(t_exact_srtt_*maxburst/window());
00140 }
00141 }
00142 #endif
00143
00144
00145 void
00146 TcpFsAgent::send_idle_helper()
00147 {
00148
00149
00150
00151
00152
00153 }
00154
00155
00156 void
00157 TcpFsAgent::recv_newack_helper(Packet *pkt)
00158 {
00159 hdr_tcp *tcph = hdr_tcp::access(pkt);
00160 double tao = Scheduler::instance().clock() - tcph->ts_echo();
00161 double g = 1/8;
00162 double h = 1/4;
00163 double delta;
00164 int ackcount, i;
00165
00166
00167
00168
00169
00170 if (count_bytes_acked_)
00171 ackcount = tcph->seqno() - last_ack_;
00172 else
00173 ackcount = 1;
00174 newack(pkt);
00175 maxseq_ = max(maxseq_, highest_ack_);
00176 if (t_exact_srtt_ != 0) {
00177 delta = tao - t_exact_srtt_;
00178 if (delta < 0)
00179 delta = -delta;
00180
00181 if (t_exact_srtt_ != 0)
00182 t_exact_srtt_ = g*tao + (1-g)*t_exact_srtt_;
00183 else
00184 t_exact_srtt_ = tao;
00185
00186 delta -= t_exact_rttvar_;
00187 t_exact_rttvar_ += h*delta;
00188 }
00189 else {
00190 t_exact_srtt_ = tao;
00191 t_exact_rttvar_ = tao/2;
00192 }
00193
00194 for (i=0; i<ackcount; i++)
00195 opencwnd();
00196
00197 if (fs_mode_ && (highest_ack_ >= fs_endseq_-1))
00198 fs_mode_ = 0;
00199
00200 if ((highest_ack_ >= curseq_-1) && !closed_) {
00201 closed_ = 1;
00202 finish();
00203 }
00204 }
00205
00206 void
00207 NewRenoTcpFsAgent::partialnewack_helper(Packet* pkt)
00208 {
00209 partialnewack(pkt);
00210
00211 maxseq_ = max(maxseq_, highest_ack_);
00212 if (fs_mode_ && fast_loss_recov_) {
00213
00214
00215
00216
00217
00218 timeout_nonrtx(TCP_TIMER_RESET);
00219 }
00220 else {
00221 output(last_ack_ + 1, 0);
00222 }
00223 }
00224
00225 void
00226 TcpFsAgent::set_rtx_timer()
00227 {
00228 if (rtx_timer_.status() == TIMER_PENDING)
00229 rtx_timer_.cancel();
00230 if (reset_timer_.status() == TIMER_PENDING)
00231 reset_timer_.cancel();
00232 if (fs_mode_ && fast_loss_recov_ && fast_reset_timer_)
00233 reset_timer_.resched(rtt_exact_timeout());
00234 else if (fs_mode_ && fast_loss_recov_)
00235 reset_timer_.resched(rtt_timeout());
00236 else
00237 rtx_timer_.resched(rtt_timeout());
00238 }
00239
00240 void
00241 TcpFsAgent::cancel_rtx_timer()
00242 {
00243 rtx_timer_.force_cancel();
00244 reset_timer_.force_cancel();
00245 }
00246
00247 void
00248 TcpFsAgent::cancel_timers()
00249 {
00250 rtx_timer_.force_cancel();
00251 reset_timer_.force_cancel();
00252 burstsnd_timer_.force_cancel();
00253 delsnd_timer_.force_cancel();
00254 }
00255
00256 void
00257 TcpFsAgent::timeout_nonrtx(int tno)
00258 {
00259 if (tno == TCP_TIMER_RESET) {
00260 fs_mode_ = 0;
00261 dupacks_ = 0;
00262 if (highest_ack_ == maxseq_ && !slow_start_restart_) {
00263
00264
00265
00266
00267 return;
00268 };
00269
00270
00271
00272
00273 if (highest_ack_ < fs_startseq_-1) {
00274 maxseq_ = fs_startseq_ - 1;
00275 recover_ = maxseq_;
00276 timeout(TCP_TIMER_RTX);
00277 }
00278
00279 else {
00280 if (highest_ack_ > last_ack_)
00281 last_ack_ = highest_ack_;
00282 maxseq_ = last_ack_;
00283 recover_ = maxseq_;
00284 last_cwnd_action_ = CWND_ACTION_TIMEOUT;
00285 slowdown(CLOSE_CWND_INIT);
00286 timeout_nonrtx_helper(tno);
00287 }
00288 }
00289 else {
00290 TcpAgent::timeout_nonrtx(tno);
00291 }
00292 }
00293
00294 void
00295 TcpFsAgent::timeout_nonrtx_helper(int tno)
00296 {
00297 if (tno == TCP_TIMER_RESET) {
00298 reset_rtx_timer(0,0);
00299 send_much(0, TCP_REASON_TIMEOUT, maxburst_);
00300 }
00301 }
00302
00303 void
00304 RenoTcpFsAgent::timeout_nonrtx_helper(int tno)
00305 {
00306 if (tno == TCP_TIMER_RESET) {
00307 dupwnd_ = 0;
00308 dupacks_ = 0;
00309 TcpFsAgent::timeout_nonrtx_helper(tno);
00310 }
00311 }
00312
00313 void
00314 NewRenoTcpFsAgent::timeout_nonrtx_helper(int tno)
00315 {
00316 if (tno == TCP_TIMER_RESET) {
00317 dupwnd_ = 0;
00318 dupacks_ = 0;
00319 TcpFsAgent::timeout_nonrtx_helper(tno);
00320 }
00321 }
00322
00323 #ifdef USE_FACK
00324 void
00325 FackTcpFsAgent::timeout_nonrtx_helper(int tno)
00326 {
00327 if (tno == TCP_TIMER_RESET) {
00328 timeout_ = FALSE;
00329 retran_data_ = 0;
00330 fack_ = last_ack_;
00331 t_seqno_ = last_ack_ + 1;
00332 reset_rtx_timer(TCP_REASON_TIMEOUT, 0);
00333 send_much(0, TCP_REASON_TIMEOUT);
00334 }
00335 }
00336 #endif