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:
Michael Tuexen 2011-05-08 09:11:59 +00:00
parent 9d644a4032
commit 689e6a5fa3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=221627
12 changed files with 112 additions and 81 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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)) {

View File

@ -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);

View File

@ -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++;

View File

@ -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) {

View File

@ -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;

View File

@ -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) { \

View File

@ -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);