[Sumover-dev] [svn commit] r4702 - vic/branches/cc/cc
sumover-dev at cs.ucl.ac.uk
sumover-dev at cs.ucl.ac.uk
Sun Mar 21 21:43:03 GMT 2010
Author: soohyunc
Date: Sun Mar 21 21:43:03 2010
New Revision: 4702
Modified:
vic/branches/cc/cc/tfwc_sndr.cpp
vic/branches/cc/cc/tfwc_sndr.h
Log:
(This changes deal with the packet re-ordering.)
Motivation: there are good number of packet re-ordering, especially when the
part of links are consisted of a wireless channel.
Packet re-ordering is particularly bad for RTT measurement, and for cwnd
calculation.
Upon reordering detection, we skip sampling RTT (but still update RTT using
previously sampled RTT). Also, insert the re-ordered packet sequence number into
the received AckVec using previously received AckVec.
** Future work:
when there are more than 3 packet re-ordering, cwnd is not increased - we may
need to consider inflating cwnd intentionally when there are 3 or more packet
re-ordering detection.
(This is because the packets are actually not lost, but only re-ordered.
However, in the cwnd calculation, cwnd has been reduced because the
re-ordered packets are out of the DUPACK range.)
Modified: vic/branches/cc/cc/tfwc_sndr.cpp
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.cpp (original)
+++ vic/branches/cc/cc/tfwc_sndr.cpp Sun Mar 21 21:43:03 2010
@@ -127,7 +127,11 @@
t_srtt_ = int(srtt_init_/tcp_tick_) << T_SRTT_BITS;
t_rttvar_ = int(rttvar_init_/tcp_tick_) << T_RTTVAR_BITS;
- prevno_ = 0;
+ // allocate previously received ackvec in memory
+ pvec_ = (u_int16_t *)malloc(sizeof(u_int16_t) * num_vec_);
+ clear_pvec(num_vec_);
+ __jacked_ = 0;
+ __begins_ = 0;
}
void TfwcSndr::tfwc_sndr_send(int seqno, double now, double offset) {
@@ -144,9 +148,9 @@
// now_, seqno_%TSZ, tsvec_[seqno_%TSZ]);
// sequence number must be greater than zero
- //assert (seqno_ > 0);
+ assert (seqno_ > 0);
// number of total data packet sent
- //ndtp_++;
+ ndtp_++;
// set retransmission timer
set_rtx_timer();
@@ -158,102 +162,152 @@
void TfwcSndr::tfwc_sndr_recv(u_int16_t type, u_int16_t begin, u_int16_t end,
u_int16_t *chunk, double so_rtime)
{
+switch (type) {
+// retrieve ackvec
+case XR_BT_1:
+ {
// number of ack received
- //nakp_++;
+ nakp_++;
+ // so_timestamp (timestamp for packet reception)
+ so_recv_ = so_rtime;
+ // packet reordering?
+ bool reorder = false;
// get start/end seqno that this XR chunk reports
begins_ = begin; // lowest packet seqno
ends_ = end; // highest packet seqno plus one
- // so_timestamp (timestamp for packet reception)
- so_recv_ = so_rtime;
+ // just acked seqno
+ // i.e.,) head seqno(= highest seqno) of this ackvec
+ jacked_ = ends_ - 1;
// get the number of AckVec chunks
// use seqno space to work out the num chunks
// (add one to num unless exactly divisible by BITLEN
// - so it is large enough to accomodate all the bits
- num_elm_ = ends_ - begins_;
- num_vec_ = num_elm_/BITLEN + (num_elm_%BITLEN > 0);
+ num_elm_ = get_numelm(begins_, jacked_);
+ num_vec_ = get_numvec(num_elm_);
- // retrieve ackvec
- if (type == XR_BT_1) {
- // just acked seqno
- // i.e.,) head seqno(= highest seqno) of this ackvec
- jacked_ = ends_ - 1;
- if (jacked_ < prevno_)
+ // declared AckVec
+ ackv_ = (u_int16_t *) malloc (sizeof(u_int16_t) * num_vec_);
+ // clear the existing AckVec
+ clear_ackv(num_vec_);
+ // clone AckVec from Vic
+ clone_ackv(chunk, num_vec_);
+
+ // packet reorder detection
+ int shift = 0;
+ if (jacked_ < __jacked_) {
debug_msg("warning: packet reordering occurred!\n");
-
- // declared AckVec
- ackv_ = (u_int16_t *) malloc (sizeof(u_int16_t) * num_vec_);
- // clear the existing AckVec
- clear_ackv(num_vec_);
- // clone AckVec from Vic
- clone_ackv(chunk, num_vec_);
-
- //fprintf(stderr,
- //" [%s +%d] begins: %d ends: %d jacked: %d\n",
- // __FILE__, __LINE__, begins_, ends_, jacked_);
-
- // generate seqno vector
- gen_seqvec(ackv_, num_vec_);
-
- // generate margin vector
- marginvec(jacked_);
- print_mvec();
-
- // generate reference vector
- // (it represents seqvec when there are no losses)
- // @begin: aoa_+1 (lowest seqno)
- // @end: mvec_[DUPACKS-1] - 1
- gen_refvec(mvec_[DUPACKS-1]-1, aoa_+1);
-
- // TFWC is not turned on (i.e., no packet loss yet)
- if(!is_tfwc_on_) {
- if(detect_loss()) {
- is_tfwc_on_ = true;
- dupack_action();
- ts_ = tsvec_[first_lost_pkt_%TSZ];
- } else {
- // TCP-like AIMD control
- cwnd_ += 1;
- }
- }
- // TFWC is turned on, so control that way
- else {
- control();
+ if(jacked_ < aoa_) {
+ debug_msg("warning: this ack is older than AoA!\n");
+ return;
}
- fprintf(stderr, "\tnow: %f\tcwnd: %d\n", so_recv_, cwnd_);
-
- // set ackofack (real number)
- aoa_ = ackofack();
+ shift = __jacked_ - jacked_;
+ // restore the previous state variables
+ replace(__begins_, __jacked_);
+ num_elm_ = get_numelm(begins_, jacked_);
+ num_vec_ = get_numvec(num_elm_);
+ reorder = true;
+ }
+ else {
+ free(pvec_);
+ }
- // update RTT with the sampled RTT
- tao_ = so_recv_ - tsvec_[jacked_%TSZ];
- update_rtt(tao_);
- fprintf(stderr, "\t<< now_: %f tsvec_[%d]: %f rtt: %f srtt: %f\n",
- so_recv_, jacked_%TSZ, tsvec_[jacked_%TSZ], tao_, srtt_);
+ //fprintf(stderr,
+ //" [%s +%d] begins: %d ends: %d jacked: %d\n",
+ // __FILE__, __LINE__, begins_, ends_, jacked_);
+
+ // if packet reordering occurred, insert re-ordered seqno
+ // into the received ackvec using previously received ackvec
+ if(reorder) {
+ for (int i = 0; i < num_vec_; i++) {
+ ackv_[i] = (ackv_[i] << shift) | pvec_[i];
+ }
+ }
- // is TFWC being driven by timeout mechanism?
- if(to_driven_ && is_tfwc_on_)
- new_rto(tao_);
+ // generate seqno vector
+ gen_seqvec(ackv_, num_vec_);
- // initialize variables for the next pkt reception
- free(ackv_);
- init_var();
+ // generate margin vector
+ marginvec(jacked_);
+ print_mvec();
+
+ // generate reference vector
+ // (it represents seqvec when there are no losses)
+ // @begin: aoa_+1 (lowest seqno)
+ // @end: mvec_[DUPACKS-1] - 1
+ gen_refvec(mvec_[DUPACKS-1]-1, aoa_+1);
+
+ // TFWC is not turned on (i.e., no packet loss yet)
+ if(!is_tfwc_on_) {
+ if(detect_loss()) {
+ is_tfwc_on_ = true;
+ dupack_action();
+ ts_ = tsvec_[first_lost_pkt_%TSZ];
+ } else {
+ // TCP-like AIMD control
+ cwnd_ += 1;
+ }
+ }
+ // TFWC is turned on, so control that way
+ else {
+ control();
}
- // retrieve ts echo
- else if (type == XR_BT_3) {
- ntep_++; // number of ts echo packet received
+ fprintf(stderr, "\tnow: %f\tcwnd: %d\n", so_recv_, cwnd_);
- ts_echo_ = chunk[num_vec_ - 1];
- fprintf(stderr,
- " [%s +%d] ts echo: %f\n", __FILE__,__LINE__, ts_echo_);
+ // set ackofack (real number)
+ aoa_ = ackofack();
- tao_ = now() - ts_echo_;
+ // sampled RTT
+ if(!reorder)
+ tao_ = so_recv_ - tsvec_[jacked_%TSZ];
+ // update RTT with the sampled RTT
+ update_rtt(tao_);
+ fprintf(stderr, "\t<< now_: %f tsvec_[%d]: %f rtt: %f srtt: %f\n",
+ so_recv_, jacked_%TSZ, tsvec_[jacked_%TSZ], tao_, srtt_);
+
+ // is TFWC being driven by timeout mechanism?
+ if(to_driven_ && is_tfwc_on_)
+ new_rto(tao_);
+
+ // reset variables for the next pkt reception
+ reset_var();
+ }
+ break;
+
+// retrieve ts echo
+case XR_BT_3:
+ {
+ ntep_++; // number of ts echo packet received
+ ts_echo_ = chunk[num_vec_ - 1];
+ //fprintf(stderr, " [%s +%d] ts echo: %f\n",
+ // __FILE__,__LINE__, ts_echo_);
+
+ tao_ = now() - ts_echo_;
+ }
+ break;
+
+default:
+ break;
+} // end switch (type)
+return;
+}
+
+void TfwcSndr::reset_var() {
+ num_missing_ = 0;
+
+ // store jack'ed and begins
+ store(begins_, jacked_);
+ // declare pvec to store ackv
+ pvec_ = (u_int16_t *)malloc(sizeof(u_int16_t) * num_vec_);
+ clear_pvec(num_vec_);
+ // store ackv
+ copy_ackv(num_vec_);
+ //print_vec(pvec_, num_vec_);
- // update RTT
- //update_rtt(tao_);
- }
+ // finally, free ackvec
+ free(ackv_);
}
/*
Modified: vic/branches/cc/cc/tfwc_sndr.h
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.h (original)
+++ vic/branches/cc/cc/tfwc_sndr.h Sun Mar 21 21:43:03 2010
@@ -130,11 +130,8 @@
// generate reference seqno
void gen_refvec(int end, int begin);
- // init variables
- inline void init_var() {
- num_missing_ = 0;
- prevno_ = jacked_;
- }
+ // reset variables
+ void reset_var();
// get the first position in ackvec where 1 is marked
inline u_int16_t get_head_pos(u_int16_t ackvec) {
@@ -177,6 +174,13 @@
fprintf(stderr, " %d", seqvec_[i]);
fprintf(stderr, " )\n");
}
+ // print vec
+ inline void print_vec(u_int16_t *vec, int numelm) {
+ fprintf(stderr, "\t(");
+ for (int i = 0; i < numelm; i++)
+ fprintf(stderr, " %d", vec[i]);
+ fprintf(stderr, " )\n");
+ }
// retransmission timer
TfwcRtxTimer rtx_timer_;
@@ -186,7 +190,7 @@
int mvec_[DUPACKS]; // margin vec (simulatinmg TCP 3 dupacks)
u_int16_t *ackv_; // received AckVec (from TfwcRcvr)
- u_int32_t pvec_; // sent packet list
+ u_int16_t *pvec_; // previous (stored) AckVec
u_int16_t aoa_; // ack of ack
u_int32_t t_now_; // the time when the data packet sent
u_int32_t t_ts_; // time stamp (u_int32_t type)
@@ -237,6 +241,12 @@
ackv_[i] = ntohs(c[i]);
}
+ // copy AckVec to store
+ inline void copy_ackv(int n) {
+ for(int i = 0; i < n; i++)
+ pvec_[i] = ackv_[i];
+ }
+
// clear timestamp vector
inline void clear_tsv (int n) {
for (int i = 0; i < n; i++)
@@ -255,12 +265,38 @@
ackv_[i] = 0;
}
+ // clear ackvec
+ inline void clear_pvec (int n) {
+ for (int i = 0; i < n; i++)
+ pvec_[i] = 0;
+ }
+
// clear refvec
inline void clear_refv (int n) {
for (int i = 0; i < n; i++)
refvec_[i] = 0;
}
+ // number of ackvec chunks
+ inline int get_numvec(int n) {
+ return (n/BITLEN + (n%BITLEN > 0));
+ }
+
+ // number of ackvec elements
+ inline int get_numelm (int begin, int end) {
+ return (end - begin + 1);
+ }
+
+ // replace jack'ed and begins from the previous ackvec
+ inline void replace (u_int16_t lowest, u_int16_t highest) {
+ begins_ = lowest; jacked_ = highest;
+ }
+
+ // store jack'ed and begins
+ inline void store (u_int16_t lowest, u_int16_t highest) {
+ __begins_ = lowest; __jacked_ = highest;
+ }
+
int ndtp_; // number of data packet sent
int nakp_; // number of ackvec packet received
int ntep_; // number of ts echo packet received
@@ -328,8 +364,9 @@
double t0_; // t0 value at TCP throughput equation
double tcp_tick_;
- // other variables
- u_int16_t prevno_; // previous highest packet sequence number
+ // highest/lowest packet sequence numbers (prev ackvec)
+ u_int16_t __jacked_; // previous highest packet sequence number
+ u_int16_t __begins_; // previous lowest packet sequence number
};
#endif
More information about the Sumover-dev
mailing list