From 70f0a601dffbb2c9aaddaae40df8e9fdd7a4df8e Mon Sep 17 00:00:00 2001 From: rrs Date: Sat, 17 Apr 2010 04:08:51 +0000 Subject: [PATCH] MFC of 204141 Cleans up so we can have a vtag reflected argument. One of Michaels fixes ;-) --- sys/netinet/sctp_input.c | 12 ++++++++++-- sys/netinet/sctp_output.c | 16 +++++++++++++--- sys/netinet/sctp_output.h | 2 +- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index d211e9ab7d4..ef187377b95 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -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); diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 4afe0099e05..be4c3a8633f 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -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; diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index ce76febda06..bd40a0b1f09 100644 --- a/sys/netinet/sctp_output.h +++ b/sys/netinet/sctp_output.h @@ -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 *, -- 2.45.2