Provide consistent error causes whenever an ABORT chunk is sent.

MFC after:	1 week
This commit is contained in:
Michael Tuexen 2015-07-27 22:35:54 +00:00
parent 7d477dc35a
commit 267dbe63a1
7 changed files with 69 additions and 23 deletions

View File

@ -1680,8 +1680,14 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
* abort the asoc, since someone probably just hijacked us... * abort the asoc, since someone probably just hijacked us...
*/ */
if (serial_num == (asoc->asconf_seq_out + 1)) { if (serial_num == (asoc->asconf_seq_out + 1)) {
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n"); SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
sctp_abort_an_association(stcb->sctp_ep, stcb, NULL, SCTP_SO_NOT_LOCKED); 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);
*abort_no_unlock = 1; *abort_no_unlock = 1;
return; return;
} }

View File

@ -2488,8 +2488,11 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
*/ */
if (SCTP_BASE_SYSCTL(sctp_strict_data_order)) { if (SCTP_BASE_SYSCTL(sctp_strict_data_order)) {
struct mbuf *op_err; struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, ""); snprintf(msg, sizeof(msg), "DATA chunk followwd by chunk of type %2.2x",
ch->ch.chunk_type);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
sctp_abort_association(inp, stcb, sctp_abort_association(inp, stcb,
m, iphlen, m, iphlen,
src, dst, src, dst,

View File

@ -4624,7 +4624,7 @@ __attribute__((noinline))
} }
} }
if (stcb == NULL) { if (stcb == NULL) {
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg); msg);
/* no association, so it's out of the blue... */ /* no association, so it's out of the blue... */
@ -4668,7 +4668,7 @@ __attribute__((noinline))
if (locked_tcb) { if (locked_tcb) {
SCTP_TCB_UNLOCK(locked_tcb); SCTP_TCB_UNLOCK(locked_tcb);
} }
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg); msg);
sctp_handle_ootb(m, iphlen, *offset, src, dst, sctp_handle_ootb(m, iphlen, *offset, src, dst,
@ -5834,7 +5834,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
*/ */
SCTP_TCB_UNLOCK(stcb); SCTP_TCB_UNLOCK(stcb);
stcb = NULL; stcb = NULL;
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg); msg);
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
@ -5886,7 +5886,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
} }
if (stcb == NULL) { if (stcb == NULL) {
/* out of the blue DATA chunk */ /* out of the blue DATA chunk */
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg); msg);
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
@ -5958,7 +5958,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
/* /*
* We consider OOTB any data sent during asoc setup. * We consider OOTB any data sent during asoc setup.
*/ */
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg); msg);
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,

View File

@ -5524,7 +5524,7 @@ do_a_abort:
if (op_err == NULL) { if (op_err == NULL) {
char msg[SCTP_DIAG_INFO_LEN]; char msg[SCTP_DIAG_INFO_LEN];
snprintf(msg, sizeof(msg), "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); snprintf(msg, sizeof(msg), "%s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg); msg);
} }
@ -6682,10 +6682,17 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
if (TAILQ_EMPTY(&asoc->send_queue) && if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) && TAILQ_EMPTY(&asoc->sent_queue) &&
(asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
abort_anyway: abort_anyway:
snprintf(msg, sizeof(msg),
"%s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
atomic_add_int(&stcb->asoc.refcnt, 1); atomic_add_int(&stcb->asoc.refcnt, 1);
sctp_abort_an_association(stcb->sctp_ep, stcb, sctp_abort_an_association(stcb->sctp_ep, stcb,
NULL, SCTP_SO_NOT_LOCKED); op_err, SCTP_SO_NOT_LOCKED);
atomic_add_int(&stcb->asoc.refcnt, -1); atomic_add_int(&stcb->asoc.refcnt, -1);
goto no_chunk_output; goto no_chunk_output;
} }
@ -9454,12 +9461,16 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
} }
if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) && if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) &&
(chk->snd_count >= SCTP_BASE_SYSCTL(sctp_max_retran_chunk))) { (chk->snd_count >= SCTP_BASE_SYSCTL(sctp_max_retran_chunk))) {
/* Gak, we have exceeded max unlucky retran, abort! */ struct mbuf *op_err;
SCTP_PRINTF("Gak, chk->snd_count:%d >= max:%d - send abort\n", char msg[SCTP_DIAG_INFO_LEN];
chk->snd_count,
SCTP_BASE_SYSCTL(sctp_max_retran_chunk)); snprintf(msg, sizeof(msg), "TSN %8.8x retransmitted %d times, giving up",
chk->rec.data.TSN_seq, chk->snd_count);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
atomic_add_int(&stcb->asoc.refcnt, 1); atomic_add_int(&stcb->asoc.refcnt, 1);
sctp_abort_an_association(stcb->sctp_ep, stcb, NULL, so_locked); sctp_abort_an_association(stcb->sctp_ep, stcb, op_err,
so_locked);
SCTP_TCB_LOCK(stcb); SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1); atomic_subtract_int(&stcb->asoc.refcnt, 1);
return (SCTP_RETRAN_EXIT); return (SCTP_RETRAN_EXIT);
@ -13344,13 +13355,20 @@ dataless_eof:
if (TAILQ_EMPTY(&asoc->send_queue) && if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) && TAILQ_EMPTY(&asoc->sent_queue) &&
(asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
abort_anyway: abort_anyway:
if (free_cnt_applied) { if (free_cnt_applied) {
atomic_add_int(&stcb->asoc.refcnt, -1); atomic_add_int(&stcb->asoc.refcnt, -1);
free_cnt_applied = 0; free_cnt_applied = 0;
} }
snprintf(msg, sizeof(msg),
"%s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
sctp_abort_an_association(stcb->sctp_ep, stcb, sctp_abort_an_association(stcb->sctp_ep, stcb,
NULL, SCTP_SO_LOCKED); op_err, SCTP_SO_LOCKED);
/* /*
* now relock the stcb so everything * now relock the stcb so everything
* is sane * is sane

View File

@ -6250,12 +6250,20 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
*/ */
if (stcb_tmp) { if (stcb_tmp) {
if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) { if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) {
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
/* /*
* in setup state we * in setup state we
* abort this guy * abort this guy
*/ */
snprintf(msg, sizeof(msg),
"%s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
sctp_abort_an_association(stcb_tmp->sctp_ep, sctp_abort_an_association(stcb_tmp->sctp_ep,
stcb_tmp, NULL, SCTP_SO_NOT_LOCKED); stcb_tmp, op_err,
SCTP_SO_NOT_LOCKED);
goto add_it_now; goto add_it_now;
} }
SCTP_TCB_UNLOCK(stcb_tmp); SCTP_TCB_UNLOCK(stcb_tmp);
@ -6339,18 +6347,26 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
* strange, address is in another * strange, address is in another
* assoc? straighten out locks. * assoc? straighten out locks.
*/ */
if (stcb_tmp) if (stcb_tmp) {
if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) { if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) {
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
/* /*
* in setup state we * in setup state we
* abort this guy * abort this guy
*/ */
snprintf(msg, sizeof(msg),
"%s:%d at %s", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
sctp_abort_an_association(stcb_tmp->sctp_ep, sctp_abort_an_association(stcb_tmp->sctp_ep,
stcb_tmp, NULL, SCTP_SO_NOT_LOCKED); stcb_tmp, op_err,
SCTP_SO_NOT_LOCKED);
goto add_it_now6; goto add_it_now6;
} }
SCTP_TCB_UNLOCK(stcb_tmp); SCTP_TCB_UNLOCK(stcb_tmp);
}
if (stcb->asoc.state == 0) { if (stcb->asoc.state == 0) {
/* the assoc was freed? */ /* the assoc was freed? */
return (-21); return (-21);

View File

@ -153,7 +153,7 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* Abort notification sends a ULP notify */ /* Abort notification sends a ULP notify */
struct mbuf *op_err; struct mbuf *op_err;
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Association error counter exceeded"); "Association error counter exceeded");
inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_2; 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, SCTP_SO_NOT_LOCKED);
@ -1046,7 +1046,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
/* FOOBAR! */ /* FOOBAR! */
struct mbuf *op_err; struct mbuf *op_err;
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Cookie timer expired, but no cookie"); "Cookie timer expired, but no cookie");
inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_3; 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, SCTP_SO_NOT_LOCKED);

View File

@ -1445,6 +1445,7 @@ sctp_timeout_handler(void *t)
struct sctp_tcb *stcb; struct sctp_tcb *stcb;
struct sctp_nets *net; struct sctp_nets *net;
struct sctp_timer *tmr; struct sctp_timer *tmr;
struct mbuf *op_err;
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so; struct socket *so;
@ -1756,7 +1757,9 @@ sctp_timeout_handler(void *t)
break; break;
} }
SCTP_STAT_INCR(sctps_timoshutdownguard); SCTP_STAT_INCR(sctps_timoshutdownguard);
sctp_abort_an_association(inp, stcb, NULL, SCTP_SO_NOT_LOCKED); 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);
/* no need to unlock on tcb its gone */ /* no need to unlock on tcb its gone */
goto out_decr; goto out_decr;