git: 85e5480df95e - main - sctp: another cleanup

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Wed, 09 Aug 2023 08:27:55 UTC
The branch main has been updated by tuexen:

URL: https://cgit.FreeBSD.org/src/commit/?id=85e5480df95e6bca38910f44f6e9b4d7773904ed

commit 85e5480df95e6bca38910f44f6e9b4d7773904ed
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2023-08-09 02:17:52 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2023-08-09 02:17:52 +0000

    sctp: another cleanup
    
    No functional change intended.
    
    MFC after:      1 week
---
 sys/netinet/sctp_usrreq.c | 226 ++++++++++++++++++++++------------------------
 1 file changed, 106 insertions(+), 120 deletions(-)

diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 5bbb32534ff0..022ff0265a7e 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -653,7 +653,10 @@ connected_type:
 int
 sctp_disconnect(struct socket *so)
 {
+	struct epoch_tracker et;
 	struct sctp_inpcb *inp;
+	struct sctp_association *asoc;
+	struct sctp_tcb *stcb;
 
 	inp = (struct sctp_inpcb *)so->so_pcb;
 	if (inp == NULL) {
@@ -661,134 +664,117 @@ sctp_disconnect(struct socket *so)
 		return (ENOTCONN);
 	}
 	SCTP_INP_RLOCK(inp);
-	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
-	    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
-		if (LIST_EMPTY(&inp->sctp_asoc_list)) {
-			/* No connection */
-			SCTP_INP_RUNLOCK(inp);
-			return (0);
-		} else {
-			struct epoch_tracker et;
-			struct sctp_association *asoc;
-			struct sctp_tcb *stcb;
-
-			stcb = LIST_FIRST(&inp->sctp_asoc_list);
-			if (stcb == NULL) {
-				SCTP_INP_RUNLOCK(inp);
-				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
-				return (EINVAL);
-			}
-			SCTP_TCB_LOCK(stcb);
-			asoc = &stcb->asoc;
-			if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
-				/* We are about to be freed, out of here */
-				SCTP_TCB_UNLOCK(stcb);
-				SCTP_INP_RUNLOCK(inp);
-				return (0);
-			}
-			NET_EPOCH_ENTER(et);
-			if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
-			    (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
-				if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) {
-					/* Left with Data unread */
-					struct mbuf *op_err;
+	KASSERT(inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE ||
+	    inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL,
+	    ("Not a one-to-one style socket"));
+	stcb = LIST_FIRST(&inp->sctp_asoc_list);
+	if (stcb == NULL) {
+		SCTP_INP_RUNLOCK(inp);
+		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
+		return (ENOTCONN);
+	}
+	SCTP_TCB_LOCK(stcb);
+	asoc = &stcb->asoc;
+	if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+		/* We are about to be freed, out of here */
+		SCTP_TCB_UNLOCK(stcb);
+		SCTP_INP_RUNLOCK(inp);
+		return (0);
+	}
+	NET_EPOCH_ENTER(et);
+	if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
+	    (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
+		if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) {
+			/* Left with Data unread */
+			struct mbuf *op_err;
 
-					op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
-					sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
-					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
-				}
-				SCTP_INP_RUNLOCK(inp);
-				if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
-				    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
-					SCTP_STAT_DECR_GAUGE32(sctps_currestab);
-				}
-				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
-				    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
-				/* No unlock tcb assoc is gone */
-				NET_EPOCH_EXIT(et);
-				return (0);
+			op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
+			sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
+			SCTP_STAT_INCR_COUNTER32(sctps_aborted);
+		}
+		SCTP_INP_RUNLOCK(inp);
+		if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
+		    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
+			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
+		}
+		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+		    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
+		/* No unlock tcb assoc is gone */
+		NET_EPOCH_EXIT(et);
+		return (0);
+	}
+	if (TAILQ_EMPTY(&asoc->send_queue) &&
+	    TAILQ_EMPTY(&asoc->sent_queue) &&
+	    (asoc->stream_queue_cnt == 0)) {
+		/* there is nothing queued to send, so done */
+		if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
+			goto abort_anyway;
+		}
+		if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) &&
+		    (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
+			/* only send SHUTDOWN 1st time thru */
+			struct sctp_nets *netp;
+
+			if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
+			    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
+				SCTP_STAT_DECR_GAUGE32(sctps_currestab);
 			}
-			if (TAILQ_EMPTY(&asoc->send_queue) &&
-			    TAILQ_EMPTY(&asoc->sent_queue) &&
-			    (asoc->stream_queue_cnt == 0)) {
-				/* there is nothing queued to send, so done */
-				if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
-					goto abort_anyway;
-				}
-				if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) &&
-				    (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
-					/* only send SHUTDOWN 1st time thru */
-					struct sctp_nets *netp;
-
-					if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
-					    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
-						SCTP_STAT_DECR_GAUGE32(sctps_currestab);
-					}
-					SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
-					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, NULL);
-					sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
-				}
+			SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
+			sctp_stop_timers_for_shutdown(stcb);
+			if (stcb->asoc.alternate) {
+				netp = stcb->asoc.alternate;
 			} else {
-				/*
-				 * we still got (or just got) data to send,
-				 * so set SHUTDOWN_PENDING
-				 */
-				/*
-				 * XXX sockets draft says that SCTP_EOF
-				 * should be sent with no data. currently,
-				 * we will allow user data to be sent first
-				 * and move to SHUTDOWN-PENDING
-				 */
-				SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
-				if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
-					SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
-				}
-				if (TAILQ_EMPTY(&asoc->send_queue) &&
-				    TAILQ_EMPTY(&asoc->sent_queue) &&
-				    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
-					struct mbuf *op_err;
-
-			abort_anyway:
-					op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
-					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
-					sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
-					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
-					if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
-					    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
-						SCTP_STAT_DECR_GAUGE32(sctps_currestab);
-					}
-					SCTP_INP_RUNLOCK(inp);
-					(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
-					    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
-					NET_EPOCH_EXIT(et);
-					return (0);
-				} else {
-					sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
-				}
+				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, NULL);
+			sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
+		}
+	} else {
+		/*
+		 * we still got (or just got) data to send, so set
+		 * SHUTDOWN_PENDING
+		 */
+		/*
+		 * XXX sockets draft says that SCTP_EOF should be sent with
+		 * no data. currently, we will allow user data to be sent
+		 * first and move to SHUTDOWN-PENDING
+		 */
+		SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
+		if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
+			SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
+		}
+		if (TAILQ_EMPTY(&asoc->send_queue) &&
+		    TAILQ_EMPTY(&asoc->sent_queue) &&
+		    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
+			struct mbuf *op_err;
+
+	abort_anyway:
+			op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
+			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
+			sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
+			SCTP_STAT_INCR_COUNTER32(sctps_aborted);
+			if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
+			    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
+				SCTP_STAT_DECR_GAUGE32(sctps_currestab);
 			}
-			soisdisconnecting(so);
-			NET_EPOCH_EXIT(et);
-			SCTP_TCB_UNLOCK(stcb);
 			SCTP_INP_RUNLOCK(inp);
+			(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+			    SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
+			NET_EPOCH_EXIT(et);
 			return (0);
+		} else {
+			sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
 		}
-		/* not reached */
-	} else {
-		/* UDP model does not support this */
-		SCTP_INP_RUNLOCK(inp);
-		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
-		return (EOPNOTSUPP);
 	}
+	soisdisconnecting(so);
+	NET_EPOCH_EXIT(et);
+	SCTP_TCB_UNLOCK(stcb);
+	SCTP_INP_RUNLOCK(inp);
+	return (0);
 }
 
 int