X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..4d15aeb193b2c68f1d38666c317f8d3734f5f083:/bsd/kern/kpi_socket.c diff --git a/bsd/kern/kpi_socket.c b/bsd/kern/kpi_socket.c index 09818e3b0..2f1b1d96a 100644 --- a/bsd/kern/kpi_socket.c +++ b/bsd/kern/kpi_socket.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2012 Apple Inc. All rights reserved. + * Copyright (c) 2003-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, socket_unlock(sock, 1); return (ENOTSUP); } +check_again: if (((flags & MSG_DONTWAIT) != 0 || (sock->so_state & SS_NBIO) != 0) && sock->so_comp.tqh_first == NULL) { socket_unlock(sock, 1); @@ -106,10 +108,19 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, return (error); } + so_acquire_accept_list(sock, NULL); + if (TAILQ_EMPTY(&sock->so_comp)) { + so_release_accept_list(sock); + goto check_again; + } new_so = TAILQ_FIRST(&sock->so_comp); TAILQ_REMOVE(&sock->so_comp, new_so, so_list); + new_so->so_state &= ~SS_COMP; + new_so->so_head = NULL; sock->so_qlen--; + so_release_accept_list(sock); + /* * Pass the pre-accepted socket to any interested socket filter(s). * Upon failure, the socket would have been closed by the callee. @@ -122,7 +133,7 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, * again once we're done with the filter(s). */ socket_unlock(sock, 0); - if ((error = soacceptfilter(new_so)) != 0) { + if ((error = soacceptfilter(new_so, sock)) != 0) { /* Drop reference on listening socket */ sodereference(sock); return (error); @@ -136,8 +147,6 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, socket_lock(new_so, 1); } - new_so->so_state &= ~SS_COMP; - new_so->so_head = NULL; (void) soacceptlock(new_so, &sa, 0); socket_unlock(sock, 1); /* release the head */ @@ -495,7 +504,7 @@ so_tc_from_dscp(u_int8_t dscp) else if (dscp >= 0x20 && dscp <= 0x2f) tc = SO_TC_VI; else if (dscp >= 0x08 && dscp <= 0x17) - tc = SO_TC_BK; + tc = SO_TC_BK_SYS; else tc = SO_TC_BE; @@ -950,11 +959,18 @@ sock_release(socket_t sock) __func__, sock->so_retaincnt, sock); /* NOTREACHED */ } - if ((sock->so_retaincnt == 0) && (sock->so_usecount == 2)) { + /* + * Check SS_NOFDREF in case a close happened as sock_retain() + * was grabbing the lock + */ + if ((sock->so_retaincnt == 0) && (sock->so_usecount == 2) && + (!(sock->so_state & SS_NOFDREF) || + (sock->so_flags & SOF_MP_SUBFLOW))) { /* close socket only if the FD is not holding it */ soclose_locked(sock); } else { /* remove extra reference holding the socket */ + VERIFY(sock->so_usecount > 1); sock->so_usecount--; } socket_unlock(sock, 1); @@ -1040,7 +1056,15 @@ sock_set_tcp_stream_priority(socket_t sock) void socket_set_traffic_mgt_flags_locked(socket_t sock, u_int8_t flags) { - (void) OSBitOrAtomic8(flags, &sock->so_traffic_mgt_flags); + u_int32_t soflags1 = 0; + + if ((flags & TRAFFIC_MGT_SO_BACKGROUND)) + soflags1 |= SOF1_TRAFFIC_MGT_SO_BACKGROUND; + if ((flags & TRAFFIC_MGT_TCP_RECVBG)) + soflags1 |= SOF1_TRAFFIC_MGT_TCP_RECVBG; + + (void) OSBitOrAtomic(soflags1, &sock->so_flags1); + sock_set_tcp_stream_priority(sock); } @@ -1058,7 +1082,15 @@ socket_set_traffic_mgt_flags(socket_t sock, u_int8_t flags) void socket_clear_traffic_mgt_flags_locked(socket_t sock, u_int8_t flags) { - (void) OSBitAndAtomic8(~flags, &sock->so_traffic_mgt_flags); + u_int32_t soflags1 = 0; + + if ((flags & TRAFFIC_MGT_SO_BACKGROUND)) + soflags1 |= SOF1_TRAFFIC_MGT_SO_BACKGROUND; + if ((flags & TRAFFIC_MGT_TCP_RECVBG)) + soflags1 |= SOF1_TRAFFIC_MGT_TCP_RECVBG; + + (void) OSBitAndAtomic(~soflags1, &sock->so_flags1); + sock_set_tcp_stream_priority(sock); }