Use ECONNABORTED in cases where the ABORT was sent to the peer.
MFC after: 3 days
This commit is contained in:
parent
58411b0821
commit
410a3b1ef0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=235403
@ -757,7 +757,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_NOTIFY_INTERFACE_UP 4
|
||||
#define SCTP_NOTIFY_DG_FAIL 5
|
||||
#define SCTP_NOTIFY_STRDATA_ERR 6
|
||||
#define SCTP_NOTIFY_ASSOC_ABORTED 7
|
||||
#define SCTP_NOTIFY_ASSOC_LOC_ABORTED 7
|
||||
#define SCTP_NOTIFY_PEER_OPENED_STREAM 8
|
||||
#define SCTP_NOTIFY_STREAM_OPENED_OK 9
|
||||
#define SCTP_NOTIFY_ASSOC_RESTART 10
|
||||
@ -781,7 +781,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_NOTIFY_SENDER_DRY 29
|
||||
#define SCTP_NOTIFY_STR_RESET_DENIED_OUT 30
|
||||
#define SCTP_NOTIFY_STR_RESET_DENIED_IN 31
|
||||
#define SCTP_NOTIFY_MAX 31
|
||||
#define SCTP_NOTIFY_ASSOC_REM_ABORTED 32
|
||||
#define SCTP_NOTIFY_MAX 32
|
||||
|
||||
|
||||
/* This is the value for messages that are NOT completely
|
||||
|
@ -782,7 +782,7 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
|
||||
/* stop any receive timers */
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_6);
|
||||
/* notify user of the abort and clean up... */
|
||||
sctp_abort_notification(stcb, error, abort, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, 1, error, abort, SCTP_SO_NOT_LOCKED);
|
||||
/* free the tcb */
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
|
||||
@ -1173,7 +1173,7 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
|
||||
asoc->stale_cookie_count++;
|
||||
if (asoc->stale_cookie_count >
|
||||
asoc->max_init_times) {
|
||||
sctp_abort_notification(stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
/* now free the asoc */
|
||||
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
so = SCTP_INP_SO(stcb->sctp_ep);
|
||||
|
@ -283,7 +283,7 @@ sctp_notify(struct sctp_inpcb *inp,
|
||||
* now is dead. In either case treat it like a OOTB abort
|
||||
* with no TCB
|
||||
*/
|
||||
sctp_abort_notification(stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
so = SCTP_INP_SO(inp);
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
|
@ -2592,7 +2592,7 @@ 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, int so_locked
|
||||
uint16_t error, struct sctp_abort_chunk *abort, uint8_t from_peer, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
@ -2688,12 +2688,17 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
|
||||
((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
|
||||
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
|
||||
stcb->sctp_socket->so_error = ECONNREFUSED;
|
||||
if (from_peer) {
|
||||
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
|
||||
stcb->sctp_socket->so_error = ECONNREFUSED;
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
|
||||
stcb->sctp_socket->so_error = ECONNRESET;
|
||||
}
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
|
||||
stcb->sctp_socket->so_error = ECONNRESET;
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
|
||||
stcb->sctp_socket->so_error = ECONNABORTED;
|
||||
}
|
||||
}
|
||||
/* Wake ANY sleepers */
|
||||
@ -3493,7 +3498,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, so_locked);
|
||||
sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, 0, so_locked);
|
||||
stcb->asoc.assoc_up_sent = 1;
|
||||
}
|
||||
if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
|
||||
@ -3505,7 +3510,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, so_locked);
|
||||
sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, 0, so_locked);
|
||||
break;
|
||||
case SCTP_NOTIFY_INTERFACE_DOWN:
|
||||
{
|
||||
@ -3553,12 +3558,20 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
}
|
||||
case SCTP_NOTIFY_STRDATA_ERR:
|
||||
break;
|
||||
case SCTP_NOTIFY_ASSOC_ABORTED:
|
||||
case SCTP_NOTIFY_ASSOC_LOC_ABORTED:
|
||||
if ((stcb) && (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED))) {
|
||||
sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, so_locked);
|
||||
sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked);
|
||||
} else {
|
||||
sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, so_locked);
|
||||
sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked);
|
||||
}
|
||||
break;
|
||||
case SCTP_NOTIFY_ASSOC_REM_ABORTED:
|
||||
if ((stcb) && (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
|
||||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED))) {
|
||||
sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked);
|
||||
} else {
|
||||
sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked);
|
||||
}
|
||||
break;
|
||||
case SCTP_NOTIFY_PEER_OPENED_STREAM:
|
||||
@ -3566,7 +3579,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
|
||||
case SCTP_NOTIFY_STREAM_OPENED_OK:
|
||||
break;
|
||||
case SCTP_NOTIFY_ASSOC_RESTART:
|
||||
sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, so_locked);
|
||||
sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
|
||||
if (stcb->asoc.peer_supports_auth == 0) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
|
||||
NULL, so_locked);
|
||||
@ -3735,7 +3748,7 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
|
||||
}
|
||||
|
||||
void
|
||||
sctp_abort_notification(struct sctp_tcb *stcb, uint16_t error,
|
||||
sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error,
|
||||
struct sctp_abort_chunk *abort, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
@ -3757,7 +3770,11 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint16_t error,
|
||||
}
|
||||
/* Tell them we lost the asoc */
|
||||
sctp_report_all_outbound(stcb, 1, so_locked);
|
||||
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, abort, so_locked);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -3776,7 +3793,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
if (stcb != NULL) {
|
||||
/* We have a TCB to abort, send notification too */
|
||||
vtag = stcb->asoc.peer_vtag;
|
||||
sctp_abort_notification(stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
/* get the assoc vrf id and table id */
|
||||
vrf_id = stcb->asoc.vrf_id;
|
||||
stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
|
||||
@ -3899,7 +3916,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, NULL, so_locked);
|
||||
sctp_abort_notification(stcb, 0, 0, NULL, so_locked);
|
||||
}
|
||||
/* notify the peer */
|
||||
sctp_send_abort_tcb(stcb, op_err, so_locked);
|
||||
|
@ -179,7 +179,7 @@ sctp_report_all_outbound(struct sctp_tcb *, int, int
|
||||
int sctp_expand_mapping_array(struct sctp_association *, uint32_t);
|
||||
|
||||
void
|
||||
sctp_abort_notification(struct sctp_tcb *, uint16_t,
|
||||
sctp_abort_notification(struct sctp_tcb *, uint8_t, uint16_t,
|
||||
struct sctp_abort_chunk *, int
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
|
@ -439,7 +439,7 @@ sctp6_notify(struct sctp_inpcb *inp,
|
||||
* now is dead. In either case treat it like a OOTB abort
|
||||
* with no TCB
|
||||
*/
|
||||
sctp_abort_notification(stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
so = SCTP_INP_SO(inp);
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user