mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-26 16:18:31 +00:00
Fix a locking issue showing up on Mac OS X when subscribing to
authentication events. DTLS/SCTP renegotiations trigger the bug. MFC after: 2 weeks.
This commit is contained in:
parent
9d644a4032
commit
689e6a5fa3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=221627
@ -598,7 +598,11 @@ sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t key_id)
|
||||
}
|
||||
|
||||
void
|
||||
sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id)
|
||||
sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
{
|
||||
sctp_sharedkey_t *skey;
|
||||
|
||||
@ -616,7 +620,7 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id)
|
||||
if ((skey->refcount <= 1) && (skey->deactivated)) {
|
||||
/* notify ULP that key is no longer used */
|
||||
sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb,
|
||||
key_id, 0, SCTP_SO_LOCKED);
|
||||
key_id, 0, so_locked);
|
||||
SCTPDBG(SCTP_DEBUG_AUTH2,
|
||||
"%s: stcb %p key %u no longer used, %d\n",
|
||||
__FUNCTION__, stcb, key_id, skey->refcount);
|
||||
|
@ -156,7 +156,9 @@ sctp_copy_skeylist(const struct sctp_keyhead *src,
|
||||
|
||||
/* ref counts on shared keys, by key id */
|
||||
extern void sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t keyid);
|
||||
extern void sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid);
|
||||
extern void
|
||||
sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid,
|
||||
int so_locked);
|
||||
|
||||
|
||||
/* hmac list handling */
|
||||
|
@ -375,7 +375,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
chk->data = NULL;
|
||||
}
|
||||
/* Now free the address and data */
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
}
|
||||
return;
|
||||
@ -479,7 +479,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
sctp_ucount_decr(asoc->cnt_on_reasm_queue);
|
||||
/* free up the chk */
|
||||
chk->data = NULL;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
|
||||
if (asoc->fragmented_delivery_inprogress == 0) {
|
||||
/*
|
||||
@ -1011,7 +1011,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
} else {
|
||||
last_flags = at->rec.data.rcv_flags;
|
||||
@ -2416,7 +2416,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag)
|
||||
stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
|
||||
}
|
||||
sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
|
||||
sctp_send_sack(stcb);
|
||||
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
|
||||
} else {
|
||||
int is_a_gap;
|
||||
|
||||
@ -2466,7 +2466,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag)
|
||||
* there are gaps or duplicates.
|
||||
*/
|
||||
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
|
||||
sctp_send_sack(stcb);
|
||||
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
} else {
|
||||
if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
|
||||
@ -3993,7 +3993,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
SCTP_LOG_FREE_SENT);
|
||||
}
|
||||
asoc->sent_queue_cnt--;
|
||||
sctp_free_a_chunk(stcb, tp1);
|
||||
sctp_free_a_chunk(stcb, tp1, SCTP_SO_NOT_LOCKED);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -4709,7 +4709,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
0,
|
||||
SCTP_LOG_FREE_SENT);
|
||||
}
|
||||
sctp_free_a_chunk(stcb, tp1);
|
||||
sctp_free_a_chunk(stcb, tp1, SCTP_SO_NOT_LOCKED);
|
||||
wake_him++;
|
||||
}
|
||||
if (TAILQ_EMPTY(&asoc->sent_queue) && (asoc->total_flight > 0)) {
|
||||
@ -5260,7 +5260,7 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
} else if (SCTP_SSN_GT(chk->rec.data.stream_seq, seq)) {
|
||||
/*
|
||||
* If the stream_seq is > than the purging one, we
|
||||
@ -5431,7 +5431,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
} else {
|
||||
/*
|
||||
* Ok we have gone beyond the end of the fwd-tsn's
|
||||
|
@ -193,7 +193,11 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
|
||||
*/
|
||||
|
||||
int
|
||||
sctp_is_there_unsent_data(struct sctp_tcb *stcb)
|
||||
sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
{
|
||||
int unsent_data = 0;
|
||||
unsigned int i;
|
||||
@ -242,7 +246,7 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb)
|
||||
sctp_m_freem(sp->data);
|
||||
sp->data = NULL;
|
||||
}
|
||||
sctp_free_a_strmoq(stcb, sp);
|
||||
sctp_free_a_strmoq(stcb, sp, so_locked);
|
||||
} else {
|
||||
unsent_data++;
|
||||
break;
|
||||
@ -301,7 +305,7 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb,
|
||||
chk->data = NULL;
|
||||
}
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
}
|
||||
}
|
||||
@ -323,7 +327,7 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb,
|
||||
sp->net = NULL;
|
||||
}
|
||||
/* Free the chunk */
|
||||
sctp_free_a_strmoq(stcb, sp);
|
||||
sctp_free_a_strmoq(stcb, sp, SCTP_SO_NOT_LOCKED);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
}
|
||||
}
|
||||
@ -902,7 +906,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
|
||||
}
|
||||
/* Now is there unsent data on a stream somewhere? */
|
||||
some_on_streamwheel = sctp_is_there_unsent_data(stcb);
|
||||
some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
|
||||
|
||||
if (!TAILQ_EMPTY(&asoc->send_queue) ||
|
||||
!TAILQ_EMPTY(&asoc->sent_queue) ||
|
||||
@ -3127,7 +3131,7 @@ sctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb, struct sct
|
||||
chk->data = NULL;
|
||||
}
|
||||
stcb->asoc.ctrl_queue_cnt--;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
if (override == 0) {
|
||||
break;
|
||||
}
|
||||
@ -3367,7 +3371,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
|
||||
case SCTP_SELECTIVE_ACK:
|
||||
case SCTP_NR_SELECTIVE_ACK:
|
||||
/* resend the sack */
|
||||
sctp_send_sack(stcb);
|
||||
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
|
||||
break;
|
||||
case SCTP_HEARTBEAT_REQUEST:
|
||||
/* resend a demand HB */
|
||||
@ -3376,7 +3380,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
|
||||
* Only retransmit if we KNOW we wont destroy the
|
||||
* tcb
|
||||
*/
|
||||
(void)sctp_send_hb(stcb, 1, net);
|
||||
(void)sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
break;
|
||||
case SCTP_SHUTDOWN:
|
||||
@ -3547,7 +3551,7 @@ sctp_clean_up_stream_reset(struct sctp_tcb *stcb)
|
||||
chk->data = NULL;
|
||||
}
|
||||
asoc->ctrl_queue_cnt--;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
stcb->asoc.str_reset = NULL;
|
||||
}
|
||||
@ -3987,7 +3991,7 @@ __attribute__((noinline))
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return (ret_code);
|
||||
}
|
||||
SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
|
||||
|
@ -53,7 +53,7 @@ sctp_reset_in_stream(struct sctp_tcb *stcb, int number_entries,
|
||||
uint16_t * list);
|
||||
|
||||
|
||||
int sctp_is_there_unsent_data(struct sctp_tcb *stcb);
|
||||
int sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -6178,7 +6178,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
|
||||
/* shutdown this assoc */
|
||||
int cnt;
|
||||
|
||||
cnt = sctp_is_there_unsent_data(stcb);
|
||||
cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
|
||||
|
||||
if (TAILQ_EMPTY(&asoc->send_queue) &&
|
||||
TAILQ_EMPTY(&asoc->sent_queue) &&
|
||||
@ -6425,7 +6425,7 @@ sctp_toss_old_cookies(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
chk->data = NULL;
|
||||
}
|
||||
asoc->ctrl_queue_cnt--;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6454,7 +6454,7 @@ sctp_toss_old_asconf(struct sctp_tcb *stcb)
|
||||
chk->data = NULL;
|
||||
}
|
||||
asoc->ctrl_queue_cnt--;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6553,7 +6553,11 @@ sctp_clean_up_datalist(struct sctp_tcb *stcb,
|
||||
}
|
||||
|
||||
static void
|
||||
sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct sctp_tmit_chunk *chk, *nchk;
|
||||
|
||||
@ -6580,7 +6584,7 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
asoc->ctrl_queue_cnt--;
|
||||
if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN)
|
||||
asoc->fwd_tsn_cnt--;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, so_locked);
|
||||
} else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) {
|
||||
/* special handling, we must look into the param */
|
||||
if (chk != asoc->str_reset) {
|
||||
@ -6660,7 +6664,12 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
int *locked,
|
||||
int *giveup,
|
||||
int eeor_mode,
|
||||
int *bail)
|
||||
int *bail,
|
||||
int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* Move from the stream to the send_queue keeping track of the total */
|
||||
struct sctp_association *asoc;
|
||||
@ -6731,7 +6740,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
sctp_m_freem(sp->data);
|
||||
sp->data = NULL;
|
||||
}
|
||||
sctp_free_a_strmoq(stcb, sp);
|
||||
sctp_free_a_strmoq(stcb, sp, so_locked);
|
||||
/* we can't be locked to it */
|
||||
*locked = 0;
|
||||
stcb->asoc.locked_on_sending = NULL;
|
||||
@ -6897,7 +6906,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
chk->last_mbuf = NULL;
|
||||
if (chk->data == NULL) {
|
||||
sp->some_taken = some_taken;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, so_locked);
|
||||
*bail = 1;
|
||||
to_move = 0;
|
||||
goto out_of;
|
||||
@ -7001,7 +7010,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
atomic_add_int(&sp->length, to_move);
|
||||
chk->data = NULL;
|
||||
*bail = 1;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, so_locked);
|
||||
to_move = 0;
|
||||
goto out_of;
|
||||
} else {
|
||||
@ -7018,7 +7027,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
panic("prepend failes HELP?");
|
||||
#else
|
||||
SCTP_PRINTF("prepend fails HELP?\n");
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, so_locked);
|
||||
#endif
|
||||
*bail = 1;
|
||||
to_move = 0;
|
||||
@ -7140,7 +7149,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
sctp_m_freem(sp->data);
|
||||
sp->data = NULL;
|
||||
}
|
||||
sctp_free_a_strmoq(stcb, sp);
|
||||
sctp_free_a_strmoq(stcb, sp, so_locked);
|
||||
|
||||
/* we can't be locked to it */
|
||||
*locked = 0;
|
||||
@ -7163,7 +7172,11 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
|
||||
|
||||
static void
|
||||
sctp_fill_outqueue(struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now)
|
||||
struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_stream_out *strq, *strqn;
|
||||
@ -7200,7 +7213,7 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
|
||||
giveup = 0;
|
||||
bail = 0;
|
||||
moved_how_much = sctp_move_to_outqueue(stcb, strq, goal_mtu, frag_point, &locked,
|
||||
&giveup, eeor_mode, &bail);
|
||||
&giveup, eeor_mode, &bail, so_locked);
|
||||
if (moved_how_much)
|
||||
stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved_how_much);
|
||||
|
||||
@ -7440,7 +7453,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
|
||||
sctp_log_cwnd(stcb, net, 4, SCTP_CWND_LOG_FILL_OUTQ_CALLED);
|
||||
}
|
||||
sctp_fill_outqueue(stcb, net, frag_point, eeor_mode, &quit_now);
|
||||
sctp_fill_outqueue(stcb, net, frag_point, eeor_mode, &quit_now, so_locked);
|
||||
if (quit_now) {
|
||||
/* memory alloc failure */
|
||||
no_data_chunks = 1;
|
||||
@ -8378,7 +8391,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
||||
} else {
|
||||
*reason_code = 5;
|
||||
}
|
||||
sctp_clean_up_ctl(stcb, asoc);
|
||||
sctp_clean_up_ctl(stcb, asoc, so_locked);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -8403,7 +8416,7 @@ sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
|
||||
chk->copy_by_ref = 0;
|
||||
SCTP_BUF_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_DONTWAIT);
|
||||
if (op_err == NULL) {
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
chk->send_size = 0;
|
||||
@ -8992,7 +9005,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
|
||||
return (0);
|
||||
} else {
|
||||
/* Clean up the fwd-tsn list */
|
||||
sctp_clean_up_ctl(stcb, asoc);
|
||||
sctp_clean_up_ctl(stcb, asoc, so_locked);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -9446,7 +9459,7 @@ sctp_chunk_output(struct sctp_inpcb *inp,
|
||||
* running, if so piggy-back the sack.
|
||||
*/
|
||||
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
|
||||
sctp_send_sack(stcb);
|
||||
sctp_send_sack(stcb, so_locked);
|
||||
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
|
||||
}
|
||||
while (asoc->sent_queue_retran_cnt) {
|
||||
@ -9730,7 +9743,7 @@ send_forward_tsn(struct sctp_tcb *stcb,
|
||||
chk->whoTo = NULL;
|
||||
chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
|
||||
if (chk->data == NULL) {
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
|
||||
@ -9875,7 +9888,11 @@ send_forward_tsn(struct sctp_tcb *stcb,
|
||||
}
|
||||
|
||||
void
|
||||
sctp_send_sack(struct sctp_tcb *stcb)
|
||||
sctp_send_sack(struct sctp_tcb *stcb, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/*-
|
||||
* Queue up a SACK or NR-SACK in the control queue.
|
||||
@ -10017,7 +10034,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
||||
sctp_m_freem(a_chk->data);
|
||||
a_chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, a_chk);
|
||||
sctp_free_a_chunk(stcb, a_chk, so_locked);
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
if (stcb->asoc.delayed_ack) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
|
||||
@ -10691,7 +10708,11 @@ sctp_select_hb_destination(struct sctp_tcb *stcb, struct timeval *now)
|
||||
}
|
||||
|
||||
int
|
||||
sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
|
||||
sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net, int so_locked
|
||||
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_UNUSED
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct sctp_tmit_chunk *chk;
|
||||
struct sctp_nets *net;
|
||||
@ -10747,7 +10768,7 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
|
||||
|
||||
chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
|
||||
if (chk->data == NULL) {
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, so_locked);
|
||||
return (0);
|
||||
}
|
||||
SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
|
||||
@ -10836,7 +10857,7 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
|
||||
sctp_free_remote_addr(chk->whoTo);
|
||||
chk->whoTo = NULL;
|
||||
}
|
||||
sctp_free_a_chunk((struct sctp_tcb *)NULL, chk);
|
||||
sctp_free_a_chunk((struct sctp_tcb *)NULL, chk, so_locked);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
@ -10892,7 +10913,7 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
|
||||
chk->send_size = sizeof(struct sctp_ecne_chunk);
|
||||
chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
|
||||
if (chk->data == NULL) {
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
|
||||
@ -10955,7 +10976,7 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
|
||||
chk->copy_by_ref = 0;
|
||||
iph = mtod(m, struct ip *);
|
||||
if (iph == NULL) {
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
switch (iph->ip_v) {
|
||||
@ -10995,7 +11016,7 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
|
||||
* INIT-ACK, because we can't know if the initiation
|
||||
* tag is correct or not.
|
||||
*/
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
@ -11018,7 +11039,7 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
|
||||
chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
|
||||
if (chk->data == NULL) {
|
||||
jump_out:
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
|
||||
@ -11129,7 +11150,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u
|
||||
chk->send_size = sizeof(struct sctp_cwr_chunk);
|
||||
chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
|
||||
if (chk->data == NULL) {
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
|
||||
@ -11418,7 +11439,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
|
||||
|
||||
chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
|
||||
if (chk->data == NULL) {
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_LOCKED);
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -12108,7 +12129,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
|
||||
*error = sctp_copy_one(sp, uio, resv_in_first);
|
||||
skip_copy:
|
||||
if (*error) {
|
||||
sctp_free_a_strmoq(stcb, sp);
|
||||
sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
|
||||
sp = NULL;
|
||||
} else {
|
||||
if (sp->sinfo_flags & SCTP_ADDR_OVER) {
|
||||
@ -13206,7 +13227,7 @@ sctp_lower_sosend(struct socket *so,
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
hold_tcblock = 1;
|
||||
}
|
||||
cnt = sctp_is_there_unsent_data(stcb);
|
||||
cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED);
|
||||
if (TAILQ_EMPTY(&asoc->send_queue) &&
|
||||
TAILQ_EMPTY(&asoc->sent_queue) &&
|
||||
(cnt == 0)) {
|
||||
|
@ -152,9 +152,9 @@ sctp_send_abort_tcb(struct sctp_tcb *, struct mbuf *, int
|
||||
|
||||
void send_forward_tsn(struct sctp_tcb *, struct sctp_association *);
|
||||
|
||||
void sctp_send_sack(struct sctp_tcb *);
|
||||
void sctp_send_sack(struct sctp_tcb *, int);
|
||||
|
||||
int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *);
|
||||
int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *, int);
|
||||
|
||||
void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t);
|
||||
|
||||
|
@ -4988,7 +4988,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
}
|
||||
sctp_free_spbufspace(stcb, asoc, sp);
|
||||
if (sp->holds_key_ref)
|
||||
sctp_auth_key_release(stcb, sp->auth_keyid);
|
||||
sctp_auth_key_release(stcb, sp->auth_keyid, SCTP_SO_LOCKED);
|
||||
/* Free the zone stuff */
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), sp);
|
||||
SCTP_DECR_STRMOQ_COUNT();
|
||||
@ -5021,7 +5021,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
chk->data = NULL;
|
||||
}
|
||||
if (chk->holds_key_ref)
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid);
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
SCTP_DECR_CHK_COUNT();
|
||||
atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1);
|
||||
@ -5043,7 +5043,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
}
|
||||
}
|
||||
if (chk->holds_key_ref)
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid);
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
if (chk->whoTo) {
|
||||
sctp_free_remote_addr(chk->whoTo);
|
||||
chk->whoTo = NULL;
|
||||
@ -5067,7 +5067,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
}
|
||||
}
|
||||
if (chk->holds_key_ref)
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid);
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
sctp_free_remote_addr(chk->whoTo);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
SCTP_DECR_CHK_COUNT();
|
||||
@ -5081,7 +5081,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
chk->data = NULL;
|
||||
}
|
||||
if (chk->holds_key_ref)
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid);
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
sctp_free_remote_addr(chk->whoTo);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
SCTP_DECR_CHK_COUNT();
|
||||
@ -5095,7 +5095,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
chk->data = NULL;
|
||||
}
|
||||
if (chk->holds_key_ref)
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid);
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
sctp_free_remote_addr(chk->whoTo);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
SCTP_DECR_CHK_COUNT();
|
||||
@ -5108,7 +5108,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
chk->data = NULL;
|
||||
}
|
||||
if (chk->holds_key_ref)
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid);
|
||||
sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
sctp_free_remote_addr(chk->whoTo);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
SCTP_DECR_CHK_COUNT();
|
||||
@ -6895,7 +6895,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
}
|
||||
/* Ok that was fun, now we will drain all the inbound streams? */
|
||||
@ -6958,7 +6958,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
asoc->last_revoke_count = cnt;
|
||||
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
sctp_send_sack(stcb);
|
||||
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED);
|
||||
reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb);
|
||||
reneged_at++;
|
||||
|
@ -597,7 +597,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
|
||||
}
|
||||
}
|
||||
asoc->sent_queue_cnt--;
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
}
|
||||
SCTP_PRINTF("after recover order is as follows\n");
|
||||
@ -1056,7 +1056,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
||||
* no recent feed back in an RTO or
|
||||
* more, request a RTT update
|
||||
*/
|
||||
if (sctp_send_hb(stcb, 1, net) < 0)
|
||||
if (sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED) < 0)
|
||||
/*
|
||||
* Less than 0 means we lost
|
||||
* the assoc
|
||||
@ -1120,7 +1120,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
||||
* but is in PF state, a PF-heartbeat needs to be sent
|
||||
* manually.
|
||||
*/
|
||||
if (sctp_send_hb(stcb, 1, net) < 0)
|
||||
if (sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED) < 0)
|
||||
/* Return less than 0 means we lost the association */
|
||||
return (1);
|
||||
}
|
||||
@ -1598,7 +1598,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
}
|
||||
/* Send a new HB, this will do threshold managment, pick a new dest */
|
||||
if (cnt_of_unconf == 0) {
|
||||
if (sctp_send_hb(stcb, 0, NULL) < 0) {
|
||||
if (sctp_send_hb(stcb, 0, NULL, SCTP_SO_NOT_LOCKED) < 0) {
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
@ -1620,7 +1620,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
net->src_addr_selected = 0;
|
||||
}
|
||||
}
|
||||
ret = sctp_send_hb(stcb, 1, net);
|
||||
ret = sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED);
|
||||
if (ret < 0)
|
||||
return 1;
|
||||
else if (ret == 0) {
|
||||
|
@ -3997,7 +3997,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
/************************NET SPECIFIC SET ******************/
|
||||
if (paddrp->spp_flags & SPP_HB_DEMAND) {
|
||||
/* on demand HB */
|
||||
if (sctp_send_hb(stcb, 1, net) < 0) {
|
||||
if (sctp_send_hb(stcb, 1, net, SCTP_SO_LOCKED) < 0) {
|
||||
/* asoc destroyed */
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||
error = EINVAL;
|
||||
|
@ -87,9 +87,9 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
} \
|
||||
}
|
||||
|
||||
#define sctp_free_a_strmoq(_stcb, _strmoq) { \
|
||||
#define sctp_free_a_strmoq(_stcb, _strmoq, _so_locked) { \
|
||||
if ((_strmoq)->holds_key_ref) { \
|
||||
sctp_auth_key_release(stcb, sp->auth_keyid); \
|
||||
sctp_auth_key_release(stcb, sp->auth_keyid, _so_locked); \
|
||||
(_strmoq)->holds_key_ref = 0; \
|
||||
} \
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), (_strmoq)); \
|
||||
@ -105,9 +105,9 @@ extern struct pr_usrreqs sctp_usrreqs;
|
||||
} \
|
||||
}
|
||||
|
||||
#define sctp_free_a_chunk(_stcb, _chk) { \
|
||||
#define sctp_free_a_chunk(_stcb, _chk, _so_locked) { \
|
||||
if ((_chk)->holds_key_ref) {\
|
||||
sctp_auth_key_release((_stcb), (_chk)->auth_keyid); \
|
||||
sctp_auth_key_release((_stcb), (_chk)->auth_keyid, _so_locked); \
|
||||
(_chk)->holds_key_ref = 0; \
|
||||
} \
|
||||
if (_stcb) { \
|
||||
|
@ -1634,7 +1634,7 @@ sctp_timeout_handler(void *t)
|
||||
} {
|
||||
SCTP_STAT_INCR(sctps_timosack);
|
||||
stcb->asoc.timosack++;
|
||||
sctp_send_sack(stcb);
|
||||
sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
#ifdef SCTP_AUDITING_ENABLED
|
||||
sctp_auditing(4, inp, stcb, net);
|
||||
@ -3656,7 +3656,7 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
|
||||
chk->data = NULL;
|
||||
}
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, so_locked);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
}
|
||||
/* pending send queue SHOULD be empty */
|
||||
@ -3672,7 +3672,7 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
|
||||
chk->data = NULL;
|
||||
}
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk);
|
||||
sctp_free_a_chunk(stcb, chk, so_locked);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
}
|
||||
for (i = 0; i < asoc->streamoutcnt; i++) {
|
||||
@ -3697,7 +3697,7 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
|
||||
sp->net = NULL;
|
||||
}
|
||||
/* Free the chunk */
|
||||
sctp_free_a_strmoq(stcb, sp);
|
||||
sctp_free_a_strmoq(stcb, sp, so_locked);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
}
|
||||
}
|
||||
@ -5033,7 +5033,7 @@ sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t * freed_so_far, int hold_rlock,
|
||||
goto out;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_wu_sacks_sent);
|
||||
sctp_send_sack(stcb);
|
||||
sctp_send_sack(stcb, SCTP_SO_LOCKED);
|
||||
|
||||
sctp_chunk_output(stcb->sctp_ep, stcb,
|
||||
SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
|
||||
|
Loading…
Reference in New Issue
Block a user