Author: tuexen
Date: Sat Apr  7 14:44:21 2018
New Revision: 332175
URL: https://svnweb.freebsd.org/changeset/base/332175

Log:
  MFC r321289:
  
  Fix the explicit EOR mode. If the final messages is not complete, send
  an ABORT.
  Joint work with rrs@

Modified:
  stable/11/sys/netinet/sctp_indata.c
  stable/11/sys/netinet/sctp_ss_functions.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/sctp_indata.c
==============================================================================
--- stable/11/sys/netinet/sctp_indata.c Sat Apr  7 14:43:01 2018        
(r332174)
+++ stable/11/sys/netinet/sctp_indata.c Sat Apr  7 14:44:21 2018        
(r332175)
@@ -4293,47 +4293,44 @@ again:
                    ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) 
(stcb, asoc))) {
                        asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
                }
+               if (((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
+                   (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) &&
+                   (asoc->stream_queue_cnt == 1) &&
+                   (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
+                       struct mbuf *op_err;
+
+                       *abort_now = 1;
+                       /* XXX */
+                       op_err = 
sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
+                       stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA 
+ SCTP_LOC_24;
+                       sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, 
SCTP_SO_NOT_LOCKED);
+                       return;
+               }
                if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
                    (asoc->stream_queue_cnt == 0)) {
-                       if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
-                               /* Need to abort here */
-                               struct mbuf *op_err;
+                       struct sctp_nets *netp;
 
-               abort_out_now:
-                               *abort_now = 1;
-                               /* XXX */
-                               op_err = 
sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
-                               stcb->sctp_ep->last_abort_code = 
SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
-                               sctp_abort_an_association(stcb->sctp_ep, stcb, 
op_err, SCTP_SO_NOT_LOCKED);
-                               return;
+                       if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
+                           (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
+                               SCTP_STAT_DECR_GAUGE32(sctps_currestab);
+                       }
+                       SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
+                       SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
+                       sctp_stop_timers_for_shutdown(stcb);
+                       if (asoc->alternate) {
+                               netp = asoc->alternate;
                        } else {
-                               struct sctp_nets *netp;
-
-                               if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
-                                   (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
-                                       SCTP_STAT_DECR_GAUGE32(sctps_currestab);
-                               }
-                               SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
-                               SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
-                               sctp_stop_timers_for_shutdown(stcb);
-                               if (asoc->alternate) {
-                                       netp = asoc->alternate;
-                               } else {
-                                       netp = asoc->primary_destination;
-                               }
-                               sctp_send_shutdown(stcb, netp);
-                               sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
-                                   stcb->sctp_ep, stcb, netp);
-                               sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
-                                   stcb->sctp_ep, stcb, netp);
+                               netp = asoc->primary_destination;
                        }
+                       sctp_send_shutdown(stcb, netp);
+                       sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
+                           stcb->sctp_ep, stcb, netp);
+                       sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
+                           stcb->sctp_ep, stcb, netp);
                } else if ((SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED) &&
                    (asoc->stream_queue_cnt == 0)) {
                        struct sctp_nets *netp;
 
-                       if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
-                               goto abort_out_now;
-                       }
                        SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                        SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
                        SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
@@ -4989,48 +4986,45 @@ hopeless_peer:
                    ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) 
(stcb, asoc))) {
                        asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT;
                }
+               if (((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
+                   (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) &&
+                   (asoc->stream_queue_cnt == 1) &&
+                   (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
+                       struct mbuf *op_err;
+
+                       *abort_now = 1;
+                       /* XXX */
+                       op_err = 
sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
+                       stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA 
+ SCTP_LOC_24;
+                       sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, 
SCTP_SO_NOT_LOCKED);
+                       return;
+               }
                if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
                    (asoc->stream_queue_cnt == 0)) {
-                       if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
-                               /* Need to abort here */
-                               struct mbuf *op_err;
+                       struct sctp_nets *netp;
 
-               abort_out_now:
-                               *abort_now = 1;
-                               /* XXX */
-                               op_err = 
sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
-                               stcb->sctp_ep->last_abort_code = 
SCTP_FROM_SCTP_INDATA + SCTP_LOC_31;
-                               sctp_abort_an_association(stcb->sctp_ep, stcb, 
op_err, SCTP_SO_NOT_LOCKED);
-                               return;
+                       if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
+                           (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
+                               SCTP_STAT_DECR_GAUGE32(sctps_currestab);
+                       }
+                       SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
+                       SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
+                       sctp_stop_timers_for_shutdown(stcb);
+                       if (asoc->alternate) {
+                               netp = asoc->alternate;
                        } else {
-                               struct sctp_nets *netp;
-
-                               if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
-                                   (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
-                                       SCTP_STAT_DECR_GAUGE32(sctps_currestab);
-                               }
-                               SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
-                               SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
-                               sctp_stop_timers_for_shutdown(stcb);
-                               if (asoc->alternate) {
-                                       netp = asoc->alternate;
-                               } else {
-                                       netp = asoc->primary_destination;
-                               }
-                               sctp_send_shutdown(stcb, netp);
-                               sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
-                                   stcb->sctp_ep, stcb, netp);
-                               sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
-                                   stcb->sctp_ep, stcb, netp);
+                               netp = asoc->primary_destination;
                        }
+                       sctp_send_shutdown(stcb, netp);
+                       sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
+                           stcb->sctp_ep, stcb, netp);
+                       sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
+                           stcb->sctp_ep, stcb, netp);
                        return;
                } else if ((SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED) &&
                    (asoc->stream_queue_cnt == 0)) {
                        struct sctp_nets *netp;
 
-                       if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
-                               goto abort_out_now;
-                       }
                        SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                        SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
                        SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);

Modified: stable/11/sys/netinet/sctp_ss_functions.c
==============================================================================
--- stable/11/sys/netinet/sctp_ss_functions.c   Sat Apr  7 14:43:01 2018        
(r332174)
+++ stable/11/sys/netinet/sctp_ss_functions.c   Sat Apr  7 14:44:21 2018        
(r332175)
@@ -268,9 +268,23 @@ sctp_ss_default_set_value(struct sctp_tcb *stcb SCTP_U
 }
 
 static int
-sctp_ss_default_is_user_msgs_incomplete(struct sctp_tcb *stcb SCTP_UNUSED, 
struct sctp_association *asoc SCTP_UNUSED)
+sctp_ss_default_is_user_msgs_incomplete(struct sctp_tcb *stcb SCTP_UNUSED, 
struct sctp_association *asoc)
 {
-       return (0);
+       struct sctp_stream_out *strq;
+       struct sctp_stream_queue_pending *sp;
+
+       if (asoc->stream_queue_cnt != 1) {
+               return (0);
+       }
+       strq = asoc->ss_data.locked_on_sending;
+       if (strq == NULL) {
+               return (0);
+       }
+       sp = TAILQ_FIRST(&strq->outqueue);
+       if (sp == NULL) {
+               return (0);
+       }
+       return (!sp->msg_is_complete);
 }
 
 /*
_______________________________________________
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