[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ns] Run-time modifiable NUMDUPACKS
Hi,
Attached to this email is a patch to ns that migrates NUMDUPACKS from a
#defined constant to a run-time modifiable tcl variable in the TCP stack.
This variable defaults to the same value of 3.
The only (moderate) ugliness in this patch is in scoreboard-rh.{h,cc}, where
the scoreboard references NUMDUPACKS. As the constant NUMDUPACKS is
disappering and numdupacks_ is now a member of Agent/TCP, a pointer to the
scoreboard's parent Agent/TCP's numdupacks_ member had to be installed.
This is less than beautiful, but effective.
This change breaks NO validation tests. As long as you don't change
numdupacks_, anyway. ;-)
If whoever owns the respective TCP variants (other than Sack1 and Agent/TCP,
which I think are both OK) would like to verify the correctness of this in
all cases, I would appreciate it.
Thanks,
Ethan
diff -ruN ns-2-snapshot-20000725/chost.cc ns-2-variable_numdupacks/chost.cc
--- ns-2-snapshot-20000725/chost.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/chost.cc Thu Jul 27 21:25:32 2000
@@ -242,7 +242,7 @@
}
/*
* A pkt is a candidate for retransmission if it is the leftmost one in the
- * unacked window for the connection AND has at least NUMDUPACKS
+ * unacked window for the connection AND has at least numdupacks_
* dupacks/later acks AND (at least one dupack OR a later packet also
* with the threshold number of dup/later acks). A pkt is also a candidate
* for immediate retransmission if it has partialack_ set, indicating that
@@ -255,7 +255,7 @@
* curArray_ only contains segments that are the first oldest
* unacked segments of their connection (i.e., they are at the left
* edge of their window) and have either received a
- * partial ack and/or have received at least NUMDUPACKS
+ * partial ack and/or have received at least cur->numdupacks_
* dupacks/later acks. Thus, segments in curArray_ have a high
* probability (but not certain) of being eligible for
* retransmission. Using curArray_ avoids having to scan
@@ -391,7 +391,7 @@
dontIncrCwnd_ = 1;
}
}
- if (cur->dupacks_+cur->later_acks_ >= NUMDUPACKS &&
+ if (cur->dupacks_+cur->later_acks_ >= sender->numdupacks_ &&
!cur->thresh_dupacks_) {
cur->thresh_dupacks_ = 1;
cur->sender_->num_thresh_dupack_segs_++;
@@ -403,7 +403,7 @@
the num_thresh_dupack_segs_ check */
if (!remove_flag &&
cur->seqno_ == cur->sender_->highest_ack_ + 1 &&
- (cur->dupacks_ + cur->later_acks_ >= NUMDUPACKS ||
+ (cur->dupacks_ + cur->later_acks_ >= sender->numdupacks_ ||
cur->partialack_)) {
curArray_[rexmtSegCount_] = cur;
prevArray_[rexmtSegCount_] = prev;
diff -ruN ns-2-snapshot-20000725/scoreboard-rh.cc ns-2-variable_numdupacks/scoreboard-rh.cc
--- ns-2-snapshot-20000725/scoreboard-rh.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/scoreboard-rh.cc Thu Jul 27 21:25:32 2000
@@ -218,7 +218,7 @@
for (i=SBN[(first_)%SBSIZE].seq_no_;
i<SBN[(first_)%SBSIZE].seq_no_+length_; i++) {
if (!SBNI.ack_flag_ && !SBNI.sack_flag_ && !SBNI.retran_
- && (SBNI.sack_cnt_ >= NUMDUPACKS)) {
+ && (SBNI.sack_cnt_ >= *numdupacks_)) {
return (i);
}
}
@@ -257,7 +257,7 @@
new_holes++;
}
#else
- if (!SBNI.ack_flag_ && !SBNI.sack_flag_ && SBNI.sack_cnt_ == NUMDUPACKS) {
+ if (!SBNI.ack_flag_ && !SBNI.sack_flag_ && SBNI.sack_cnt_ == *numdupacks_) {
new_holes++;
}
#endif
@@ -303,7 +303,7 @@
if (!SBNI.ack_flag_ && !SBNI.sack_flag_) {
SBNI.retran_ = 0;
SBNI.snd_nxt_ = 0;
- SBNI.sack_cnt_ = NUMDUPACKS; // This forces all holes to be retransmitted.
+ SBNI.sack_cnt_ = *numdupacks_; // This forces all holes to be retransmitted.
}
}
@@ -314,7 +314,7 @@
SBNI.sack_flag_ = 0;
SBNI.retran_ = 0;
SBNI.snd_nxt_ = 0;
- SBNI.sack_cnt_ = NUMDUPACKS; // This forces it to be retransmitted.
+ SBNI.sack_cnt_ = *numdupacks_; // This forces it to be retransmitted.
}
}
diff -ruN ns-2-snapshot-20000725/scoreboard-rh.h ns-2-variable_numdupacks/scoreboard-rh.h
--- ns-2-snapshot-20000725/scoreboard-rh.h Thu Jul 27 21:40:36 2000
+++ ns-2-variable_numdupacks/scoreboard-rh.h Thu Jul 27 21:40:51 2000
@@ -45,7 +45,7 @@
class ScoreBoardRH {
public:
- ScoreBoardRH() {first_=0; length_=0; retran_occured_=0;}
+ ScoreBoardRH(int *numdupacks) : numdupacks_(numdupacks) {first_=0; length_=0; retran_occured_=0;}
int IsEmpty () {return (length_ == 0);}
void ClearScoreBoard ();
int GetNextRetran ();
@@ -65,6 +65,9 @@
in which a retransmission occured */
int retran_sacked_; /* This variable stores the last adjustment interval
in which a retransmission was sacked */
+ int *numdupacks_; /* I know, it stinks... But this is numdupacks_ from
+ * our parent TCP stack. */
+
struct ScoreBoardNode {
int seq_no_; /* Packet number */
int ack_flag_; /* Acked by cumulative ACK */
diff -ruN ns-2-snapshot-20000725/tcl/lib/ns-default.tcl ns-2-variable_numdupacks/tcl/lib/ns-default.tcl
--- ns-2-snapshot-20000725/tcl/lib/ns-default.tcl Thu Jul 27 21:22:02 2000
+++ ns-2-variable_numdupacks/tcl/lib/ns-default.tcl Thu Jul 27 21:25:51 2000
@@ -91,6 +91,7 @@
Agent/TCP set t_seqno_ 0
Agent/TCP set maxburst_ 0
Agent/TCP set maxcwnd_ 0
+Agent/TCP set numdupacks_ 3
Agent/TCP set window_ 20
Agent/TCP set windowInit_ 1
Agent/TCP set windowInitOption_ 1
diff -ruN ns-2-snapshot-20000725/tcp-fack.cc ns-2-variable_numdupacks/tcp-fack.cc
--- ns-2-snapshot-20000725/tcp-fack.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp-fack.cc Thu Jul 27 21:25:32 2000
@@ -169,7 +169,7 @@
/*
* a duplicate ACK
*/
- if (dupacks_ >= NUMDUPACKS) {
+ if (dupacks_ >= numdupacks_) {
/*
* Assume we dropped just one packet.
* Retransmit last ack + 1
diff -ruN ns-2-snapshot-20000725/tcp-newreno.cc ns-2-variable_numdupacks/tcp-newreno.cc
--- ns-2-snapshot-20000725/tcp-newreno.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp-newreno.cc Thu Jul 27 21:25:32 2000
@@ -219,10 +219,10 @@
tcp_eln(pkt);
return;
}
- if (++dupacks_ == NUMDUPACKS) {
+ if (++dupacks_ == numdupacks_) {
dupack_action();
- dupwnd_ = NUMDUPACKS;
- } else if (dupacks_ > NUMDUPACKS) {
+ dupwnd_ = numdupacks_;
+ } else if (dupacks_ > numdupacks_) {
++dupwnd_; // fast recovery
/* For every two duplicate ACKs we receive (in the
* "fast retransmit phase"), send one entirely new
@@ -230,7 +230,7 @@
*/
if (newreno_changes_ > 0 && (dupacks_ % 2) == 1)
output (t_seqno_++,0);
- } else if (dupacks_ < NUMDUPACKS && singledup_ ) {
+ } else if (dupacks_ < numdupacks_ && singledup_ ) {
send_one();
}
}
@@ -250,7 +250,7 @@
* window of data on exiting Fast Recovery.
*/
send_much(0, 0, maxburst_);
- else if (dupacks_ > NUMDUPACKS - 1 && newreno_changes_ == 0)
+ else if (dupacks_ > numdupacks_ - 1 && newreno_changes_ == 0)
send_much(0, 0, 2);
}
diff -ruN ns-2-snapshot-20000725/tcp-reno.cc ns-2-variable_numdupacks/tcp-reno.cc
--- ns-2-snapshot-20000725/tcp-reno.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp-reno.cc Thu Jul 27 21:25:32 2000
@@ -83,12 +83,12 @@
tcp_eln(pkt);
return;
}
- if (++dupacks_ == NUMDUPACKS) {
+ if (++dupacks_ == numdupacks_) {
dupack_action();
- dupwnd_ = NUMDUPACKS;
- } else if (dupacks_ > NUMDUPACKS) {
+ dupwnd_ = numdupacks_;
+ } else if (dupacks_ > numdupacks_) {
++dupwnd_; // fast recovery
- } else if (dupacks_ < NUMDUPACKS && singledup_ ) {
+ } else if (dupacks_ < numdupacks_ && singledup_ ) {
send_one();
}
}
@@ -102,7 +102,7 @@
* Try to send more data
*/
- if (dupacks_ == 0 || dupacks_ > NUMDUPACKS - 1)
+ if (dupacks_ == 0 || dupacks_ > numdupacks_ - 1)
send_much(0, 0, maxburst_);
}
diff -ruN ns-2-snapshot-20000725/tcp-rfc793edu.cc ns-2-variable_numdupacks/tcp-rfc793edu.cc
--- ns-2-snapshot-20000725/tcp-rfc793edu.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp-rfc793edu.cc Thu Jul 27 21:25:32 2000
@@ -227,7 +227,7 @@
return;
}
// fast retransmission
- if ( (++dupacks_ == NUMDUPACKS) && add793fastrtx_ ) {
+ if ( (++dupacks_ == numdupacks_) && add793fastrtx_ ) {
dupack_action();
}
}
diff -ruN ns-2-snapshot-20000725/tcp-sack-rh.cc ns-2-variable_numdupacks/tcp-sack-rh.cc
--- ns-2-snapshot-20000725/tcp-sack-rh.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp-sack-rh.cc Thu Jul 27 21:25:32 2000
@@ -49,7 +49,7 @@
class SackRHTcpAgent : public TcpAgent {
public:
- SackRHTcpAgent();
+ SackRHTcpAgent();
virtual int window();
virtual void recv(Packet *pkt, Handler*);
virtual void timeout(int tno);
@@ -91,7 +91,7 @@
SackRHTcpAgent::SackRHTcpAgent() : fack_(-1),
retran_data_(0), num_dupacks_(0), rh_state_(RH_INCR), rh_id_(0), rh_max_(0),
- rh_est_hole_state_(0), rh_retran_flag_(0), rh_ecn_flag_(0)
+ rh_est_hole_state_(0), rh_retran_flag_(0), rh_ecn_flag_(0), scb_(&numdupacks_)
{
}
@@ -127,7 +127,7 @@
if (!sackpresent && (old_ack == last_ack_)) {
num_dupacks_++;
if ((rh_est_hole_state_ == RHEH_COUNTING) &&
- (num_dupacks_ == NUMDUPACKS)) {
+ (num_dupacks_ == numdupacks_)) {
rh_est_hole_state_ = RHEH_NEW_HOLE;
}
}
@@ -180,7 +180,7 @@
&& (last_ack_ > old_ack)) {
retran_data_ = 0;
num_dupacks_ -= (last_ack_ - old_ack - 1);
- if (num_dupacks_ >= NUMDUPACKS) {
+ if (num_dupacks_ >= numdupacks_) {
rh_est_hole_state_ = RHEH_NEW_HOLE;
}
else {
diff -ruN ns-2-snapshot-20000725/tcp-sack1.cc ns-2-variable_numdupacks/tcp-sack1.cc
--- ns-2-snapshot-20000725/tcp-sack1.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp-sack1.cc Thu Jul 27 21:25:32 2000
@@ -126,14 +126,14 @@
* acknowledges new data.
*/
if(scb_.CheckUpdate()) {
- if (++dupacks_ == NUMDUPACKS) {
+ if (++dupacks_ == numdupacks_) {
/*
* Assume we dropped just one packet.
* Retransmit last ack + 1
* and try to resume the sequence.
*/
dupack_action();
- } else if (dupacks_ < NUMDUPACKS && singledup_ ) {
+ } else if (dupacks_ < numdupacks_ && singledup_ ) {
send_one();
}
}
@@ -204,17 +204,17 @@
reset_rtx_timer(1,0);
/*
* There are three possibilities:
- * (1) pipe_ = int(cwnd_) - NUMDUPACKS;
- * (2) pipe_ = window() - NUMDUPACKS;
- * (3) pipe_ = maxseq_ - highest_ack_ - NUMDUPACKS;
+ * (1) pipe_ = int(cwnd_) - numdupacks_;
+ * (2) pipe_ = window() - numdupacks_;
+ * (3) pipe_ = maxseq_ - highest_ack_ - numdupacks_;
* equation (2) takes into account the receiver's
* advertised window, and equation (3) takes into
* accout a data-limited sender.
*/
if (!singledup_)
- pipe_ = maxseq_ - highest_ack_ - NUMDUPACKS;
+ pipe_ = maxseq_ - highest_ack_ - numdupacks_;
else pipe_ = maxseq_ - highest_ack_ - 1;
- //pipe_ = int(cwnd_) - NUMDUPACKS;
+ //pipe_ = int(cwnd_) - numdupacks_;
fastrecov_ = TRUE;
scb_.MarkRetran(highest_ack_+1);
output(last_ack_ + 1, TCP_REASON_DUPACK);
@@ -233,10 +233,10 @@
sack_action:
recover_ = maxseq_;
last_cwnd_action_ = CWND_ACTION_DUPACK;
- pipe_ = int(cwnd_) - NUMDUPACKS;
- //pipe_ = maxseq_ - highest_ack_ - NUMDUPACKS;
+ pipe_ = int(cwnd_) - numdupacks_;
+ //pipe_ = maxseq_ - highest_ack_ - numdupacks_;
//if (!singledup_)
- // pipe_ = maxseq_ - highest_ack_ - NUMDUPACKS;
+ // pipe_ = maxseq_ - highest_ack_ - numdupacks_;
//else pipe_ = maxseq_ - highest_ack_ - 1;
slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF);
reset_rtx_timer(1,0);
@@ -244,7 +244,7 @@
scb_.MarkRetran(highest_ack_+1);
output(last_ack_ + 1, TCP_REASON_DUPACK); // from top
/*
- * If dynamically adjusting NUMDUPACKS, record information
+ * If dynamically adjusting numdupacks_, record information
* at this point.
*/
return;
@@ -254,8 +254,8 @@
{
if (tno == TCP_TIMER_RTX) {
/*
- * IF DSACK and dynamic adjustment of NUMDUPACKS,
- * check whether a smaller value of NUMDUPACKS
+ * IF DSACK and dynamic adjustment of numdupacks_,
+ * check whether a smaller value of numdupacks_
* would have prevented this retransmit timeout.
* If DSACK and detection of premature retransmit
* timeouts, then save some info here.
diff -ruN ns-2-snapshot-20000725/tcp-vegas.cc ns-2-variable_numdupacks/tcp-vegas.cc
--- ns-2-snapshot-20000725/tcp-vegas.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp-vegas.cc Thu Jul 27 21:25:32 2000
@@ -153,7 +153,7 @@
cwnd_ = initial_window();
}
/* check if cwnd has been inflated */
- if(dupacks_ > NUMDUPACKS && cwnd_ > v_newcwnd_) {
+ if(dupacks_ > numdupacks_ && cwnd_ > v_newcwnd_) {
cwnd_ = v_newcwnd_;
// vegas ssthresh is used only during slow-start
ssthresh_ = 2;
@@ -300,7 +300,7 @@
--v_worried_;
int expired=vegas_expire(pkt);
if(expired>=0) {
- dupacks_ = NUMDUPACKS;
+ dupacks_ = numdupacks_;
output(expired, TCP_REASON_DUPACK);
} else
v_worried_ = 0;
@@ -309,7 +309,7 @@
/* check if a timeout should happen */
++dupacks_;
int expired=vegas_expire(pkt);
- if (expired>=0 || dupacks_ == NUMDUPACKS) {
+ if (expired>=0 || dupacks_ == numdupacks_) {
double sendTime=v_sendtime_[(last_ack_+1) % v_maxwnd_];
int transmits=v_transmits_[(last_ack_+1) % v_maxwnd_];
/* The line below, for "bug_fix_" true, avoids
@@ -356,9 +356,9 @@
output(last_ack_ + 1, TCP_REASON_DUPACK);
if(transmits==1)
- dupacks_ = NUMDUPACKS;
+ dupacks_ = numdupacks_;
}
- } else if (dupacks_ > NUMDUPACKS)
+ } else if (dupacks_ > numdupacks_)
++cwnd_;
}
Packet::free(pkt);
@@ -370,7 +370,7 @@
/*
* Try to send more data
*/
- if (dupacks_ == 0 || dupacks_ > NUMDUPACKS - 1)
+ if (dupacks_ == 0 || dupacks_ > numdupacks_ - 1)
send_much(0, 0, maxburst_);
}
diff -ruN ns-2-snapshot-20000725/tcp.cc ns-2-variable_numdupacks/tcp.cc
--- ns-2-snapshot-20000725/tcp.cc Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp.cc Thu Jul 27 21:25:32 2000
@@ -129,6 +129,7 @@
delay_bind_init_one("timestamps_");
delay_bind_init_one("maxburst_");
delay_bind_init_one("maxcwnd_");
+ delay_bind_init_one("numdupacks_");
delay_bind_init_one("maxrto_");
delay_bind_init_one("srtt_init_");
delay_bind_init_one("rttvar_init_");
@@ -199,6 +200,7 @@
if (delay_bind_bool(varName, localName, "timestamps_", &ts_option_ , tracer)) return TCL_OK;
if (delay_bind(varName, localName, "maxburst_", &maxburst_ , tracer)) return TCL_OK;
if (delay_bind(varName, localName, "maxcwnd_", &maxcwnd_ , tracer)) return TCL_OK;
+ if (delay_bind(varName, localName, "numdupacks_", &numdupacks_, tracer)) return TCL_OK;
if (delay_bind(varName, localName, "maxrto_", &maxrto_ , tracer)) return TCL_OK;
if (delay_bind(varName, localName, "srtt_init_", &srtt_init_ , tracer)) return TCL_OK;
if (delay_bind(varName, localName, "rttvar_init_", &rttvar_init_ , tracer)) return TCL_OK;
@@ -1035,7 +1037,7 @@
* A first or second duplicate acknowledgement has arrived, and
* singledup_ is enabled.
* If the receiver's advertised window permits, and we are exceeding our
- * congestion window by less than NUMDUPACKS, then send a new packet.
+ * congestion window by less than numdupacks_, then send a new packet.
*/
void
TcpAgent::send_one()
@@ -1115,9 +1117,9 @@
tcp_eln(pkt);
return;
}
- if (++dupacks_ == NUMDUPACKS && !noFastRetrans_) {
+ if (++dupacks_ == numdupacks_ && !noFastRetrans_) {
dupack_action();
- } else if (dupacks_ < NUMDUPACKS && singledup_ ) {
+ } else if (dupacks_ < numdupacks_ && singledup_ ) {
send_one();
}
}
@@ -1440,7 +1442,7 @@
F_counting = 0 ;
}
else {
- if (dupacks_ == NUMDUPACKS)
+ if (dupacks_ == numdupacks_)
RTT_count ++ ;
}
}
diff -ruN ns-2-snapshot-20000725/tcp.h ns-2-variable_numdupacks/tcp.h
--- ns-2-snapshot-20000725/tcp.h Thu Jul 27 21:20:51 2000
+++ ns-2-variable_numdupacks/tcp.h Thu Jul 27 21:25:32 2000
@@ -103,7 +103,8 @@
* 0.01 for new window algorithms,
*/
-#define NUMDUPACKS 3 /* normally 3, sometimes 1 */
+/* #define NUMDUPACKS 3 This is now set in tcl/lib/ns-default.tcl
+ * as Agent/Tcp numdupacks_ */
#define TCP_MAXSEQ 1073741824 /* Number that curseq_ is set to for */
/* "infinite send" (2^30) */
@@ -250,6 +251,7 @@
int ts_option_; /* use RFC1323-like timestamps? */
int maxburst_; /* max # packets can send back-2-back */
int maxcwnd_; /* max # cwnd can ever be */
+ int numdupacks_; /* dup ACKs before fast retransmit */
double maxrto_; /* max value of an RTO */
int old_ecn_; /* For backwards compatibility with the
* old ECN implementation, which never