summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2011-05-08 09:11:59 +0000
committertuexen <tuexen@FreeBSD.org>2011-05-08 09:11:59 +0000
commitf237c9d1bd2c10286b14fbc7c53110782a9ec164 (patch)
tree66156b7445130d0f2286124ccd8bbde0ba209ba4 /sys
parentb5e32df2e047c30254644ec28a836794b00a4e48 (diff)
downloadFreeBSD-src-f237c9d1bd2c10286b14fbc7c53110782a9ec164.zip
FreeBSD-src-f237c9d1bd2c10286b14fbc7c53110782a9ec164.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/sctp_auth.c8
-rw-r--r--sys/netinet/sctp_auth.h4
-rw-r--r--sys/netinet/sctp_indata.c18
-rw-r--r--sys/netinet/sctp_input.c24
-rw-r--r--sys/netinet/sctp_input.h2
-rw-r--r--sys/netinet/sctp_output.c85
-rw-r--r--sys/netinet/sctp_output.h4
-rw-r--r--sys/netinet/sctp_pcb.c18
-rw-r--r--sys/netinet/sctp_timer.c10
-rw-r--r--sys/netinet/sctp_usrreq.c2
-rw-r--r--sys/netinet/sctp_var.h8
-rw-r--r--sys/netinet/sctputil.c10
12 files changed, 112 insertions, 81 deletions
diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c
index eb5a77b..91e3f78 100644
--- a/sys/netinet/sctp_auth.c
+++ b/sys/netinet/sctp_auth.c
@@ -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);
diff --git a/sys/netinet/sctp_auth.h b/sys/netinet/sctp_auth.h
index 9406ce8..e3600d8 100644
--- a/sys/netinet/sctp_auth.h
+++ b/sys/netinet/sctp_auth.h
@@ -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 */
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 6ea4669..9734aea 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -375,7 +375,7 @@ abandon:
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 @@ abandon:
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
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 63771d7..4c4d779 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -193,7 +193,11 @@ outnow:
*/
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 @@ strres_nochunk:
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);
diff --git a/sys/netinet/sctp_input.h b/sys/netinet/sctp_input.h
index 95b4bd7..fe7bf77 100644
--- a/sys/netinet/sctp_input.h
+++ b/sys/netinet/sctp_input.h
@@ -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
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 1e16b99..60de83e 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -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 @@ all_done:
}
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 @@ one_more_time:
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 @@ dont_do_it:
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 @@ dont_do_it:
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 @@ dont_do_it:
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 @@ dont_do_it:
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 @@ out_of:
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 @@ nothing_to_send:
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 @@ no_data_fill:
} 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 @@ sctp_fill_in_rest:
}
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 @@ dataless_eof:
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)) {
diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h
index fc8bc62..835a377 100644
--- a/sys/netinet/sctp_output.h
+++ b/sys/netinet/sctp_output.h
@@ -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);
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index b7c8dc6..e53e28a 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -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++;
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index bccf7df..133af4a 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -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) {
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 734d92b..c9fad80 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -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;
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
index c972a16..1e17900 100644
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -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) { \
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 974aa62..39df039 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -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);
OpenPOWER on IntegriCloud