[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