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,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to