svn commit: r189444 - head/sys/netinet

Randall Stewart rrs at FreeBSD.org
Fri Mar 6 03:03:53 PST 2009


Author: rrs
Date: Fri Mar  6 11:03:52 2009
New Revision: 189444
URL: http://svn.freebsd.org/changeset/base/189444

Log:
  Fixes for window probes:
   1) WP should never be marked unless flight size is 0
   2) When recovering from wp if the peer ack's it we don't mark for retran
   3) When recovering, we must assure a timer is still running.

Modified:
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctp_output.c

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Fri Mar  6 10:45:57 2009	(r189443)
+++ head/sys/netinet/sctp_indata.c	Fri Mar  6 11:03:52 2009	(r189444)
@@ -4179,13 +4179,8 @@ sctp_window_probe_recovery(struct sctp_t
     struct sctp_nets *net,
     struct sctp_tmit_chunk *tp1)
 {
-	struct sctp_tmit_chunk *chk;
-
-	/* First setup this one and get it moved back */
-	sctp_flight_size_decrease(tp1);
-	sctp_total_flight_decrease(stcb, tp1);
 	tp1->window_probe = 0;
-	if ((tp1->sent == SCTP_FORWARD_TSN_SKIP) || (tp1->data == NULL)) {
+	if ((tp1->sent >= SCTP_DATAGRAM_ACKED) || (tp1->data == NULL)) {
 		/* TSN's skipped we do NOT move back. */
 		sctp_misc_ints(SCTP_FLIGHT_LOG_DWN_WP_FWD,
 		    tp1->whoTo->flight_size,
@@ -4194,7 +4189,12 @@ sctp_window_probe_recovery(struct sctp_t
 		    tp1->rec.data.TSN_seq);
 		return;
 	}
-	tp1->sent = SCTP_DATAGRAM_UNSENT;
+	/* First setup this by shrinking flight */
+	sctp_flight_size_decrease(tp1);
+	sctp_total_flight_decrease(stcb, tp1);
+	/* Now mark for resend */
+	tp1->sent = SCTP_DATAGRAM_RESEND;
+	asoc->sent_queue_retran_cnt++;
 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
 		sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_WP,
 		    tp1->whoTo->flight_size,
@@ -4202,26 +4202,6 @@ sctp_window_probe_recovery(struct sctp_t
 		    (uintptr_t) tp1->whoTo,
 		    tp1->rec.data.TSN_seq);
 	}
-	TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
-	TAILQ_INSERT_HEAD(&asoc->send_queue, tp1, sctp_next);
-	asoc->sent_queue_cnt--;
-	asoc->send_queue_cnt++;
-	/*
-	 * Now all guys marked for RESEND on the sent_queue must be moved
-	 * back too.
-	 */
-	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
-		if (chk->sent == SCTP_DATAGRAM_RESEND) {
-			/* Another chunk to move */
-			chk->sent = SCTP_DATAGRAM_UNSENT;
-			/* It should not be in flight */
-			TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
-			TAILQ_INSERT_AFTER(&asoc->send_queue, tp1, chk, sctp_next);
-			asoc->sent_queue_cnt--;
-			asoc->send_queue_cnt++;
-			sctp_ucount_decr(asoc->sent_queue_retran_cnt);
-		}
-	}
 }
 
 void
@@ -4552,8 +4532,9 @@ sctp_express_handle_sack(struct sctp_tcb
 again:
 	j = 0;
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
+		int to_ticks;
+
 		if (win_probe_recovery && (net->window_probe)) {
-			net->window_probe = 0;
 			win_probe_recovered = 1;
 			/*
 			 * Find first chunk that was used with window probe
@@ -4562,25 +4543,35 @@ again:
 			/* sa_ignore FREED_MEMORY */
 			TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
 				if (tp1->window_probe) {
-					/* move back to data send queue */
 					sctp_window_probe_recovery(stcb, asoc, net, tp1);
 					break;
 				}
 			}
 		}
+		if (net->RTO == 0) {
+			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+		} else {
+			to_ticks = MSEC_TO_TICKS(net->RTO);
+		}
 		if (net->flight_size) {
-			int to_ticks;
-
-			if (net->RTO == 0) {
-				to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
-			} else {
-				to_ticks = MSEC_TO_TICKS(net->RTO);
-			}
 			j++;
 			(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
 			    sctp_timeout_handler, &net->rxt_timer);
+			if (net->window_probe) {
+				net->window_probe = 0;
+			}
 		} else {
-			if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
+			if (net->window_probe) {
+				/*
+				 * In window probes we must assure a timer
+				 * is still running there
+				 */
+				net->window_probe = 0;
+				if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
+					SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
+					    sctp_timeout_handler, &net->rxt_timer);
+				}
+			} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
 				    stcb, net,
 				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
@@ -5563,7 +5554,6 @@ again:
 	j = 0;
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
 		if (win_probe_recovery && (net->window_probe)) {
-			net->window_probe = 0;
 			win_probe_recovered = 1;
 			/*-
 			 * Find first chunk that was used with
@@ -5582,8 +5572,21 @@ again:
 			j++;
 			sctp_timer_start(SCTP_TIMER_TYPE_SEND,
 			    stcb->sctp_ep, stcb, net);
+			if (net->window_probe) {
+			}
 		} else {
-			if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
+			if (net->window_probe) {
+				/*
+				 * In window probes we must assure a timer
+				 * is still running there
+				 */
+
+				if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
+					sctp_timer_start(SCTP_TIMER_TYPE_SEND,
+					    stcb->sctp_ep, stcb, net);
+
+				}
+			} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
 				    stcb, net,
 				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
@@ -6553,8 +6556,9 @@ sctp_express_handle_nr_sack(struct sctp_
 again:
 	j = 0;
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
+		int to_ticks;
+
 		if (win_probe_recovery && (net->window_probe)) {
-			net->window_probe = 0;
 			win_probe_recovered = 1;
 			/*
 			 * Find first chunk that was used with window probe
@@ -6569,19 +6573,29 @@ again:
 				}
 			}
 		}
+		if (net->RTO == 0) {
+			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+		} else {
+			to_ticks = MSEC_TO_TICKS(net->RTO);
+		}
 		if (net->flight_size) {
-			int to_ticks;
 
-			if (net->RTO == 0) {
-				to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
-			} else {
-				to_ticks = MSEC_TO_TICKS(net->RTO);
-			}
 			j++;
 			(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
 			    sctp_timeout_handler, &net->rxt_timer);
+			if (net->window_probe) {
+				net->window_probe = 0;
+			}
 		} else {
-			if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
+			if (net->window_probe) {
+				/*
+				 * In window probes we must assure a timer
+				 * is still running there
+				 */
+				net->window_probe = 0;
+				(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
+				    sctp_timeout_handler, &net->rxt_timer);
+			} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
 				    stcb, net,
 				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
@@ -8111,7 +8125,6 @@ again:
 	j = 0;
 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
 		if (win_probe_recovery && (net->window_probe)) {
-			net->window_probe = 0;
 			win_probe_recovered = 1;
 			/*-
 			 * Find first chunk that was used with
@@ -8130,8 +8143,15 @@ again:
 			j++;
 			sctp_timer_start(SCTP_TIMER_TYPE_SEND,
 			    stcb->sctp_ep, stcb, net);
+			if (net->window_probe) {
+				net->window_probe = 0;
+			}
 		} else {
-			if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
+			if (net->window_probe) {
+				net->window_probe = 0;
+				sctp_timer_start(SCTP_TIMER_TYPE_SEND,
+				    stcb->sctp_ep, stcb, net);
+			} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
 				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
 				    stcb, net,
 				    SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Fri Mar  6 10:45:57 2009	(r189443)
+++ head/sys/netinet/sctp_output.c	Fri Mar  6 11:03:52 2009	(r189444)
@@ -10036,7 +10036,7 @@ again_one_more_time:
 							SCTP_STAT_INCR_COUNTER64(sctps_fragusrmsgs);
 					}
 					if ((mtu == 0) || (r_mtu == 0) || (one_chunk)) {
-						if (one_chunk) {
+						if ((one_chunk) && (stcb->asoc.total_flight == 0)) {
 							data_list[0]->window_probe = 1;
 							net->window_probe = 1;
 						}


More information about the svn-src-all mailing list