X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/ea3f04195ba4a5034c9c8e9b726d4f7ce96f1832..f427ee49d309d8fc33ebf3042c3a775f2f530ded:/bsd/kern/uipc_socket.c diff --git a/bsd/kern/uipc_socket.c b/bsd/kern/uipc_socket.c index b94476d05..607af6d3c 100644 --- a/bsd/kern/uipc_socket.c +++ b/bsd/kern/uipc_socket.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2019 Apple Inc. All rights reserved. + * Copyright (c) 1998-2020 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -229,7 +229,7 @@ static unsigned long sodefunct_calls = 0; SYSCTL_LONG(_kern_ipc, OID_AUTO, sodefunct_calls, CTLFLAG_LOCKED, &sodefunct_calls, ""); -static int socket_zone = M_SOCKET; +ZONE_DECLARE(socket_zone, "socket", sizeof(struct socket), ZC_ZFREE_CLEARMEM); so_gen_t so_gencnt; /* generation count for sockets */ MALLOC_DEFINE(M_SONAME, "soname", "socket name"); @@ -338,7 +338,7 @@ vm_size_t so_cache_zone_element_size; static int sodelayed_copy(struct socket *, struct uio *, struct mbuf **, user_ssize_t *); -static void cached_sock_alloc(struct socket **, int); +static void cached_sock_alloc(struct socket **, zalloc_flags_t); static void cached_sock_free(struct socket *); /* @@ -433,10 +433,8 @@ socketinit(void) so_cache_zone_element_size = (vm_size_t)(sizeof(struct socket) + 4 + get_inpcb_str_size() + 4 + get_tcp_str_size()); - so_cache_zone = zinit(so_cache_zone_element_size, - (120000 * so_cache_zone_element_size), 8192, "socache zone"); - zone_change(so_cache_zone, Z_CALLERACCT, FALSE); - zone_change(so_cache_zone, Z_NOENCRYPT, TRUE); + so_cache_zone = zone_create("socache zone", so_cache_zone_element_size, + ZC_ZFREE_CLEARMEM | ZC_NOENCRYPT); bzero(&soextbkidlestat, sizeof(struct soextbkidlestat)); soextbkidlestat.so_xbkidle_maxperproc = SO_IDLE_BK_IDLE_MAX_PER_PROC; @@ -452,7 +450,7 @@ socketinit(void) } static void -cached_sock_alloc(struct socket **so, int waitok) +cached_sock_alloc(struct socket **so, zalloc_flags_t how) { caddr_t temp; uintptr_t offset; @@ -476,17 +474,7 @@ cached_sock_alloc(struct socket **so, int waitok) } else { lck_mtx_unlock(so_cache_mtx); - if (waitok) { - *so = (struct socket *)zalloc(so_cache_zone); - } else { - *so = (struct socket *)zalloc_noblock(so_cache_zone); - } - - if (*so == NULL) { - return; - } - - bzero((caddr_t)*so, sizeof(struct socket)); + *so = zalloc_flags(so_cache_zone, how | Z_ZERO); /* * Define offsets for extra structures into our @@ -628,33 +616,21 @@ so_cache_timer(void) struct socket * soalloc(int waitok, int dom, int type) { + zalloc_flags_t how = waitok ? Z_WAITOK : Z_NOWAIT; struct socket *so; if ((dom == PF_INET) && (type == SOCK_STREAM)) { - cached_sock_alloc(&so, waitok); + cached_sock_alloc(&so, how); } else { - MALLOC_ZONE(so, struct socket *, sizeof(*so), socket_zone, - M_WAITOK); - if (so != NULL) { - bzero(so, sizeof(*so)); - } + so = zalloc_flags(socket_zone, how | Z_ZERO); } if (so != NULL) { so->so_gencnt = OSIncrementAtomic64((SInt64 *)&so_gencnt); - so->so_zone = socket_zone; /* * Increment the socket allocation statistics */ INC_ATOMIC_INT64_LIM(net_api_stats.nas_socket_alloc_total); - -#if CONFIG_MACF_SOCKET - /* Convert waitok to M_WAITOK/M_NOWAIT for MAC Framework. */ - if (mac_socket_label_init(so, !waitok) != 0) { - sodealloc(so); - return NULL; - } -#endif /* MAC_SOCKET */ } return so; @@ -795,10 +771,6 @@ socreate_internal(int dom, struct socket **aso, int type, int proto, so->next_lock_lr = 0; so->next_unlock_lr = 0; -#if CONFIG_MACF_SOCKET - mac_socket_label_associate(kauth_cred_get(), so); -#endif /* MAC_SOCKET */ - /* * Attachment will create the per pcb lock if necessary and * increase refcount for creation, make sure it's done before @@ -828,7 +800,6 @@ socreate_internal(int dom, struct socket **aso, int type, int proto, } atomic_add_32(&prp->pr_domain->dom_refs, 1); - TAILQ_INIT(&so->so_evlist); /* Attach socket filters for this protocol */ sflt_initsock(so); @@ -1003,23 +974,12 @@ sodealloc(struct socket *so) cfil_sock_detach(so); #endif /* CONTENT_FILTER */ - /* Delete the state allocated for msg queues on a socket */ - if (so->so_flags & SOF_ENABLE_MSGS) { - FREE(so->so_msg_state, M_TEMP); - so->so_msg_state = NULL; - } - VERIFY(so->so_msg_state == NULL); - so->so_gencnt = OSIncrementAtomic64((SInt64 *)&so_gencnt); -#if CONFIG_MACF_SOCKET - mac_socket_label_destroy(so); -#endif /* MAC_SOCKET */ - if (so->so_flags1 & SOF1_CACHED_IN_SOCK_LAYER) { cached_sock_free(so); } else { - FREE_ZONE(so, sizeof(*so), so->so_zone); + zfree(socket_zone, so); } } @@ -1522,7 +1482,6 @@ discard: } atomic_add_32(&so->so_proto->pr_domain->dom_refs, -1); - evsofree(so); VERIFY(so->so_usecount > 0); so->so_usecount--; @@ -1839,6 +1798,39 @@ soconnectxlocked(struct socket *so, struct sockaddr *src, (error = sodisconnectlocked(so)) != 0)) { error = EISCONN; } else { + if ((so->so_proto->pr_flags & PR_DATA_IDEMPOTENT) && + (flags & CONNECT_DATA_IDEMPOTENT)) { + so->so_flags1 |= SOF1_DATA_IDEMPOTENT; + + if (flags & CONNECT_DATA_AUTHENTICATED) { + so->so_flags1 |= SOF1_DATA_AUTHENTICATED; + } + } + + /* + * Case 1: CONNECT_RESUME_ON_READ_WRITE set, no data. + * Case 2: CONNECT_RESUME_ON_READ_WRITE set, with data (user error) + * Case 3: CONNECT_RESUME_ON_READ_WRITE not set, with data + * Case 3 allows user to combine write with connect even if they have + * no use for TFO (such as regular TCP, and UDP). + * Case 4: CONNECT_RESUME_ON_READ_WRITE not set, no data (regular case) + */ + if ((so->so_proto->pr_flags & PR_PRECONN_WRITE) && + ((flags & CONNECT_RESUME_ON_READ_WRITE) || auio)) { + so->so_flags1 |= SOF1_PRECONNECT_DATA; + } + + /* + * If a user sets data idempotent and does not pass an uio, or + * sets CONNECT_RESUME_ON_READ_WRITE, this is an error, reset + * SOF1_DATA_IDEMPOTENT. + */ + if (!(so->so_flags1 & SOF1_PRECONNECT_DATA) && + (so->so_flags1 & SOF1_DATA_IDEMPOTENT)) { + /* We should return EINVAL instead perhaps. */ + so->so_flags1 &= ~SOF1_DATA_IDEMPOTENT; + } + /* * Run connect filter before calling protocol: * - non-blocking connect returns before completion; @@ -1856,6 +1848,9 @@ soconnectxlocked(struct socket *so, struct sockaddr *src, flags, arg, arglen, auio, bytes_written); if (error != 0) { so->so_state &= ~SS_ISCONNECTING; + if (error != EINPROGRESS) { + so->so_flags1 &= ~SOF1_PRECONNECT_DATA; + } } } } @@ -1947,8 +1942,7 @@ sodisconnectx(struct socket *so, sae_associd_t aid, sae_connid_t cid) */ int sosendcheck(struct socket *so, struct sockaddr *addr, user_ssize_t resid, - int32_t clen, int32_t atomic, int flags, int *sblocked, - struct mbuf *control) + int32_t clen, int32_t atomic, int flags, int *sblocked) { int error = 0; int32_t space; @@ -2026,11 +2020,7 @@ defunct: } } - if (so->so_flags & SOF_ENABLE_MSGS) { - space = msgq_sbspace(so, control); - } else { - space = sbspace(&so->so_snd); - } + space = sbspace(&so->so_snd); if (flags & MSG_OOB) { space += 1024; @@ -2141,7 +2131,6 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, int atomic = sosendallatonce(so) || top; int sblocked = 0; struct proc *p = current_proc(); - struct mbuf *control_copy = NULL; uint16_t headroom = 0; boolean_t en_tracing = FALSE; @@ -2199,13 +2188,12 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, * causes us to loop sending 0-length segments to the protocol. * * Usually, MSG_EOR isn't used on SOCK_STREAM type sockets. - * But it will be used by sockets doing message delivery. * * Note: We limit resid to be a positive int value as we use * imin() to set bytes_to_copy -- radr://14558484 */ - if (resid < 0 || resid > INT_MAX || (so->so_type == SOCK_STREAM && - !(so->so_flags & SOF_ENABLE_MSGS) && (flags & MSG_EOR))) { + if (resid < 0 || resid > INT_MAX || + (so->so_type == SOCK_STREAM && (flags & MSG_EOR))) { error = EINVAL; goto out_locked; } @@ -2225,17 +2213,13 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, do { error = sosendcheck(so, addr, resid, clen, atomic, flags, - &sblocked, control); + &sblocked); if (error) { goto out_locked; } mp = ⊤ - if (so->so_flags & SOF_ENABLE_MSGS) { - space = msgq_sbspace(so, control); - } else { - space = sbspace(&so->so_snd) - clen; - } + space = sbspace(&so->so_snd) - clen; space += ((flags & MSG_OOB) ? 1024 : 0); do { @@ -2410,12 +2394,14 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, * reserving the socket headroom */ if (freelist == NULL) { - if (top == NULL) { - MGETHDR(freelist, - M_WAIT, MT_DATA); - } else { - MGET(freelist, - M_WAIT, MT_DATA); + if (SOCK_TYPE(so) != SOCK_STREAM || bytes_to_alloc <= MINCLSIZE) { + if (top == NULL) { + MGETHDR(freelist, + M_WAIT, MT_DATA); + } else { + MGET(freelist, + M_WAIT, MT_DATA); + } } if (freelist == NULL) { @@ -2534,14 +2520,6 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, } #endif /* CONTENT_FILTER */ } - if (so->so_flags & SOF_ENABLE_MSGS) { - /* - * Make a copy of control mbuf, - * so that msg priority can be - * passed to subsequent mbufs. - */ - control_copy = m_dup(control, M_NOWAIT); - } error = (*so->so_proto->pr_usrreqs->pru_send) (so, sendflags, top, addr, control, p); @@ -2550,8 +2528,7 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, } clen = 0; - control = control_copy; - control_copy = NULL; + control = NULL; top = NULL; mp = ⊤ if (error) { @@ -2575,9 +2552,6 @@ out_locked: if (freelist != NULL) { m_freem_list(freelist); } - if (control_copy != NULL) { - m_freem(control_copy); - } soclearfastopen(so); @@ -2708,8 +2682,7 @@ sosend_list(struct socket *so, struct uio **uioarray, u_int uiocnt, int flags) (so->so_proto->pr_flags & PR_ATOMIC); OSIncrementAtomicLong(&p->p_stats->p_ru.ru_msgsnd); - error = sosendcheck(so, NULL, resid, 0, atomic, flags, - &sblocked, NULL); + error = sosendcheck(so, NULL, resid, 0, atomic, flags, &sblocked); if (error) { goto release; } @@ -3216,6 +3189,51 @@ done: return error; } +/* + * If we have less data than requested, block awaiting more + * (subject to any timeout) if: + * 1. the current count is less than the low water mark, or + * 2. MSG_WAITALL is set, and it is possible to do the entire + * receive operation at once if we block (resid <= hiwat). + * 3. MSG_DONTWAIT is not set + * If MSG_WAITALL is set but resid is larger than the receive buffer, + * we have to do the receive in sections, and thus risk returning + * a short count if a timeout or signal occurs after we start. + */ +static boolean_t +so_should_wait(struct socket *so, struct uio *uio, struct mbuf *m, int flags) +{ + struct protosw *pr = so->so_proto; + + /* No mbufs in the receive-queue? Wait! */ + if (m == NULL) { + return true; + } + + /* Not enough data in the receive socket-buffer - we may have to wait */ + if ((flags & MSG_DONTWAIT) == 0 && so->so_rcv.sb_cc < uio_resid(uio) && + m->m_nextpkt == NULL && (pr->pr_flags & PR_ATOMIC) == 0) { + /* + * Application did set the lowater-mark, so we should wait for + * this data to be present. + */ + if (so->so_rcv.sb_cc < so->so_rcv.sb_lowat) { + return true; + } + + /* + * Application wants all the data - so let's try to do the + * receive-operation at once by waiting for everything to + * be there. + */ + if ((flags & MSG_WAITALL) && uio_resid(uio) <= so->so_rcv.sb_hiwat) { + return true; + } + } + + return false; +} + /* * Implement receive operations on a socket. * We depend on the way that records are added to the sockbuf @@ -3266,7 +3284,6 @@ soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, user_ssize_t orig_resid = uio_resid(uio); user_ssize_t delayed_copy_len; int can_delay; - int need_event; struct proc *p = current_proc(); boolean_t en_tracing = FALSE; @@ -3475,22 +3492,7 @@ restart: } m = so->so_rcv.sb_mb; - /* - * If we have less data than requested, block awaiting more - * (subject to any timeout) if: - * 1. the current count is less than the low water mark, or - * 2. MSG_WAITALL is set, and it is possible to do the entire - * receive operation at once if we block (resid <= hiwat). - * 3. MSG_DONTWAIT is not set - * If MSG_WAITALL is set but resid is larger than the receive buffer, - * we have to do the receive in sections, and thus risk returning - * a short count if a timeout or signal occurs after we start. - */ - if (m == NULL || (((flags & MSG_DONTWAIT) == 0 && - so->so_rcv.sb_cc < uio_resid(uio)) && - (so->so_rcv.sb_cc < so->so_rcv.sb_lowat || - ((flags & MSG_WAITALL) && uio_resid(uio) <= so->so_rcv.sb_hiwat)) && - m->m_nextpkt == NULL && (pr->pr_flags & PR_ATOMIC) == 0)) { + if (so_should_wait(so, uio, m, flags)) { /* * Panic if we notice inconsistencies in the socket's * receive list; both sb_mb and sb_cc should correctly @@ -3557,7 +3559,24 @@ restart: } #endif - error = sbwait(&so->so_rcv); + /* + * Depending on the protocol (e.g. TCP), the following + * might cause the socket lock to be dropped and later + * be reacquired, and more data could have arrived and + * have been appended to the receive socket buffer by + * the time it returns. Therefore, we only sleep in + * sbwait() below if and only if the wait-condition is still + * true. + */ + if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb != NULL) { + (*pr->pr_usrreqs->pru_rcvd)(so, flags); + } + + error = 0; + if (so_should_wait(so, uio, so->so_rcv.sb_mb, flags)) { + error = sbwait(&so->so_rcv); + } + #if EVEN_MORE_LOCKING_DEBUG if (socket_debug) { printf("SORECEIVE - sbwait returned %d\n", error); @@ -3612,28 +3631,6 @@ dontblock: orig_resid = 0; } - /* - * If the socket is a TCP socket with message delivery - * enabled, then create a control msg to deliver the - * relative TCP sequence number for this data. Waiting - * until this point will protect against failures to - * allocate an mbuf for control msgs. - */ - if (so->so_type == SOCK_STREAM && SOCK_PROTO(so) == IPPROTO_TCP && - (so->so_flags & SOF_ENABLE_MSGS) && controlp != NULL) { - struct mbuf *seq_cm; - - seq_cm = sbcreatecontrol((caddr_t)&m->m_pkthdr.msg_seq, - sizeof(uint32_t), SCM_SEQNUM, SOL_SOCKET); - if (seq_cm == NULL) { - /* unable to allocate a control mbuf */ - error = ENOBUFS; - goto release; - } - *controlp = seq_cm; - controlp = &seq_cm->m_next; - } - if (m != NULL) { if (!(flags & MSG_PEEK)) { /* @@ -3676,8 +3673,6 @@ dontblock: can_delay = 0; } - need_event = 0; - while (m != NULL && (uio_resid(uio) - delayed_copy_len) > 0 && error == 0) { if (m->m_type == MT_OOBDATA) { @@ -3775,28 +3770,6 @@ dontblock: sbfree(&so->so_rcv, m); m->m_nextpkt = NULL; - /* - * If this packet is an unordered packet - * (indicated by M_UNORDERED_DATA flag), remove - * the additional bytes added to the - * receive socket buffer size. - */ - if ((so->so_flags & SOF_ENABLE_MSGS) && - m->m_len && - (m->m_flags & M_UNORDERED_DATA) && - sbreserve(&so->so_rcv, - so->so_rcv.sb_hiwat - m->m_len)) { - if (so->so_msg_state->msg_uno_bytes > - m->m_len) { - so->so_msg_state-> - msg_uno_bytes -= m->m_len; - } else { - so->so_msg_state-> - msg_uno_bytes = 0; - } - m->m_flags &= ~M_UNORDERED_DATA; - } - if (mp != NULL) { *mp = m; mp = &m->m_next; @@ -3859,12 +3832,6 @@ dontblock: so->so_oobmark -= len; if (so->so_oobmark == 0) { so->so_state |= SS_RCVATMARK; - /* - * delay posting the actual event until - * after any delayed copy processing - * has finished - */ - need_event = 1; break; } } else { @@ -3905,9 +3872,7 @@ dontblock: * sbwait() below if and only if the socket buffer is * empty, in order to avoid a false sleep. */ - if (pr->pr_flags & PR_WANTRCVD && so->so_pcb && - (((struct inpcb *)so->so_pcb)->inp_state != - INPCB_STATE_DEAD)) { + if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb != NULL) { (*pr->pr_usrreqs->pru_rcvd)(so, flags); } @@ -4016,9 +3981,6 @@ dontblock: m_freem_list(free_list); free_list = NULL; } - if (need_event) { - postevent(so, 0, EV_OOB); - } if (orig_resid == uio_resid(uio) && orig_resid && (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) { @@ -4666,7 +4628,6 @@ soshutdownlock_final(struct socket *so, int how) goto done; } sorflush(so); - postevent(so, 0, EV_RCLOSED); } if (how != SHUT_RD) { if ((so->so_state & SS_CANTSENDMORE) != 0) { @@ -4675,7 +4636,6 @@ soshutdownlock_final(struct socket *so, int how) goto done; } error = (*pr->pr_usrreqs->pru_shutdown)(so); - postevent(so, 0, EV_WCLOSED); } done: KERNEL_DEBUG(DBG_FNC_SOSHUTDOWN, how, 1, 0, 0, 0); @@ -5001,9 +4961,6 @@ sosetoptlock(struct socket *so, struct sockopt *sopt, int dolock) int64_t long_optval; struct linger l; struct timeval tv; -#if CONFIG_MACF_SOCKET - struct mac extmac; -#endif /* MAC_SOCKET */ if (sopt->sopt_dir != SOPT_SET) { sopt->sopt_dir = SOPT_SET; @@ -5312,17 +5269,7 @@ sosetoptlock(struct socket *so, struct sockopt *sopt, int dolock) break; case SO_LABEL: -#if CONFIG_MACF_SOCKET - if ((error = sooptcopyin(sopt, &extmac, sizeof(extmac), - sizeof(extmac))) != 0) { - goto out; - } - - error = mac_setsockopt_label(proc_ucred(sopt->sopt_p), - so, &extmac); -#else error = EOPNOTSUPP; -#endif /* MAC_SOCKET */ break; case SO_UPCALLCLOSEWAIT: @@ -5750,6 +5697,19 @@ sosetoptlock(struct socket *so, struct sockopt *sopt, int dolock) } break; } + case SO_WANT_KEV_SOCKET_CLOSED: { + error = sooptcopyin(sopt, &optval, sizeof(optval), + sizeof(optval)); + if (error != 0) { + goto out; + } + if (optval == 0) { + so->so_flags1 &= ~SOF1_WANT_KEV_SOCK_CLOSED; + } else { + so->so_flags1 |= SOF1_WANT_KEV_SOCK_CLOSED; + } + break; + } default: error = ENOPROTOOPT; break; @@ -5843,9 +5803,6 @@ sogetoptlock(struct socket *so, struct sockopt *sopt, int dolock) int error, optval; struct linger l; struct timeval tv; -#if CONFIG_MACF_SOCKET - struct mac extmac; -#endif /* MAC_SOCKET */ if (sopt->sopt_dir != SOPT_GET) { sopt->sopt_dir = SOPT_GET; @@ -6042,33 +5999,11 @@ integer: break; case SO_LABEL: -#if CONFIG_MACF_SOCKET - if ((error = sooptcopyin(sopt, &extmac, sizeof(extmac), - sizeof(extmac))) != 0 || - (error = mac_socket_label_get(proc_ucred( - sopt->sopt_p), so, &extmac)) != 0) { - break; - } - - error = sooptcopyout(sopt, &extmac, sizeof(extmac)); -#else error = EOPNOTSUPP; -#endif /* MAC_SOCKET */ break; case SO_PEERLABEL: -#if CONFIG_MACF_SOCKET - if ((error = sooptcopyin(sopt, &extmac, sizeof(extmac), - sizeof(extmac))) != 0 || - (error = mac_socketpeer_label_get(proc_ucred( - sopt->sopt_p), so, &extmac)) != 0) { - break; - } - - error = sooptcopyout(sopt, &extmac, sizeof(extmac)); -#else error = EOPNOTSUPP; -#endif /* MAC_SOCKET */ break; #ifdef __APPLE_API_PRIVATE @@ -6100,11 +6035,6 @@ integer: optval = (so->so_flags & SOF_RECV_TRAFFIC_CLASS); goto integer; - case SO_TRAFFIC_CLASS_STATS: - error = sooptcopyout(sopt, &so->so_tc_stats, - sizeof(so->so_tc_stats)); - break; - #if (DEVELOPMENT || DEBUG) case SO_TRAFFIC_CLASS_DBG: error = sogetopt_tcdbg(so, sopt); @@ -6446,22 +6376,13 @@ sopoll(struct socket *so, int events, kauth_cred_t cred, void * wql) int soo_kqfilter(struct fileproc *fp, struct knote *kn, struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)fp->f_fglob->fg_data; + struct socket *so = (struct socket *)fp->fp_glob->fg_data; int result; socket_lock(so, 1); so_update_last_owner_locked(so, PROC_NULL); so_update_policy(so); -#if CONFIG_MACF_SOCKET - proc_t p = knote_get_kq(kn)->kq_p; - if (mac_socket_check_kqfilter(proc_ucred(p), kn, so) != 0) { - socket_unlock(so, 1); - knote_set_error(kn, EPERM); - return 0; - } -#endif /* MAC_SOCKET */ - switch (kn->kn_filter) { case EVFILT_READ: kn->kn_filtid = EVFILTID_SOREAD; @@ -6574,7 +6495,7 @@ out: static int filt_sorattach(struct knote *kn, __unused struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; /* socket locked */ @@ -6601,7 +6522,7 @@ filt_sorattach(struct knote *kn, __unused struct kevent_qos_s *kev) static void filt_sordetach(struct knote *kn) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; socket_lock(so, 1); if (so->so_rcv.sb_flags & SB_KNOTE) { @@ -6616,7 +6537,7 @@ filt_sordetach(struct knote *kn) static int filt_soread(struct knote *kn, long hint) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; int retval; if ((hint & SO_FILT_HINT_LOCKED) == 0) { @@ -6635,7 +6556,7 @@ filt_soread(struct knote *kn, long hint) static int filt_sortouch(struct knote *kn, struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; int retval; socket_lock(so, 1); @@ -6655,7 +6576,7 @@ filt_sortouch(struct knote *kn, struct kevent_qos_s *kev) static int filt_sorprocess(struct knote *kn, struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; int retval; socket_lock(so, 1); @@ -6755,7 +6676,7 @@ out: static int filt_sowattach(struct knote *kn, __unused struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; /* socket locked */ if (KNOTE_ATTACH(&so->so_snd.sb_sel.si_note, kn)) { @@ -6769,7 +6690,7 @@ filt_sowattach(struct knote *kn, __unused struct kevent_qos_s *kev) static void filt_sowdetach(struct knote *kn) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; socket_lock(so, 1); if (so->so_snd.sb_flags & SB_KNOTE) { @@ -6784,7 +6705,7 @@ filt_sowdetach(struct knote *kn) static int filt_sowrite(struct knote *kn, long hint) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; int ret; if ((hint & SO_FILT_HINT_LOCKED) == 0) { @@ -6803,7 +6724,7 @@ filt_sowrite(struct knote *kn, long hint) static int filt_sowtouch(struct knote *kn, struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; int ret; socket_lock(so, 1); @@ -6823,7 +6744,7 @@ filt_sowtouch(struct knote *kn, struct kevent_qos_s *kev) static int filt_sowprocess(struct knote *kn, struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; int ret; socket_lock(so, 1); @@ -6925,7 +6846,7 @@ filt_sockev_common(struct knote *kn, struct kevent_qos_s *kev, data = so->so_error; kn->kn_flags |= EV_EOF; } else { - u_int32_t data32; + u_int32_t data32 = 0; get_sockev_state(so, &data32); data = data32; } @@ -6975,7 +6896,7 @@ filt_sockev_common(struct knote *kn, struct kevent_qos_s *kev, static int filt_sockattach(struct knote *kn, __unused struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; /* socket locked */ kn->kn_hook32 = 0; @@ -6990,7 +6911,7 @@ filt_sockattach(struct knote *kn, __unused struct kevent_qos_s *kev) static void filt_sockdetach(struct knote *kn) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; socket_lock(so, 1); if ((so->so_flags & SOF_KNOTE) != 0) { @@ -7005,7 +6926,7 @@ static int filt_sockev(struct knote *kn, long hint) { int ret = 0, locked = 0; - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; long ev_hint = (hint & SO_FILT_HINT_EV); if ((hint & SO_FILT_HINT_LOCKED) == 0) { @@ -7032,7 +6953,7 @@ filt_socktouch( struct knote *kn, struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; uint32_t changed_flags; int ret; @@ -7073,7 +6994,7 @@ filt_socktouch( static int filt_sockprocess(struct knote *kn, struct kevent_qos_s *kev) { - struct socket *so = (struct socket *)kn->kn_fp->f_fglob->fg_data; + struct socket *so = (struct socket *)kn->kn_fp->fp_glob->fg_data; int ret = 0; socket_lock(so, 1); @@ -7565,8 +7486,7 @@ so_set_extended_bk_idle(struct socket *so, int optval) soresume(current_proc(), so, 1); } else { struct proc *p = current_proc(); - int i; - struct filedesc *fdp; + struct fileproc *fp; int count = 0; /* @@ -7576,19 +7496,14 @@ so_set_extended_bk_idle(struct socket *so, int optval) socket_unlock(so, 0); proc_fdlock(p); - - fdp = p->p_fd; - for (i = 0; i < fdp->fd_nfiles; i++) { - struct fileproc *fp = fdp->fd_ofiles[i]; + fdt_foreach(fp, p) { struct socket *so2; - if (fp == NULL || - (fdp->fd_ofileflags[i] & UF_RESERVED) != 0 || - FILEGLOB_DTYPE(fp->f_fglob) != DTYPE_SOCKET) { + if (FILEGLOB_DTYPE(fp->fp_glob) != DTYPE_SOCKET) { continue; } - so2 = (struct socket *)fp->f_fglob->fg_data; + so2 = (struct socket *)fp->fp_glob->fg_data; if (so != so2 && so2->so_flags1 & SOF1_EXTEND_BK_IDLE_WANTED) { count++; @@ -7692,23 +7607,16 @@ void resume_proc_sockets(proc_t p) { if (p->p_ladvflag & P_LXBKIDLEINPROG) { - struct filedesc *fdp; - int i; + struct fileproc *fp; + struct socket *so; proc_fdlock(p); - fdp = p->p_fd; - for (i = 0; i < fdp->fd_nfiles; i++) { - struct fileproc *fp; - struct socket *so; - - fp = fdp->fd_ofiles[i]; - if (fp == NULL || - (fdp->fd_ofileflags[i] & UF_RESERVED) != 0 || - FILEGLOB_DTYPE(fp->f_fglob) != DTYPE_SOCKET) { + fdt_foreach(fp, p) { + if (FILEGLOB_DTYPE(fp->fp_glob) != DTYPE_SOCKET) { continue; } - so = (struct socket *)fp->f_fglob->fg_data; + so = (struct socket *)fp->fp_glob->fg_data; (void) soresume(p, so, 0); } proc_fdunlock(p); @@ -7722,11 +7630,7 @@ so_set_recv_anyif(struct socket *so, int optval) { int ret = 0; -#if INET6 if (SOCK_DOM(so) == PF_INET || SOCK_DOM(so) == PF_INET6) { -#else - if (SOCK_DOM(so) == PF_INET) { -#endif /* !INET6 */ if (optval) { sotoinpcb(so)->inp_flags |= INP_RECV_ANYIF; } else { @@ -7743,11 +7647,7 @@ so_get_recv_anyif(struct socket *so) { int ret = 0; -#if INET6 if (SOCK_DOM(so) == PF_INET || SOCK_DOM(so) == PF_INET6) { -#else - if (SOCK_DOM(so) == PF_INET) { -#endif /* !INET6 */ ret = (sotoinpcb(so)->inp_flags & INP_RECV_ANYIF) ? 1 : 0; } @@ -7790,11 +7690,7 @@ so_set_restrictions(struct socket *so, uint32_t vals) (noconstrained_new - noconstrained_old) == 0) { return 0; } -#if INET6 if (SOCK_DOM(so) == PF_INET || SOCK_DOM(so) == PF_INET6) { -#else - if (SOCK_DOM(so) == PF_INET) { -#endif /* !INET6 */ if (nocell_new - nocell_old != 0) { /* * if deny cellular is now set, do what's needed @@ -8092,10 +7988,13 @@ socket_post_kev_msg(uint32_t ev_code, void socket_post_kev_msg_closed(struct socket *so) { - struct kev_socket_closed ev; + struct kev_socket_closed ev = {}; struct sockaddr *socksa = NULL, *peersa = NULL; int err; - bzero(&ev, sizeof(ev)); + + if ((so->so_flags1 & SOF1_WANT_KEV_SOCK_CLOSED) == 0) { + return; + } err = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &socksa); if (err == 0) { err = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so,