Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Apr 2016 18:58:47 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r298713 - head/sys/netinet
Message-ID:  <201604271858.u3RIwlNA073653@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Wed Apr 27 18:58:47 2016
New Revision: 298713
URL: https://svnweb.freebsd.org/changeset/base/298713

Log:
  Don't use the control argument after calling sctp_add_to_readq().
  This breaks the userland stack. There should be no functional change
  for the FreeBSD kernel stack.
  While there, use consistent variable nameing.

Modified:
  head/sys/netinet/sctp_indata.c

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Wed Apr 27 17:49:42 2016	(r298712)
+++ head/sys/netinet/sctp_indata.c	Wed Apr 27 18:58:47 2016	(r298713)
@@ -812,11 +812,6 @@ restart:
 						control->on_strm_q = 0;
 					}
 				}
-				if (control->on_read_q == 0) {
-					sctp_add_to_readq(stcb->sctp_ep, stcb, control,
-					    &stcb->sctp_socket->so_rcv, control->end_added,
-					    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
-				}
 				if (control->pdapi_started) {
 					strm->pd_api_started = 0;
 					control->pdapi_started = 0;
@@ -825,6 +820,11 @@ restart:
 					TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm);
 					control->on_strm_q = 0;
 				}
+				if (control->on_read_q == 0) {
+					sctp_add_to_readq(stcb->sctp_ep, stcb, control,
+					    &stcb->sctp_socket->so_rcv, control->end_added,
+					    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
+				}
 				sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
 				if ((nc) && (nc->first_frag_seen)) {
 					/*
@@ -843,11 +843,11 @@ restart:
 		}
 	}
 	if ((control->length > pd_point) && (strm->pd_api_started == 0)) {
+		strm->pd_api_started = 1;
+		control->pdapi_started = 1;
 		sctp_add_to_readq(stcb->sctp_ep, stcb, control,
 		    &stcb->sctp_socket->so_rcv, control->end_added,
 		    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
-		strm->pd_api_started = 1;
-		control->pdapi_started = 1;
 		sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
 		return (0);
 	} else {
@@ -1083,16 +1083,16 @@ done_un:
 				TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
 				control->on_strm_q = 0;
 			}
+			if (strm->pd_api_started && control->pdapi_started) {
+				control->pdapi_started = 0;
+				strm->pd_api_started = 0;
+			}
 			if (control->on_read_q == 0) {
 				sctp_add_to_readq(stcb->sctp_ep, stcb,
 				    control,
 				    &stcb->sctp_socket->so_rcv, control->end_added,
 				    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
 			}
-			if (strm->pd_api_started && control->pdapi_started) {
-				control->pdapi_started = 0;
-				strm->pd_api_started = 0;
-			}
 			control = nctl;
 		}
 	}
@@ -1113,6 +1113,8 @@ deliver_more:
 		nctl = TAILQ_NEXT(control, next_instrm);
 		if ((control->sinfo_ssn == next_to_del) &&
 		    (control->first_frag_seen)) {
+			int done;
+
 			/* Ok we can deliver it onto the stream. */
 			if (control->end_added) {
 				/* We are done with it afterwards */
@@ -1147,6 +1149,7 @@ deliver_more:
 					goto out;
 				}
 			}
+			done = (control->end_added) && (control->last_frag_seen);
 			if (control->on_read_q == 0) {
 				sctp_add_to_readq(stcb->sctp_ep, stcb,
 				    control,
@@ -1154,7 +1157,7 @@ deliver_more:
 				    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
 			}
 			strm->last_sequence_delivered = next_to_del;
-			if ((control->end_added) && (control->last_frag_seen)) {
+			if (done) {
 				control = nctl;
 				goto deliver_more;
 			} else {
@@ -1248,7 +1251,7 @@ sctp_queue_data_for_reasm(struct sctp_tc
 {
 	uint32_t next_fsn;
 	struct sctp_tmit_chunk *at, *nat;
-	int cnt_added, unordered;
+	int do_wakeup, unordered;
 
 	/*
 	 * For old un-ordered data chunks.
@@ -1457,7 +1460,7 @@ sctp_queue_data_for_reasm(struct sctp_tc
 	 * Ok lets see if we can suck any up into the control structure that
 	 * are in seq if it makes sense.
 	 */
-	cnt_added = 0;
+	do_wakeup = 0;
 	/*
 	 * If the first fragment has not been seen there is no sense in
 	 * looking.
@@ -1474,7 +1477,9 @@ sctp_queue_data_for_reasm(struct sctp_tc
 				    next_fsn, control->fsn_included);
 				TAILQ_REMOVE(&control->reasm, at, sctp_next);
 				sctp_add_chk_to_control(control, strm, stcb, asoc, at);
-				cnt_added++;
+				if (control->on_read_q) {
+					do_wakeup = 1;
+				}
 				next_fsn++;
 				if (control->end_added && control->pdapi_started) {
 					if (strm->pd_api_started) {
@@ -1486,6 +1491,7 @@ sctp_queue_data_for_reasm(struct sctp_tc
 						    control,
 						    &stcb->sctp_socket->so_rcv, control->end_added,
 						    SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
+						do_wakeup = 1;
 					}
 					break;
 				}
@@ -1494,7 +1500,7 @@ sctp_queue_data_for_reasm(struct sctp_tc
 			}
 		}
 	}
-	if ((control->on_read_q) && (cnt_added > 0)) {
+	if (do_wakeup) {
 		/* Need to wakeup the reader */
 		sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
 	}
@@ -1503,29 +1509,28 @@ sctp_queue_data_for_reasm(struct sctp_tc
 static struct sctp_queued_to_read *
 find_reasm_entry(struct sctp_stream_in *strm, uint32_t msg_id, int ordered, int old)
 {
-	struct sctp_queued_to_read *reasm;
+	struct sctp_queued_to_read *control;
 
 	if (ordered) {
-		TAILQ_FOREACH(reasm, &strm->inqueue, next_instrm) {
-			if (reasm->msg_id == msg_id) {
+		TAILQ_FOREACH(control, &strm->inqueue, next_instrm) {
+			if (control->msg_id == msg_id) {
 				break;
 			}
 		}
 	} else {
 		if (old) {
-			reasm = TAILQ_FIRST(&strm->uno_inqueue);
-			return (reasm);
+			control = TAILQ_FIRST(&strm->uno_inqueue);
+			return (control);
 		}
-		TAILQ_FOREACH(reasm, &strm->uno_inqueue, next_instrm) {
-			if (reasm->msg_id == msg_id) {
+		TAILQ_FOREACH(control, &strm->uno_inqueue, next_instrm) {
+			if (control->msg_id == msg_id) {
 				break;
 			}
 		}
 	}
-	return (reasm);
+	return (control);
 }
 
-
 static int
 sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
     struct mbuf **m, int offset, int chk_length,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604271858.u3RIwlNA073653>