sflt_notify(so, sock_evt_connected, NULL);
if (head && (so->so_state & SS_INCOMP)) {
- if (head->so_proto->pr_getlock != NULL)
+ so->so_state &= ~SS_INCOMP;
+ so->so_state |= SS_COMP;
+ if (head->so_proto->pr_getlock != NULL) {
+ socket_unlock(so, 0);
socket_lock(head, 1);
+ }
postevent(head, 0, EV_RCONN);
TAILQ_REMOVE(&head->so_incomp, so, so_list);
head->so_incqlen--;
- so->so_state &= ~SS_INCOMP;
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
- so->so_state |= SS_COMP;
sorwakeup(head);
wakeup_one((caddr_t)&head->so_timeo);
- if (head->so_proto->pr_getlock != NULL)
+ if (head->so_proto->pr_getlock != NULL) {
socket_unlock(head, 1);
+ socket_lock(so, 0);
+ }
} else {
postevent(so, 0, EV_WCONN);
wakeup((caddr_t)&so->so_timeo);
}
/*
- * Must be done with head unlocked to avoid deadlock with pcb list
+ * Must be done with head unlocked to avoid deadlock for protocol with per socket mutexes.
*/
- socket_unlock(head, 0);
+ if (head->so_proto->pr_unlock)
+ socket_unlock(head, 0);
if (((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL) != 0) || error) {
sflt_termsock(so);
sodealloc(so);
- socket_lock(head, 0);
+ if (head->so_proto->pr_unlock)
+ socket_lock(head, 0);
return ((struct socket *)0);
}
- socket_lock(head, 0);
+ if (head->so_proto->pr_unlock)
+ socket_lock(head, 0);
#ifdef __APPLE__
so->so_proto->pr_domain->dom_refs++;
#endif
register struct mbuf *n, *sb_first;
int result = 0;
int error = 0;
+ int filtered = 0;
KERNEL_DEBUG((DBG_FNC_SBAPPEND | DBG_FUNC_START), sb, m->m_len, 0, 0, 0);
if (m == 0)
return 0;
+
+again:
sb_first = n = sb->sb_mb;
if (n) {
while (n->m_nextpkt)
} while (n->m_next && (n = n->m_next));
}
- if ((sb->sb_flags & SB_RECV) != 0) {
- error = sflt_data_in(sb->sb_so, NULL, &m, NULL, 0);
+ if (!filtered && (sb->sb_flags & SB_RECV) != 0) {
+ error = sflt_data_in(sb->sb_so, NULL, &m, NULL, 0, &filtered);
if (error) {
/* no data was appended, caller should not call sowakeup */
return 0;
}
- }
-
- /* 3962537 - sflt_data_in may drop the lock, need to validate state again */
- if (sb_first != sb->sb_mb) {
- n = sb->sb_mb;
- if (n) {
- while (n->m_nextpkt)
- n = n->m_nextpkt;
- }
+
+ /*
+ If we any filters, the socket lock was dropped. n and sb_first
+ cached data from the socket buffer. This cache is not valid
+ since we dropped the lock. We must start over. Since filtered
+ is set we won't run through the filters a second time. We just
+ set n and sb_start again.
+ */
+ if (filtered)
+ goto again;
}
result = sbcompress(sb, m, n);
return 0;
if ((sb->sb_flags & SB_RECV) != 0) {
- int error = sflt_data_in(sb->sb_so, NULL, &m0, NULL, sock_data_filt_flag_record);
+ int error = sflt_data_in(sb->sb_so, NULL, &m0, NULL, sock_data_filt_flag_record, NULL);
if (error != 0) {
if (error != EJUSTRETURN)
m_freem(m0);
if ((sb->sb_flags & SB_RECV) != 0) {
int error = sflt_data_in(sb->sb_so, NULL, &m0, NULL,
- sock_data_filt_flag_oob);
+ sock_data_filt_flag_oob, NULL);
if (error) {
if (error != EJUSTRETURN) {
/* Call socket data in filters */
if ((sb->sb_flags & SB_RECV) != 0) {
int error;
- error = sflt_data_in(sb->sb_so, asa, &m0, &control, 0);
+ error = sflt_data_in(sb->sb_so, asa, &m0, &control, 0, NULL);
if (error) {
if (error != EJUSTRETURN) {
if (m0) m_freem(m0);
if (sb->sb_flags & SB_RECV) {
int error;
- error = sflt_data_in(sb->sb_so, NULL, &m0, &control, 0);
+ error = sflt_data_in(sb->sb_so, NULL, &m0, &control, 0, NULL);
if (error) {
if (error != EJUSTRETURN) {
if (m0) m_freem(m0);