sctp: Fix errno in case of association setup failures
Do not report always ETIMEDOUT, but only when appropriate. In other cases report ECONNABORTED. MFC after: 3 days
This commit is contained in:
@@ -1704,7 +1704,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
|
||||
SCTP_SNPRINTF(msg, sizeof(msg), "Never sent serial number %8.8x", serial_num);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_no_unlock = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -716,6 +716,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_NOTIFY_NO_PEER_AUTH 25
|
||||
#define SCTP_NOTIFY_SENDER_DRY 26
|
||||
#define SCTP_NOTIFY_REMOTE_ERROR 27
|
||||
#define SCTP_NOTIFY_ASSOC_TIMEDOUT 28
|
||||
|
||||
/* This is the value for messages that are NOT completely
|
||||
* copied down where we will start to split the message.
|
||||
|
||||
+17
-17
@@ -444,7 +444,7 @@ sctp_abort_in_reasm(struct sctp_tcb *stcb,
|
||||
chk->data = NULL;
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_1;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, oper, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_flag = 1;
|
||||
}
|
||||
|
||||
@@ -533,7 +533,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_2;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_flag = 1;
|
||||
return;
|
||||
}
|
||||
@@ -623,7 +623,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
|
||||
sctp_clean_up_control(stcb, control);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_3;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_flag = 1;
|
||||
}
|
||||
}
|
||||
@@ -1745,7 +1745,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
*/
|
||||
op_err = sctp_generate_no_user_data_cause(tsn);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_flag = 1;
|
||||
return (0);
|
||||
}
|
||||
@@ -1811,7 +1811,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
* receiver. Send peer an ABORT!
|
||||
*/
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_flag = 1;
|
||||
return (0);
|
||||
}
|
||||
@@ -1882,7 +1882,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
err_out:
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_flag = 1;
|
||||
return (0);
|
||||
}
|
||||
@@ -2017,7 +2017,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_18;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_flag = 1;
|
||||
return (0);
|
||||
}
|
||||
@@ -2736,7 +2736,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
|
||||
SCTP_SNPRINTF(msg, sizeof(msg), "%s", "DATA chunk received when I-DATA was negotiated");
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_21;
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return (2);
|
||||
}
|
||||
if ((asoc->idata_supported == 0) &&
|
||||
@@ -2747,7 +2747,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
|
||||
SCTP_SNPRINTF(msg, sizeof(msg), "%s", "I-DATA chunk received when DATA was negotiated");
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_22;
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return (2);
|
||||
}
|
||||
if ((ch->chunk_type == SCTP_DATA) ||
|
||||
@@ -2772,7 +2772,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
|
||||
chk_length);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_23;
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return (2);
|
||||
}
|
||||
#ifdef SCTP_AUDITING_ENABLED
|
||||
@@ -2841,7 +2841,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
|
||||
SCTP_SNPRINTF(msg, sizeof(msg), "DATA chunk followed by chunk of type %2.2x",
|
||||
ch->chunk_type);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return (2);
|
||||
}
|
||||
default:
|
||||
@@ -2860,7 +2860,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
|
||||
SCTP_SNPRINTF(msg, sizeof(msg), "Chunk of length %u", chk_length);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return (2);
|
||||
}
|
||||
if (ch->chunk_type & 0x40) {
|
||||
@@ -4003,7 +4003,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
cumack, send_s);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
asoc->this_sack_highest_gap = cumack;
|
||||
@@ -4308,7 +4308,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
/* XXX */
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_28;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
|
||||
@@ -4524,7 +4524,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
cum_ack, send_s);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_29;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
/**********************/
|
||||
@@ -4985,7 +4985,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
/* XXX */
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_35;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) &&
|
||||
@@ -5533,7 +5533,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
new_cum_tsn, asoc->highest_tsn_inside_map);
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_37;
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_fwdtsn_map_over);
|
||||
|
||||
@@ -414,7 +414,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
|
||||
&nat_friendly, &cookie_found);
|
||||
if (abort_flag) {
|
||||
/* Send an abort and notify peer */
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*abort_no_unlock = 1;
|
||||
return (-1);
|
||||
}
|
||||
@@ -785,7 +785,7 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
|
||||
SCTP_FROM_SCTP_INPUT + SCTP_LOC_7);
|
||||
/* notify user of the abort and clean up... */
|
||||
sctp_abort_notification(stcb, 1, error, abort, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, true, false, error, abort, SCTP_SO_NOT_LOCKED);
|
||||
/* free the tcb */
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
|
||||
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
|
||||
@@ -1140,7 +1140,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, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, false, true, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
/* now free the asoc */
|
||||
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
|
||||
SCTP_FROM_SCTP_INPUT + SCTP_LOC_12);
|
||||
@@ -5106,7 +5106,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
SCTP_SNPRINTF(msg, sizeof(msg), "%s", "I-FORWARD-TSN chunk received when FORWARD-TSN was negotiated");
|
||||
}
|
||||
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
*offset = length;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -6631,7 +6631,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
* us.
|
||||
*/
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, m, false, SCTP_SO_NOT_LOCKED);
|
||||
/*
|
||||
* sctp_abort_an_association calls sctp_free_asoc() free
|
||||
* association will NOT free it since we incremented the
|
||||
@@ -6715,7 +6715,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
msg);
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb,
|
||||
op_err, SCTP_SO_NOT_LOCKED);
|
||||
op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
goto no_chunk_output;
|
||||
}
|
||||
@@ -9555,7 +9555,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
|
||||
msg);
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err,
|
||||
so_locked);
|
||||
false, so_locked);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_subtract_int(&stcb->asoc.refcnt, 1);
|
||||
return (SCTP_RETRAN_EXIT);
|
||||
@@ -12967,7 +12967,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
free_cnt_applied = 0;
|
||||
/* release this lock, otherwise we hang on ourselves */
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, mm, SCTP_SO_LOCKED);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb, mm, false, SCTP_SO_LOCKED);
|
||||
NET_EPOCH_EXIT(et);
|
||||
/* now relock the stcb so everything is sane */
|
||||
hold_tcblock = 0;
|
||||
@@ -13544,7 +13544,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
msg);
|
||||
NET_EPOCH_ENTER(et);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb,
|
||||
op_err, SCTP_SO_LOCKED);
|
||||
op_err, false, SCTP_SO_LOCKED);
|
||||
NET_EPOCH_EXIT(et);
|
||||
/*
|
||||
* now relock the stcb so everything
|
||||
|
||||
@@ -6198,7 +6198,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
|
||||
msg);
|
||||
sctp_abort_an_association(stcb_tmp->sctp_ep,
|
||||
stcb_tmp, op_err,
|
||||
stcb_tmp, op_err, false,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
goto add_it_now;
|
||||
}
|
||||
@@ -6298,7 +6298,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
||||
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
|
||||
msg);
|
||||
sctp_abort_an_association(stcb_tmp->sctp_ep,
|
||||
stcb_tmp, op_err,
|
||||
stcb_tmp, op_err, false,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
goto add_it_now6;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
|
||||
"Association error counter exceeded");
|
||||
inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_2;
|
||||
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);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@@ -1071,7 +1071,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
|
||||
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
|
||||
"Cookie timer expired, but no cookie");
|
||||
inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_3;
|
||||
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_an_association(inp, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("Cookie timer expires in wrong state?");
|
||||
|
||||
@@ -189,7 +189,7 @@ sctp_notify(struct sctp_inpcb *inp,
|
||||
} else if ((icmp_code == ICMP_UNREACH_PROTOCOL) ||
|
||||
(icmp_code == ICMP_UNREACH_PORT)) {
|
||||
/* Treat it like an ABORT. */
|
||||
sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, true, false, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
|
||||
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
|
||||
/* no need to unlock here, since the TCB is gone */
|
||||
@@ -960,7 +960,7 @@ sctp_shutdown(struct socket *so)
|
||||
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
sctp_abort_an_association(stcb->sctp_ep, stcb,
|
||||
op_err, SCTP_SO_LOCKED);
|
||||
op_err, false, SCTP_SO_LOCKED);
|
||||
NET_EPOCH_EXIT(et);
|
||||
return (0);
|
||||
}
|
||||
|
||||
+33
-19
@@ -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 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
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 @@ sctp_print_out_track_log(struct sctp_tcb *stcb)
|
||||
|
||||
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
|
||||
|
||||
@@ -167,7 +167,7 @@ void sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int);
|
||||
int sctp_expand_mapping_array(struct sctp_association *, uint32_t);
|
||||
|
||||
void
|
||||
sctp_abort_notification(struct sctp_tcb *, uint8_t, uint16_t,
|
||||
sctp_abort_notification(struct sctp_tcb *, bool, bool, uint16_t,
|
||||
struct sctp_abort_chunk *, int);
|
||||
|
||||
/* We abort responding to an IP packet for some reason */
|
||||
@@ -181,7 +181,7 @@ sctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *,
|
||||
/* We choose to abort via user input */
|
||||
void
|
||||
sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *,
|
||||
struct mbuf *, int);
|
||||
struct mbuf *, bool, int);
|
||||
|
||||
void
|
||||
sctp_handle_ootb(struct mbuf *, int, int,
|
||||
|
||||
@@ -200,7 +200,7 @@ sctp6_notify(struct sctp_inpcb *inp,
|
||||
case ICMP6_PARAM_PROB:
|
||||
/* Treat it like an ABORT. */
|
||||
if (icmp6_code == ICMP6_PARAMPROB_NEXTHEADER) {
|
||||
sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
sctp_abort_notification(stcb, true, false, 0, NULL, SCTP_SO_NOT_LOCKED);
|
||||
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
|
||||
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user