The branch stable/13 has been updated by tuexen:

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

commit a2f048084999dca10f774412eb69839a0b0aea83
Author:     Michael Tuexen <tue...@freebsd.org>
AuthorDate: 2023-08-09 02:17:52 +0000
Commit:     Michael Tuexen <tue...@freebsd.org>
CommitDate: 2024-01-11 12:31:09 +0000

    sctp: another cleanup
    
    No functional change intended.
    
    (cherry picked from commit 85e5480df95e6bca38910f44f6e9b4d7773904ed)
---
 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 4e43c8c72f40..b28bfc66af8d 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -663,7 +663,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) {
@@ -671,134 +674,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

Reply via email to