mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-02 17:08:56 +00:00
Fix the explicit EOR mode. If the final messages is not complete, send
an ABORT. Joint work with rrs@ MFC after: 1 week
This commit is contained in:
parent
6478f3180c
commit
bbc9dfbc08
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=321289
@ -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;
|
||||
} 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);
|
||||
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);
|
||||
} 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;
|
||||
} 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);
|
||||
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);
|
||||
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);
|
||||
|
@ -268,9 +268,23 @@ sctp_ss_default_set_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_associa
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user