Author: tuexen
Date: Sun Aug  7 23:04:46 2016
New Revision: 303819
URL: https://svnweb.freebsd.org/changeset/base/303819

Log:
  Consistently check for unsent data on the stream queues.
  
  MFC after:    3 days

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

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Sun Aug  7 21:23:55 2016        
(r303818)
+++ head/sys/netinet/sctp_input.c       Sun Aug  7 23:04:46 2016        
(r303819)
@@ -221,18 +221,18 @@ sctp_is_there_unsent_data(struct sctp_tc
 #endif
 )
 {
-       int unsent_data = 0;
+       int unsent_data;
        unsigned int i;
        struct sctp_stream_queue_pending *sp;
        struct sctp_association *asoc;
 
        /*
-        * This function returns the number of streams that have true unsent
-        * data on them. Note that as it looks through it will clean up any
-        * places that have old data that has been sent but left at top of
-        * stream queue.
+        * This function returns if any stream has true unsent data on it.
+        * Note that as it looks through it will clean up any places that
+        * have old data that has been sent but left at top of stream queue.
         */
        asoc = &stcb->asoc;
+       unsent_data = 0;
        SCTP_TCB_SEND_LOCK(stcb);
        if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
                /* Check to see if some data queued */
@@ -270,8 +270,13 @@ sctp_is_there_unsent_data(struct sctp_tc
                                        sp->data = NULL;
                                }
                                sctp_free_a_strmoq(stcb, sp, so_locked);
+                               if 
(!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
+                                       unsent_data++;
+                               }
                        } else {
                                unsent_data++;
+                       }
+                       if (unsent_data > 0) {
                                break;
                        }
                }
@@ -1049,7 +1054,7 @@ sctp_handle_shutdown_ack(struct sctp_shu
 #ifdef INVARIANTS
        if (!TAILQ_EMPTY(&asoc->send_queue) ||
            !TAILQ_EMPTY(&asoc->sent_queue) ||
-           !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
+           sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED)) {
                panic("Queues are not empty when handling SHUTDOWN-ACK");
        }
 #endif
@@ -3215,7 +3220,7 @@ sctp_handle_shutdown_complete(struct sct
 #ifdef INVARIANTS
        if (!TAILQ_EMPTY(&asoc->send_queue) ||
            !TAILQ_EMPTY(&asoc->sent_queue) ||
-           !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
+           sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED)) {
                panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
        }
 #endif

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c      Sun Aug  7 21:23:55 2016        
(r303818)
+++ head/sys/netinet/sctp_output.c      Sun Aug  7 23:04:46 2016        
(r303819)
@@ -6687,13 +6687,9 @@ sctp_sendall_iterator(struct sctp_inpcb 
                asoc = &stcb->asoc;
                if (ca->sndrcv.sinfo_flags & SCTP_EOF) {
                        /* shutdown this assoc */
-                       int cnt;
-
-                       cnt = sctp_is_there_unsent_data(stcb, 
SCTP_SO_NOT_LOCKED);
-
                        if (TAILQ_EMPTY(&asoc->send_queue) &&
                            TAILQ_EMPTY(&asoc->sent_queue) &&
-                           (cnt == 0)) {
+                           sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED) 
== 0) {
                                if 
((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
                                        goto abort_anyway;
                                }
@@ -7902,7 +7898,7 @@ sctp_med_chunk_output(struct sctp_inpcb 
            (asoc->ctrl_queue_cnt == stcb->asoc.ecn_echo_cnt_onq)) &&
            TAILQ_EMPTY(&asoc->asconf_send_queue) &&
            TAILQ_EMPTY(&asoc->send_queue) &&
-           stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
+           sctp_is_there_unsent_data(stcb, so_locked) == 0) {
 nothing_to_send:
                *reason_code = 9;
                return (0);
@@ -10185,7 +10181,7 @@ do_it_again:
                }
                if (TAILQ_EMPTY(&asoc->control_send_queue) &&
                    TAILQ_EMPTY(&asoc->send_queue) &&
-                   stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
+                   sctp_is_there_unsent_data(stcb, so_locked) == 0) {
                        /* Nothing left to send */
                        break;
                }
@@ -13455,18 +13451,15 @@ dataless_eof:
        /* EOF thing ? */
        if ((srcv->sinfo_flags & SCTP_EOF) &&
            (got_all_of_the_send == 1)) {
-               int cnt;
-
                SCTP_STAT_INCR(sctps_sends_with_eof);
                error = 0;
                if (hold_tcblock == 0) {
                        SCTP_TCB_LOCK(stcb);
                        hold_tcblock = 1;
                }
-               cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED);
                if (TAILQ_EMPTY(&asoc->send_queue) &&
                    TAILQ_EMPTY(&asoc->sent_queue) &&
-                   (cnt == 0)) {
+                   sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED) == 0) {
                        if 
((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
                                goto abort_anyway;
                        }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to