Fix handling of SHUTDOWN-ACK chunk in COOKIE_WAIT and COOKIE_ECHOED.
MFC after: 1 week
This commit is contained in:
parent
9802380e41
commit
7b470fc31c
@ -918,7 +918,8 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
|
||||
|
||||
static void
|
||||
sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
|
||||
struct sctp_tcb *stcb, struct sctp_nets *net)
|
||||
struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net)
|
||||
{
|
||||
struct sctp_association *asoc;
|
||||
|
||||
@ -934,6 +935,13 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
|
||||
|
||||
asoc = &stcb->asoc;
|
||||
/* process according to association state */
|
||||
if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
(SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
|
||||
/* unexpected SHUTDOWN-ACK... do OOTB handling... */
|
||||
sctp_send_shutdown_complete(stcb, net, 1);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
return;
|
||||
}
|
||||
if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
|
||||
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
|
||||
/* unexpected SHUTDOWN-ACK... so ignore... */
|
||||
@ -975,7 +983,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
|
||||
/* stop the timer */
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_9);
|
||||
/* send SHUTDOWN-COMPLETE */
|
||||
sctp_send_shutdown_complete(stcb, net);
|
||||
sctp_send_shutdown_complete(stcb, net, 0);
|
||||
/* notify upper layer protocol */
|
||||
if (stcb->sctp_socket) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
|
@ -10622,27 +10622,37 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
|
||||
|
||||
void
|
||||
sctp_send_shutdown_complete(struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net)
|
||||
struct sctp_nets *net,
|
||||
int reflect_vtag)
|
||||
{
|
||||
/* formulate and SEND a SHUTDOWN-COMPLETE */
|
||||
struct mbuf *m_shutdown_comp;
|
||||
struct sctp_shutdown_complete_chunk *shutdown_complete;
|
||||
uint32_t vtag;
|
||||
uint8_t flags;
|
||||
|
||||
m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_DONTWAIT, 1, MT_HEADER);
|
||||
if (m_shutdown_comp == NULL) {
|
||||
/* no mbuf's */
|
||||
return;
|
||||
}
|
||||
if (reflect_vtag) {
|
||||
flags = SCTP_HAD_NO_TCB;
|
||||
vtag = stcb->asoc.my_vtag;
|
||||
} else {
|
||||
flags = 0;
|
||||
vtag = stcb->asoc.peer_vtag;
|
||||
}
|
||||
shutdown_complete = mtod(m_shutdown_comp, struct sctp_shutdown_complete_chunk *);
|
||||
shutdown_complete->ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
|
||||
shutdown_complete->ch.chunk_flags = 0;
|
||||
shutdown_complete->ch.chunk_flags = flags;
|
||||
shutdown_complete->ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
|
||||
SCTP_BUF_LEN(m_shutdown_comp) = sizeof(struct sctp_shutdown_complete_chunk);
|
||||
(void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
|
||||
(struct sockaddr *)&net->ro._l_addr,
|
||||
m_shutdown_comp, 0, NULL, 0, 1, 0, NULL, 0,
|
||||
stcb->sctp_ep->sctp_lport, stcb->rport,
|
||||
htonl(stcb->asoc.peer_vtag),
|
||||
htonl(vtag),
|
||||
net->port, SCTP_SO_NOT_LOCKED, NULL);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
|
||||
return;
|
||||
|
@ -111,7 +111,7 @@ void sctp_send_shutdown(struct sctp_tcb *, struct sctp_nets *);
|
||||
|
||||
void sctp_send_shutdown_ack(struct sctp_tcb *, struct sctp_nets *);
|
||||
|
||||
void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *);
|
||||
void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *, int);
|
||||
|
||||
void
|
||||
sctp_send_shutdown_complete2(struct mbuf *, int, struct sctphdr *,
|
||||
|
Loading…
Reference in New Issue
Block a user