[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ns] Bugfixes/enhancements for scoreboard.cc



Hi all,
I believe I have found and fixed two bugs in the scoreboard code for SACK.
Attached to this message is a diff against scoreboard.cc containing these
changes.

The first involves creation of a scoreboard; the existing code creates a
scoreboard any time a packet is processed by UpdateScoreboard(); I believe
this should only happen when the processed packet contains a SACK block.
The fix is simply to check that tcph->sa_length() is nonzero before creating
a scoreboard.  A SACK-less packet falls straight through this check,
preventing from creating an invalid scoreboard (which is truncated upon
receipt of a packet containing SACK information, anyway).

The second fix also involves SACK-less packets processed by
UpdateScoreboard().  The check for advancing the left edge of the stored
SACK information is only processed for a packet containing SACK information;
this prevents a cumulative acknowledgement that covers SACKed packets from
properly updating the scoreboard.  The attached fix moves this check outside
of the per-SACK-block portion of code and into the globally-executed
portion.  (This has the added side effect of not trying to update a
packet-dependent characteristic on a per-SACK-block basis, as it can only
occur once per packet)

Please let me know if you have thoughts on this code, it seems to work well
for me.
Ethan
--- scoreboard.cc	Wed Jul  5 13:54:33 2000
+++ ns-2/scoreboard.cc	Wed Jul  5 12:58:28 2000
@@ -64,7 +64,7 @@
 	int retran_decr = 0;
 
 	//  If there is no scoreboard, create one.
-	if (length_ == 0) {
+	if (length_ == 0 && tcph->sa_length()) {
 		i = last_ack+1;
 		SBNI.seq_no_ = i;
 		SBNI.ack_flag_ = 0;
@@ -78,7 +78,29 @@
 			exit(1);
 		}
 	}	
-
+	
+	//  Advance the left edge of the block.
+	if (SBN[first_].seq_no_ <= last_ack) {
+		for (i=SBN[(first_)%SBSIZE].seq_no_; i<=last_ack; i++) {
+			//  Advance the ACK
+			if (SBNI.seq_no_ <= last_ack) {
+				ASSERT(first_ == i%SBSIZE);
+				first_ = (first_+1)%SBSIZE; 
+				length_--;
+				ASSERT1(length_ >= 0);
+				SBNI.ack_flag_ = 1;
+				SBNI.sack_flag_ = 1;
+				if (SBNI.retran_) {
+					SBNI.retran_ = 0;
+					SBNI.snd_nxt_ = 0;
+					retran_decr++;
+				}
+				if (length_==0) 
+					break;
+			}
+		}
+	}
+	
 	for (sack_index=0; sack_index < tcph->sa_length(); sack_index++) {
 		sack_left = tcph->sa_left(sack_index);
 		sack_right = tcph->sa_right(sack_index);
@@ -99,28 +124,6 @@
 				}
 			}
 		}
-
-		//  Advance the left edge of the block.
-		if (SBN[first_].seq_no_ <= last_ack) {
-			for (i=SBN[(first_)%SBSIZE].seq_no_; i<=last_ack; i++) {
-				//  Advance the ACK
-				if (SBNI.seq_no_ <= last_ack) {
-					ASSERT(first_ == i%SBSIZE);
-					first_ = (first_+1)%SBSIZE; 
-					length_--;
-					ASSERT1(length_ >= 0);
-					SBNI.ack_flag_ = 1;
-					SBNI.sack_flag_ = 1;
-					if (SBNI.retran_) {
-						SBNI.retran_ = 0;
-						SBNI.snd_nxt_ = 0;
-						retran_decr++;
-					}
-					if (length_==0) 
-					  break;
-				}
-			}
-		}
 		
 		for (i=SBN[(first_)%SBSIZE].seq_no_; i<sack_right; i++) {
 			//  Check to see if this segment is now covered by the sack block