aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/sctp_asconf.c2
-rw-r--r--sys/netinet/sctp_constants.h1
-rw-r--r--sys/netinet/sctp_indata.c34
-rw-r--r--sys/netinet/sctp_input.c8
-rw-r--r--sys/netinet/sctp_output.c10
-rw-r--r--sys/netinet/sctp_pcb.c4
-rw-r--r--sys/netinet/sctp_timer.c4
-rw-r--r--sys/netinet/sctp_usrreq.c4
-rw-r--r--sys/netinet/sctputil.c52
-rw-r--r--sys/netinet/sctputil.h4
-rw-r--r--sys/netinet6/sctp6_usrreq.c2
11 files changed, 70 insertions, 55 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index c06ddf7b1f2e..0915e187ee40 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -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;
}
diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h
index 197b93791944..1ff3f3918ef6 100644
--- a/sys/netinet/sctp_constants.h
+++ b/sys/netinet/sctp_constants.h
@@ -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.
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 6997a0099c88..fb1327a94475 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -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 @@ again:
/* 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 @@ hopeless_peer:
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 @@ hopeless_peer:
/* 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);
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 6a0b5d41052a..ed15b81ba3e5 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -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 @@ process_control_chunks:
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);
}
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index c69db88f7d7d..e34534e80fa3 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -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 @@ dataless_eof:
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
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index ce4850469144..bdc575de615f 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -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;
}
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index 582abd8e8854..2d3836829e89 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -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?");
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 6308cabf5d63..822a8ffb534f 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -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);
}
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
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index c81633223224..3319eb4f455b 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -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,
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 09371ce249db..6f5d639e6367 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -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 {