mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Fix a bug where HEARTBEATs were still sent in SHUTDOWN_SENT or
SHUTDOWN_ACK_SENT state. While there, make the corresponding code consistent. MFC after: 1 week
This commit is contained in:
parent
1848dd2aec
commit
c39cfa1f7e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=246588
@ -4262,19 +4262,19 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
(asoc->stream_queue_cnt == 0)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
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);
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
}
|
||||
@ -4973,11 +4973,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
} else {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
@ -4985,6 +4980,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
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);
|
||||
@ -4996,19 +4996,19 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
(asoc->stream_queue_cnt == 0)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
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);
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
if (asoc->alternate) {
|
||||
netp = asoc->alternate;
|
||||
} else {
|
||||
netp = asoc->primary_destination;
|
||||
}
|
||||
sctp_send_shutdown_ack(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
|
||||
stcb->sctp_ep, stcb, netp);
|
||||
return;
|
||||
|
@ -956,7 +956,6 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
|
||||
} else {
|
||||
/* no outstanding data to send, so move on... */
|
||||
/* send SHUTDOWN-ACK */
|
||||
sctp_send_shutdown_ack(stcb, net);
|
||||
/* move to SHUTDOWN-ACK-SENT state */
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
@ -965,6 +964,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
|
||||
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
sctp_send_shutdown_ack(stcb, net);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep,
|
||||
stcb, net);
|
||||
}
|
||||
|
@ -6574,12 +6574,13 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
* only send SHUTDOWN the first time
|
||||
* through
|
||||
*/
|
||||
sctp_send_shutdown(stcb, net);
|
||||
if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
|
||||
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);
|
||||
sctp_send_shutdown(stcb, net);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
|
||||
net);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
|
||||
@ -13092,18 +13093,19 @@ sctp_lower_sosend(struct socket *so,
|
||||
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
/* only send SHUTDOWN the first time through */
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
|
||||
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 (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->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,
|
||||
|
@ -3332,22 +3332,23 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
(SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (asoc->asoc.alternate) {
|
||||
netp = asoc->asoc.alternate;
|
||||
} else {
|
||||
netp = asoc->asoc.primary_destination;
|
||||
}
|
||||
/*
|
||||
* there is nothing queued to send,
|
||||
* so I send shutdown
|
||||
*/
|
||||
sctp_send_shutdown(asoc, netp);
|
||||
if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
|
||||
(SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
|
||||
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
|
||||
}
|
||||
SCTP_SET_STATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_SENT);
|
||||
SCTP_CLEAR_SUBSTATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_PENDING);
|
||||
sctp_stop_timers_for_shutdown(asoc);
|
||||
if (asoc->asoc.alternate) {
|
||||
netp = asoc->asoc.alternate;
|
||||
} else {
|
||||
netp = asoc->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(asoc, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, asoc->sctp_ep, asoc,
|
||||
netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,
|
||||
|
@ -1560,18 +1560,19 @@ sctp_autoclose_timer(struct sctp_inpcb *inp,
|
||||
/* only send SHUTDOWN 1st time thru */
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(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 (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
|
||||
stcb->sctp_ep, stcb,
|
||||
netp);
|
||||
|
@ -794,25 +794,24 @@ sctp_disconnect(struct socket *so)
|
||||
/* only send SHUTDOWN 1st time thru */
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
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 (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->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);
|
||||
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -1014,24 +1013,24 @@ sctp_shutdown(struct socket *so)
|
||||
/* only send SHUTDOWN the first time through */
|
||||
struct sctp_nets *netp;
|
||||
|
||||
if (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->asoc.primary_destination;
|
||||
}
|
||||
sctp_stop_timers_for_shutdown(stcb);
|
||||
sctp_send_shutdown(stcb, netp);
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
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 (stcb->asoc.alternate) {
|
||||
netp = stcb->asoc.alternate;
|
||||
} else {
|
||||
netp = stcb->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);
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user