git: e40d16ad6ee9 - main - sctp: cleanup
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 25 Aug 2023 15:34:16 UTC
The branch main has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=e40d16ad6ee952f315356ef091fa282f28fac0d5 commit e40d16ad6ee952f315356ef091fa282f28fac0d5 Author: Michael Tuexen <tuexen@FreeBSD.org> AuthorDate: 2023-08-25 15:31:19 +0000 Commit: Michael Tuexen <tuexen@FreeBSD.org> CommitDate: 2023-08-25 15:31:19 +0000 sctp: cleanup In particular, don't use a socket level flag, use the inp level one. After adding appropriate locking, this will close a race condition. MFC after: 1 week --- sys/netinet/sctputil.c | 60 +++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 2f021c22165e..381f67f40b99 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -4054,14 +4054,14 @@ void sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, uint32_t error, void *data, int so_locked) { - if ((stcb == NULL) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || - (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { - /* If the socket is gone we are out of here */ - return; - } - if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) { + struct sctp_inpcb *inp; + struct sctp_nets *net; + + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + + inp = stcb->sctp_ep; + if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { return; } if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || @@ -4073,6 +4073,12 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, return; } } + if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ)) { + return; + } + switch (notification) { case SCTP_NOTIFY_ASSOC_UP: if (stcb->asoc.assoc_up_sent == 0) { @@ -4091,32 +4097,20 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, false, false, so_locked); break; case SCTP_NOTIFY_INTERFACE_DOWN: - { - struct sctp_nets *net; - - net = (struct sctp_nets *)data; - sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE, - (struct sockaddr *)&net->ro._l_addr, error, so_locked); - break; - } + net = (struct sctp_nets *)data; + sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE, + &net->ro._l_addr.sa, error, so_locked); + break; case SCTP_NOTIFY_INTERFACE_UP: - { - struct sctp_nets *net; - - net = (struct sctp_nets *)data; - sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE, - (struct sockaddr *)&net->ro._l_addr, error, so_locked); - break; - } + net = (struct sctp_nets *)data; + sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE, + &net->ro._l_addr.sa, error, so_locked); + break; case SCTP_NOTIFY_INTERFACE_CONFIRMED: - { - struct sctp_nets *net; - - net = (struct sctp_nets *)data; - sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED, - (struct sockaddr *)&net->ro._l_addr, error, so_locked); - break; - } + net = (struct sctp_nets *)data; + sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED, + &net->ro._l_addr.sa, error, so_locked); + break; case SCTP_NOTIFY_SPECIAL_SP_FAIL: sctp_notify_send_failed2(stcb, error, (struct sctp_stream_queue_pending *)data, so_locked); @@ -4227,7 +4221,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n", __func__, notification, notification); break; - } /* end switch */ + } } void