diff options
| author | Michael Tuexen <tuexen@FreeBSD.org> | 2021-07-09 21:17:35 +0000 |
|---|---|---|
| committer | Michael Tuexen <tuexen@FreeBSD.org> | 2021-07-09 21:19:25 +0000 |
| commit | 105b68b42dd11bce5c554b1ef0ddf73aa069d7da (patch) | |
| tree | b5abcb3da01486d91cfdd5bd2ab4ab8cd9c84816 /sys/netinet/sctputil.c | |
| parent | 82626fef6253a9172163df137097f54e93e3c209 (diff) | |
Diffstat (limited to 'sys/netinet/sctputil.c')
| -rw-r--r-- | sys/netinet/sctputil.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 21e49bdfcb23..ad4409f666df 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1998,7 +1998,7 @@ sctp_timeout_handler(void *t) SCTP_STAT_INCR(sctps_timoshutdownguard); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), "Shutdown guard timer expired"); - sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(inp, stcb, op_err, true, SCTP_SO_NOT_LOCKED); /* no need to unlock on tcb its gone */ goto out_decr; case SCTP_TIMER_TYPE_AUTOCLOSE: @@ -3154,7 +3154,8 @@ sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf) static void sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, - uint16_t error, struct sctp_abort_chunk *abort, uint8_t from_peer, int so_locked) + uint16_t error, struct sctp_abort_chunk *abort, + bool from_peer, bool timedout, int so_locked) { struct mbuf *m_notify; struct sctp_assoc_change *sac; @@ -3163,8 +3164,10 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, uint16_t abort_len; unsigned int i; - KASSERT((abort == NULL) || (from_peer != 0), + KASSERT(abort == NULL || from_peer, ("sctp_notify_assoc_change: ABORT chunk provided for local termination")); + KASSERT(!from_peer || !timedout, + ("sctp_notify_assoc_change: timeouts can only be local")); if (stcb == NULL) { return; } @@ -3272,8 +3275,7 @@ set_error: stcb->sctp_socket->so_error = ECONNRESET; } } else { - if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || - (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { + if (timedout) { SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT); stcb->sctp_socket->so_error = ETIMEDOUT; } else { @@ -4085,7 +4087,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, switch (notification) { case SCTP_NOTIFY_ASSOC_UP: if (stcb->asoc.assoc_up_sent == 0) { - sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, 0, so_locked); + sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, false, false, so_locked); stcb->asoc.assoc_up_sent = 1; } if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) { @@ -4097,7 +4099,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, } break; case SCTP_NOTIFY_ASSOC_DOWN: - sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, 0, so_locked); + sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, false, false, so_locked); break; case SCTP_NOTIFY_INTERFACE_DOWN: { @@ -4150,21 +4152,29 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, case SCTP_NOTIFY_ASSOC_LOC_ABORTED: if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { - sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked); + sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, false, false, so_locked); } else { - sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked); + sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, false, false, so_locked); } break; case SCTP_NOTIFY_ASSOC_REM_ABORTED: if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { - sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked); + sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, true, false, so_locked); } else { - sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked); + sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, true, false, so_locked); + } + break; + case SCTP_NOTIFY_ASSOC_TIMEDOUT: + if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || + (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { + sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, false, true, so_locked); + } else { + sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, false, true, so_locked); } break; case SCTP_NOTIFY_ASSOC_RESTART: - sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked); + sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, false, false, so_locked); if (stcb->asoc.auth_supported == 0) { sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0, NULL, so_locked); @@ -4337,8 +4347,9 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int so_locked) } void -sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error, - struct sctp_abort_chunk *abort, int so_locked) +sctp_abort_notification(struct sctp_tcb *stcb, bool from_peer, bool timeout, + uint16_t error, struct sctp_abort_chunk *abort, + int so_locked) { if (stcb == NULL) { return; @@ -4361,7 +4372,11 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error if (from_peer) { sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked); } else { - sctp_ulp_notify(SCTP_NOTIFY_ASSOC_LOC_ABORTED, stcb, error, abort, so_locked); + if (timeout) { + sctp_ulp_notify(SCTP_NOTIFY_ASSOC_TIMEDOUT, stcb, error, abort, so_locked); + } else { + sctp_ulp_notify(SCTP_NOTIFY_ASSOC_LOC_ABORTED, stcb, error, abort, so_locked); + } } } @@ -4395,7 +4410,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, vrf_id, port); if (stcb != NULL) { /* We have a TCB to abort, send notification too */ - sctp_abort_notification(stcb, 0, cause_code, NULL, SCTP_SO_NOT_LOCKED); + sctp_abort_notification(stcb, false, false, cause_code, NULL, SCTP_SO_NOT_LOCKED); /* Ok, now lets free it */ SCTP_STAT_INCR_COUNTER32(sctps_aborted); if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) || @@ -4471,8 +4486,7 @@ none_in: void sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, - struct mbuf *op_err, - int so_locked) + struct mbuf *op_err, bool timedout, int so_locked) { struct sctp_gen_error_cause *cause; uint16_t cause_code; @@ -4503,7 +4517,7 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, } /* notify the ulp */ if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { - sctp_abort_notification(stcb, 0, cause_code, NULL, so_locked); + sctp_abort_notification(stcb, false, timedout, cause_code, NULL, so_locked); } /* now free the asoc */ #ifdef SCTP_ASOCLOG_OF_TSNS |
