svn commit: r321289 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Thu Jul 20 11:09:35 UTC 2017
Author: tuexen
Date: Thu Jul 20 11:09:33 2017
New Revision: 321289
URL: https://svnweb.freebsd.org/changeset/base/321289
Log:
Fix the explicit EOR mode. If the final messages is not complete, send
an ABORT.
Joint work with rrs@
MFC after: 1 week
Modified:
head/sys/netinet/sctp_indata.c
head/sys/netinet/sctp_ss_functions.c
Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c Thu Jul 20 09:35:39 2017 (r321288)
+++ head/sys/netinet/sctp_indata.c Thu Jul 20 11:09:33 2017 (r321289)
@@ -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: head/sys/netinet/sctp_ss_functions.c
==============================================================================
--- head/sys/netinet/sctp_ss_functions.c Thu Jul 20 09:35:39 2017 (r321288)
+++ head/sys/netinet/sctp_ss_functions.c Thu Jul 20 11:09:33 2017 (r321289)
@@ -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);
}
/*
More information about the svn-src-all
mailing list