2 * Copyright (c) 2003-2020 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/socketvar.h>
35 #include <sys/param.h>
37 #include <sys/errno.h>
38 #include <sys/malloc.h>
39 #include <sys/protosw.h>
40 #include <sys/domain.h>
42 #include <sys/mcache.h>
43 #include <sys/fcntl.h>
44 #include <sys/filio.h>
45 #include <sys/uio_internal.h>
46 #include <kern/locks.h>
47 #include <net/net_api_stats.h>
48 #include <netinet/in.h>
49 #include <libkern/OSAtomic.h>
52 static errno_t
sock_send_internal(socket_t
, const struct msghdr
*,
53 mbuf_t
, int, size_t *);
57 errno_t
sock_accept(socket_t so
, struct sockaddr
*from
, int fromlen
,
58 int flags
, sock_upcall callback
, void *cookie
, socket_t
*new_so
);
59 errno_t
sock_socket(int domain
, int type
, int protocol
, sock_upcall callback
,
60 void *context
, socket_t
*new_so
);
62 static errno_t
sock_accept_common(socket_t sock
, struct sockaddr
*from
,
63 int fromlen
, int flags
, sock_upcall callback
, void *cookie
,
64 socket_t
*new_sock
, bool is_internal
);
65 static errno_t
sock_socket_common(int domain
, int type
, int protocol
,
66 sock_upcall callback
, void *context
, socket_t
*new_so
, bool is_internal
);
69 sock_accept_common(socket_t sock
, struct sockaddr
*from
, int fromlen
, int flags
,
70 sock_upcall callback
, void *cookie
, socket_t
*new_sock
, bool is_internal
)
73 struct socket
*new_so
;
74 lck_mtx_t
*mutex_held
;
78 if (sock
== NULL
|| new_sock
== NULL
) {
83 if ((sock
->so_options
& SO_ACCEPTCONN
) == 0) {
84 socket_unlock(sock
, 1);
87 if ((flags
& ~(MSG_DONTWAIT
)) != 0) {
88 socket_unlock(sock
, 1);
92 if (((flags
& MSG_DONTWAIT
) != 0 || (sock
->so_state
& SS_NBIO
) != 0) &&
93 sock
->so_comp
.tqh_first
== NULL
) {
94 socket_unlock(sock
, 1);
98 if (sock
->so_proto
->pr_getlock
!= NULL
) {
99 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, PR_F_WILLUNLOCK
);
102 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
106 while (TAILQ_EMPTY(&sock
->so_comp
) && sock
->so_error
== 0) {
107 if (sock
->so_state
& SS_CANTRCVMORE
) {
108 sock
->so_error
= ECONNABORTED
;
111 error
= msleep((caddr_t
)&sock
->so_timeo
, mutex_held
,
112 PSOCK
| PCATCH
, "sock_accept", NULL
);
114 socket_unlock(sock
, 1);
118 if (sock
->so_error
!= 0) {
119 error
= sock
->so_error
;
121 socket_unlock(sock
, 1);
125 so_acquire_accept_list(sock
, NULL
);
126 if (TAILQ_EMPTY(&sock
->so_comp
)) {
127 so_release_accept_list(sock
);
130 new_so
= TAILQ_FIRST(&sock
->so_comp
);
131 TAILQ_REMOVE(&sock
->so_comp
, new_so
, so_list
);
132 new_so
->so_state
&= ~SS_COMP
;
133 new_so
->so_head
= NULL
;
136 so_release_accept_list(sock
);
139 * Count the accepted socket as an in-kernel socket
141 new_so
->so_flags1
|= SOF1_IN_KERNEL_SOCKET
;
142 INC_ATOMIC_INT64_LIM(net_api_stats
.nas_socket_in_kernel_total
);
144 INC_ATOMIC_INT64_LIM(net_api_stats
.nas_socket_in_kernel_os_total
);
148 * Pass the pre-accepted socket to any interested socket filter(s).
149 * Upon failure, the socket would have been closed by the callee.
151 if (new_so
->so_filt
!= NULL
) {
153 * Temporarily drop the listening socket's lock before we
154 * hand off control over to the socket filter(s), but keep
155 * a reference so that it won't go away. We'll grab it
156 * again once we're done with the filter(s).
158 socket_unlock(sock
, 0);
159 if ((error
= soacceptfilter(new_so
, sock
)) != 0) {
160 /* Drop reference on listening socket */
164 socket_lock(sock
, 0);
168 LCK_MTX_ASSERT(new_so
->so_proto
->pr_getlock(new_so
, 0),
169 LCK_MTX_ASSERT_NOTOWNED
);
170 socket_lock(new_so
, 1);
173 (void) soacceptlock(new_so
, &sa
, 0);
175 socket_unlock(sock
, 1); /* release the head */
177 /* see comments in sock_setupcall() */
178 if (callback
!= NULL
) {
179 #if (defined(__arm__) || defined(__arm64__))
180 sock_setupcalls_locked(new_so
, callback
, cookie
, callback
, cookie
, 0);
181 #else /* (defined(__arm__) || defined(__arm64__)) */
182 sock_setupcalls_locked(new_so
, callback
, cookie
, NULL
, NULL
, 0);
183 #endif /* (defined(__arm__) || defined(__arm64__)) */
186 if (sa
!= NULL
&& from
!= NULL
) {
187 if (fromlen
> sa
->sa_len
) {
188 fromlen
= sa
->sa_len
;
190 memcpy(from
, sa
, fromlen
);
197 * If the socket has been marked as inactive by sosetdefunct(),
198 * disallow further operations on it.
200 if (new_so
->so_flags
& SOF_DEFUNCT
) {
201 (void) sodefunct(current_proc(), new_so
,
202 SHUTDOWN_SOCKET_LEVEL_DISCONNECT_INTERNAL
);
206 socket_unlock(new_so
, 1);
212 sock_accept(socket_t sock
, struct sockaddr
*from
, int fromlen
, int flags
,
213 sock_upcall callback
, void *cookie
, socket_t
*new_sock
)
215 return sock_accept_common(sock
, from
, fromlen
, flags
,
216 callback
, cookie
, new_sock
, false);
220 sock_accept_internal(socket_t sock
, struct sockaddr
*from
, int fromlen
, int flags
,
221 sock_upcall callback
, void *cookie
, socket_t
*new_sock
)
223 return sock_accept_common(sock
, from
, fromlen
, flags
,
224 callback
, cookie
, new_sock
, true);
228 sock_bind(socket_t sock
, const struct sockaddr
*to
)
231 struct sockaddr
*sa
= NULL
;
232 struct sockaddr_storage ss
;
233 boolean_t want_free
= TRUE
;
235 if (sock
== NULL
|| to
== NULL
) {
239 if (to
->sa_len
> sizeof(ss
)) {
240 sa
= kheap_alloc(KHEAP_TEMP
, to
->sa_len
, Z_WAITOK
);
245 sa
= (struct sockaddr
*)&ss
;
248 memcpy(sa
, to
, to
->sa_len
);
250 error
= sobindlock(sock
, sa
, 1); /* will lock socket */
252 if (sa
!= NULL
&& want_free
== TRUE
) {
253 kheap_free(KHEAP_TEMP
, sa
, sa
->sa_len
);
260 sock_connect(socket_t sock
, const struct sockaddr
*to
, int flags
)
263 lck_mtx_t
*mutex_held
;
264 struct sockaddr
*sa
= NULL
;
265 struct sockaddr_storage ss
;
266 boolean_t want_free
= TRUE
;
268 if (sock
== NULL
|| to
== NULL
) {
272 if (to
->sa_len
> sizeof(ss
)) {
273 sa
= kheap_alloc(KHEAP_TEMP
, to
->sa_len
,
274 (flags
& MSG_DONTWAIT
) ? Z_NOWAIT
: Z_WAITOK
);
279 sa
= (struct sockaddr
*)&ss
;
282 memcpy(sa
, to
, to
->sa_len
);
284 socket_lock(sock
, 1);
286 if ((sock
->so_state
& SS_ISCONNECTING
) &&
287 ((sock
->so_state
& SS_NBIO
) != 0 || (flags
& MSG_DONTWAIT
) != 0)) {
291 error
= soconnectlock(sock
, sa
, 0);
293 if ((sock
->so_state
& SS_ISCONNECTING
) &&
294 ((sock
->so_state
& SS_NBIO
) != 0 ||
295 (flags
& MSG_DONTWAIT
) != 0)) {
300 if (sock
->so_proto
->pr_getlock
!= NULL
) {
301 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, PR_F_WILLUNLOCK
);
303 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
306 while ((sock
->so_state
& SS_ISCONNECTING
) &&
307 sock
->so_error
== 0) {
308 error
= msleep((caddr_t
)&sock
->so_timeo
,
309 mutex_held
, PSOCK
| PCATCH
, "sock_connect", NULL
);
316 error
= sock
->so_error
;
320 sock
->so_state
&= ~SS_ISCONNECTING
;
323 socket_unlock(sock
, 1);
325 if (sa
!= NULL
&& want_free
== TRUE
) {
326 kheap_free(KHEAP_TEMP
, sa
, sa
->sa_len
);
333 sock_connectwait(socket_t sock
, const struct timeval
*tv
)
335 lck_mtx_t
*mutex_held
;
339 socket_lock(sock
, 1);
341 /* Check if we're already connected or if we've already errored out */
342 if ((sock
->so_state
& SS_ISCONNECTING
) == 0 || sock
->so_error
!= 0) {
343 if (sock
->so_error
!= 0) {
344 retval
= sock
->so_error
;
347 if ((sock
->so_state
& SS_ISCONNECTED
) != 0) {
356 /* copied translation from timeval to hertz from SO_RCVTIMEO handling */
357 if (tv
->tv_sec
< 0 || tv
->tv_sec
> SHRT_MAX
/ hz
||
358 tv
->tv_usec
< 0 || tv
->tv_usec
>= 1000000) {
363 ts
.tv_sec
= tv
->tv_sec
;
364 ts
.tv_nsec
= (tv
->tv_usec
* (integer_t
)NSEC_PER_USEC
);
365 if ((ts
.tv_sec
+ (ts
.tv_nsec
/ (long)NSEC_PER_SEC
)) / 100 > SHRT_MAX
) {
370 if (sock
->so_proto
->pr_getlock
!= NULL
) {
371 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, PR_F_WILLUNLOCK
);
373 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
376 msleep((caddr_t
)&sock
->so_timeo
, mutex_held
,
377 PSOCK
, "sock_connectwait", &ts
);
379 /* Check if we're still waiting to connect */
380 if ((sock
->so_state
& SS_ISCONNECTING
) && sock
->so_error
== 0) {
381 retval
= EINPROGRESS
;
385 if (sock
->so_error
!= 0) {
386 retval
= sock
->so_error
;
391 socket_unlock(sock
, 1);
396 sock_nointerrupt(socket_t sock
, int on
)
398 socket_lock(sock
, 1);
401 sock
->so_rcv
.sb_flags
|= SB_NOINTR
; /* This isn't safe */
402 sock
->so_snd
.sb_flags
|= SB_NOINTR
; /* This isn't safe */
404 sock
->so_rcv
.sb_flags
&= ~SB_NOINTR
; /* This isn't safe */
405 sock
->so_snd
.sb_flags
&= ~SB_NOINTR
; /* This isn't safe */
408 socket_unlock(sock
, 1);
414 sock_getpeername(socket_t sock
, struct sockaddr
*peername
, int peernamelen
)
417 struct sockaddr
*sa
= NULL
;
419 if (sock
== NULL
|| peername
== NULL
|| peernamelen
< 0) {
423 socket_lock(sock
, 1);
424 if (!(sock
->so_state
& (SS_ISCONNECTED
| SS_ISCONFIRMING
))) {
425 socket_unlock(sock
, 1);
428 error
= sogetaddr_locked(sock
, &sa
, 1);
429 socket_unlock(sock
, 1);
431 if (peernamelen
> sa
->sa_len
) {
432 peernamelen
= sa
->sa_len
;
434 memcpy(peername
, sa
, peernamelen
);
441 sock_getsockname(socket_t sock
, struct sockaddr
*sockname
, int socknamelen
)
444 struct sockaddr
*sa
= NULL
;
446 if (sock
== NULL
|| sockname
== NULL
|| socknamelen
< 0) {
450 socket_lock(sock
, 1);
451 error
= sogetaddr_locked(sock
, &sa
, 0);
452 socket_unlock(sock
, 1);
454 if (socknamelen
> sa
->sa_len
) {
455 socknamelen
= sa
->sa_len
;
457 memcpy(sockname
, sa
, socknamelen
);
463 __private_extern__
int
464 sogetaddr_locked(struct socket
*so
, struct sockaddr
**psa
, int peer
)
468 if (so
== NULL
|| psa
== NULL
) {
473 error
= peer
? so
->so_proto
->pr_usrreqs
->pru_peeraddr(so
, psa
) :
474 so
->so_proto
->pr_usrreqs
->pru_sockaddr(so
, psa
);
476 if (error
== 0 && *psa
== NULL
) {
478 } else if (error
!= 0) {
479 FREE(*psa
, M_SONAME
);
485 sock_getaddr(socket_t sock
, struct sockaddr
**psa
, int peer
)
489 if (sock
== NULL
|| psa
== NULL
) {
493 socket_lock(sock
, 1);
494 error
= sogetaddr_locked(sock
, psa
, peer
);
495 socket_unlock(sock
, 1);
501 sock_freeaddr(struct sockaddr
*sa
)
507 sock_getsockopt(socket_t sock
, int level
, int optname
, void *optval
,
513 if (sock
== NULL
|| optval
== NULL
|| optlen
== NULL
) {
517 sopt
.sopt_dir
= SOPT_GET
;
518 sopt
.sopt_level
= level
;
519 sopt
.sopt_name
= optname
;
520 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
521 sopt
.sopt_valsize
= *optlen
;
522 sopt
.sopt_p
= kernproc
;
523 error
= sogetoptlock(sock
, &sopt
, 1); /* will lock socket */
525 *optlen
= (uint32_t)sopt
.sopt_valsize
;
531 sock_ioctl(socket_t sock
, unsigned long request
, void *argp
)
533 return soioctl(sock
, request
, argp
, kernproc
); /* will lock socket */
537 sock_setsockopt(socket_t sock
, int level
, int optname
, const void *optval
,
542 if (sock
== NULL
|| optval
== NULL
) {
546 sopt
.sopt_dir
= SOPT_SET
;
547 sopt
.sopt_level
= level
;
548 sopt
.sopt_name
= optname
;
549 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
550 sopt
.sopt_valsize
= optlen
;
551 sopt
.sopt_p
= kernproc
;
552 return sosetoptlock(sock
, &sopt
, 1); /* will lock socket */
556 * This follows the recommended mappings between DSCP code points
557 * and WMM access classes.
560 so_tc_from_dscp(uint8_t dscp
)
564 if (dscp
>= 0x30 && dscp
<= 0x3f) {
566 } else if (dscp
>= 0x20 && dscp
<= 0x2f) {
568 } else if (dscp
>= 0x08 && dscp
<= 0x17) {
578 sock_settclassopt(socket_t sock
, const void *optval
, size_t optlen
)
584 if (sock
== NULL
|| optval
== NULL
|| optlen
!= sizeof(int)) {
588 socket_lock(sock
, 1);
589 if (!(sock
->so_state
& SS_ISCONNECTED
)) {
591 * If the socket is not connected then we don't know
592 * if the destination is on LAN or not. Skip
593 * setting traffic class in this case
599 if (sock
->so_proto
== NULL
|| sock
->so_proto
->pr_domain
== NULL
||
600 sock
->so_pcb
== NULL
) {
606 * Set the socket traffic class based on the passed DSCP code point
607 * regardless of the scope of the destination
609 sotc
= so_tc_from_dscp((uint8_t)((*(const int *)optval
) >> 2));
611 sopt
.sopt_dir
= SOPT_SET
;
612 sopt
.sopt_val
= CAST_USER_ADDR_T(&sotc
);
613 sopt
.sopt_valsize
= sizeof(sotc
);
614 sopt
.sopt_p
= kernproc
;
615 sopt
.sopt_level
= SOL_SOCKET
;
616 sopt
.sopt_name
= SO_TRAFFIC_CLASS
;
618 error
= sosetoptlock(sock
, &sopt
, 0); /* already locked */
621 printf("%s: sosetopt SO_TRAFFIC_CLASS failed %d\n",
627 * Check if the destination address is LAN or link local address.
628 * We do not want to set traffic class bits if the destination
631 if (!so_isdstlocal(sock
)) {
635 sopt
.sopt_dir
= SOPT_SET
;
636 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
637 sopt
.sopt_valsize
= optlen
;
638 sopt
.sopt_p
= kernproc
;
640 switch (SOCK_DOM(sock
)) {
642 sopt
.sopt_level
= IPPROTO_IP
;
643 sopt
.sopt_name
= IP_TOS
;
646 sopt
.sopt_level
= IPPROTO_IPV6
;
647 sopt
.sopt_name
= IPV6_TCLASS
;
654 error
= sosetoptlock(sock
, &sopt
, 0); /* already locked */
655 socket_unlock(sock
, 1);
658 socket_unlock(sock
, 1);
663 sock_gettclassopt(socket_t sock
, void *optval
, size_t *optlen
)
668 if (sock
== NULL
|| optval
== NULL
|| optlen
== NULL
) {
672 sopt
.sopt_dir
= SOPT_GET
;
673 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
674 sopt
.sopt_valsize
= *optlen
;
675 sopt
.sopt_p
= kernproc
;
677 socket_lock(sock
, 1);
678 if (sock
->so_proto
== NULL
|| sock
->so_proto
->pr_domain
== NULL
) {
679 socket_unlock(sock
, 1);
683 switch (SOCK_DOM(sock
)) {
685 sopt
.sopt_level
= IPPROTO_IP
;
686 sopt
.sopt_name
= IP_TOS
;
689 sopt
.sopt_level
= IPPROTO_IPV6
;
690 sopt
.sopt_name
= IPV6_TCLASS
;
693 socket_unlock(sock
, 1);
696 error
= sogetoptlock(sock
, &sopt
, 0); /* already locked */
697 socket_unlock(sock
, 1);
699 *optlen
= sopt
.sopt_valsize
;
705 sock_listen(socket_t sock
, int backlog
)
711 return solisten(sock
, backlog
); /* will lock socket */
715 sock_receive_internal(socket_t sock
, struct msghdr
*msg
, mbuf_t
*data
,
716 int flags
, size_t *recvdlen
)
719 struct mbuf
*control
= NULL
;
721 user_ssize_t length
= 0;
722 struct sockaddr
*fromsa
= NULL
;
723 char uio_buf
[UIO_SIZEOF((msg
!= NULL
) ? msg
->msg_iovlen
: 0)];
729 auio
= uio_createwithbuffer(((msg
!= NULL
) ? msg
->msg_iovlen
: 0),
730 0, UIO_SYSSPACE
, UIO_READ
, &uio_buf
[0], sizeof(uio_buf
));
731 if (msg
!= NULL
&& data
== NULL
) {
733 struct iovec
*tempp
= msg
->msg_iov
;
735 for (i
= 0; i
< msg
->msg_iovlen
; i
++) {
737 CAST_USER_ADDR_T((tempp
+ i
)->iov_base
),
738 (tempp
+ i
)->iov_len
);
740 if (uio_resid(auio
) < 0) {
743 } else if (recvdlen
!= NULL
) {
744 uio_setresid(auio
, (uio_resid(auio
) + *recvdlen
));
746 length
= uio_resid(auio
);
748 if (recvdlen
!= NULL
) {
752 /* let pru_soreceive handle the socket locking */
753 error
= sock
->so_proto
->pr_usrreqs
->pru_soreceive(sock
, &fromsa
, auio
,
754 data
, (msg
&& msg
->msg_control
) ? &control
: NULL
, &flags
);
759 if (recvdlen
!= NULL
) {
760 *recvdlen
= length
- uio_resid(auio
);
763 msg
->msg_flags
= flags
;
765 if (msg
->msg_name
!= NULL
) {
767 salen
= msg
->msg_namelen
;
768 if (msg
->msg_namelen
> 0 && fromsa
!= NULL
) {
769 salen
= MIN(salen
, fromsa
->sa_len
);
770 memcpy(msg
->msg_name
, fromsa
,
771 msg
->msg_namelen
> fromsa
->sa_len
?
772 fromsa
->sa_len
: msg
->msg_namelen
);
776 if (msg
->msg_control
!= NULL
) {
777 struct mbuf
*m
= control
;
778 u_char
*ctlbuf
= msg
->msg_control
;
779 int clen
= msg
->msg_controllen
;
781 msg
->msg_controllen
= 0;
783 while (m
!= NULL
&& clen
> 0) {
786 if (clen
>= m
->m_len
) {
789 msg
->msg_flags
|= MSG_CTRUNC
;
792 memcpy(ctlbuf
, mtod(m
, caddr_t
), tocopy
);
797 msg
->msg_controllen
=
798 (socklen_t
)((uintptr_t)ctlbuf
- (uintptr_t)msg
->msg_control
);
803 if (control
!= NULL
) {
806 FREE(fromsa
, M_SONAME
);
811 sock_receive(socket_t sock
, struct msghdr
*msg
, int flags
, size_t *recvdlen
)
813 if ((msg
== NULL
) || (msg
->msg_iovlen
< 1) ||
814 (msg
->msg_iov
[0].iov_len
== 0) ||
815 (msg
->msg_iov
[0].iov_base
== NULL
)) {
819 return sock_receive_internal(sock
, msg
, NULL
, flags
, recvdlen
);
823 sock_receivembuf(socket_t sock
, struct msghdr
*msg
, mbuf_t
*data
, int flags
,
826 if (data
== NULL
|| recvlen
== 0 || *recvlen
<= 0 || (msg
!= NULL
&&
827 (msg
->msg_iov
!= NULL
|| msg
->msg_iovlen
!= 0))) {
831 return sock_receive_internal(sock
, msg
, data
, flags
, recvlen
);
835 sock_send_internal(socket_t sock
, const struct msghdr
*msg
, mbuf_t data
,
836 int flags
, size_t *sentlen
)
839 struct mbuf
*control
= NULL
;
841 user_ssize_t datalen
= 0;
842 char uio_buf
[UIO_SIZEOF((msg
!= NULL
? msg
->msg_iovlen
: 1))];
849 if (data
== NULL
&& msg
!= NULL
) {
850 struct iovec
*tempp
= msg
->msg_iov
;
852 auio
= uio_createwithbuffer(msg
->msg_iovlen
, 0,
853 UIO_SYSSPACE
, UIO_WRITE
, &uio_buf
[0], sizeof(uio_buf
));
857 for (i
= 0; i
< msg
->msg_iovlen
; i
++) {
859 CAST_USER_ADDR_T((tempp
+ i
)->iov_base
),
860 (tempp
+ i
)->iov_len
);
863 if (uio_resid(auio
) < 0) {
870 if (sentlen
!= NULL
) {
875 datalen
= uio_resid(auio
);
877 datalen
= data
->m_pkthdr
.len
;
880 if (msg
!= NULL
&& msg
->msg_control
) {
881 if ((size_t)msg
->msg_controllen
< sizeof(struct cmsghdr
)) {
886 if ((size_t)msg
->msg_controllen
> MLEN
) {
891 control
= m_get(M_NOWAIT
, MT_CONTROL
);
892 if (control
== NULL
) {
896 memcpy(mtod(control
, caddr_t
), msg
->msg_control
,
897 msg
->msg_controllen
);
898 control
->m_len
= msg
->msg_controllen
;
901 error
= sock
->so_proto
->pr_usrreqs
->pru_sosend(sock
, msg
!= NULL
?
902 (struct sockaddr
*)msg
->msg_name
: NULL
, auio
, data
,
906 * Residual data is possible in the case of IO vectors but not
907 * in the mbuf case since the latter is treated as atomic send.
908 * If pru_sosend() consumed a portion of the iovecs data and
909 * the error returned is transient, treat it as success; this
910 * is consistent with sendit() behavior.
912 if (auio
!= NULL
&& uio_resid(auio
) != datalen
&&
913 (error
== ERESTART
|| error
== EINTR
|| error
== EWOULDBLOCK
)) {
917 if (error
== 0 && sentlen
!= NULL
) {
919 *sentlen
= datalen
- uio_resid(auio
);
928 * In cases where we detect an error before returning, we need to
929 * free the mbuf chain if there is one. sosend (and pru_sosend) will
930 * free the mbuf chain if they encounter an error.
946 sock_send(socket_t sock
, const struct msghdr
*msg
, int flags
, size_t *sentlen
)
948 if (msg
== NULL
|| msg
->msg_iov
== NULL
|| msg
->msg_iovlen
< 1) {
952 return sock_send_internal(sock
, msg
, NULL
, flags
, sentlen
);
956 sock_sendmbuf(socket_t sock
, const struct msghdr
*msg
, mbuf_t data
,
957 int flags
, size_t *sentlen
)
959 if (data
== NULL
|| (msg
!= NULL
&& (msg
->msg_iov
!= NULL
||
960 msg
->msg_iovlen
!= 0))) {
966 return sock_send_internal(sock
, msg
, data
, flags
, sentlen
);
970 sock_shutdown(socket_t sock
, int how
)
976 return soshutdown(sock
, how
);
980 sock_socket_common(int domain
, int type
, int protocol
, sock_upcall callback
,
981 void *context
, socket_t
*new_so
, bool is_internal
)
985 if (new_so
== NULL
) {
989 /* socreate will create an initial so_count */
990 error
= socreate(domain
, new_so
, type
, protocol
);
993 * This is an in-kernel socket
995 (*new_so
)->so_flags1
|= SOF1_IN_KERNEL_SOCKET
;
996 INC_ATOMIC_INT64_LIM(net_api_stats
.nas_socket_in_kernel_total
);
998 INC_ATOMIC_INT64_LIM(net_api_stats
.nas_socket_in_kernel_os_total
);
1001 /* see comments in sock_setupcall() */
1002 if (callback
!= NULL
) {
1003 sock_setupcall(*new_so
, callback
, context
);
1006 * last_pid and last_upid should be zero for sockets
1007 * created using sock_socket
1009 (*new_so
)->last_pid
= 0;
1010 (*new_so
)->last_upid
= 0;
1016 sock_socket_internal(int domain
, int type
, int protocol
, sock_upcall callback
,
1017 void *context
, socket_t
*new_so
)
1019 return sock_socket_common(domain
, type
, protocol
, callback
,
1020 context
, new_so
, true);
1024 sock_socket(int domain
, int type
, int protocol
, sock_upcall callback
,
1025 void *context
, socket_t
*new_so
)
1027 return sock_socket_common(domain
, type
, protocol
, callback
,
1028 context
, new_so
, false);
1032 sock_close(socket_t sock
)
1041 /* Do we want this to be APPLE_PRIVATE API?: YES (LD 12/23/04) */
1043 sock_retain(socket_t sock
)
1049 socket_lock(sock
, 1);
1050 sock
->so_retaincnt
++;
1051 sock
->so_usecount
++; /* add extra reference for holding the socket */
1052 socket_unlock(sock
, 1);
1055 /* Do we want this to be APPLE_PRIVATE API? */
1057 sock_release(socket_t sock
)
1063 socket_lock(sock
, 1);
1064 if (sock
->so_upcallusecount
> 0) {
1065 soclose_wait_locked(sock
);
1068 sock
->so_retaincnt
--;
1069 if (sock
->so_retaincnt
< 0) {
1070 panic("%s: negative retain count (%d) for sock=%p\n",
1071 __func__
, sock
->so_retaincnt
, sock
);
1075 * Check SS_NOFDREF in case a close happened as sock_retain()
1076 * was grabbing the lock
1078 if ((sock
->so_retaincnt
== 0) && (sock
->so_usecount
== 2) &&
1079 (!(sock
->so_state
& SS_NOFDREF
) ||
1080 (sock
->so_flags
& SOF_MP_SUBFLOW
))) {
1081 /* close socket only if the FD is not holding it */
1082 soclose_locked(sock
);
1084 /* remove extra reference holding the socket */
1085 VERIFY(sock
->so_usecount
> 1);
1086 sock
->so_usecount
--;
1088 socket_unlock(sock
, 1);
1092 sock_setpriv(socket_t sock
, int on
)
1098 socket_lock(sock
, 1);
1100 sock
->so_state
|= SS_PRIV
;
1102 sock
->so_state
&= ~SS_PRIV
;
1104 socket_unlock(sock
, 1);
1109 sock_isconnected(socket_t sock
)
1113 socket_lock(sock
, 1);
1114 retval
= ((sock
->so_state
& SS_ISCONNECTED
) ? 1 : 0);
1115 socket_unlock(sock
, 1);
1120 sock_isnonblocking(socket_t sock
)
1124 socket_lock(sock
, 1);
1125 retval
= ((sock
->so_state
& SS_NBIO
) ? 1 : 0);
1126 socket_unlock(sock
, 1);
1131 sock_gettype(socket_t sock
, int *outDomain
, int *outType
, int *outProtocol
)
1133 socket_lock(sock
, 1);
1134 if (outDomain
!= NULL
) {
1135 *outDomain
= SOCK_DOM(sock
);
1137 if (outType
!= NULL
) {
1138 *outType
= sock
->so_type
;
1140 if (outProtocol
!= NULL
) {
1141 *outProtocol
= SOCK_PROTO(sock
);
1143 socket_unlock(sock
, 1);
1148 * Return the listening socket of a pre-accepted socket. It returns the
1149 * listener (so_head) value of a given socket. This is intended to be
1150 * called by a socket filter during a filter attach (sf_attach) callback.
1151 * The value returned by this routine is safe to be used only in the
1152 * context of that callback, because we hold the listener's lock across
1153 * the sflt_initsock() call.
1156 sock_getlistener(socket_t sock
)
1158 return sock
->so_head
;
1162 sock_set_tcp_stream_priority(socket_t sock
)
1164 if ((SOCK_DOM(sock
) == PF_INET
|| SOCK_DOM(sock
) == PF_INET6
) &&
1165 SOCK_TYPE(sock
) == SOCK_STREAM
) {
1166 set_tcp_stream_priority(sock
);
1171 * Caller must have ensured socket is valid and won't be going away.
1174 socket_set_traffic_mgt_flags_locked(socket_t sock
, u_int8_t flags
)
1176 u_int32_t soflags1
= 0;
1178 if ((flags
& TRAFFIC_MGT_SO_BACKGROUND
)) {
1179 soflags1
|= SOF1_TRAFFIC_MGT_SO_BACKGROUND
;
1181 if ((flags
& TRAFFIC_MGT_TCP_RECVBG
)) {
1182 soflags1
|= SOF1_TRAFFIC_MGT_TCP_RECVBG
;
1185 (void) OSBitOrAtomic(soflags1
, &sock
->so_flags1
);
1187 sock_set_tcp_stream_priority(sock
);
1191 socket_set_traffic_mgt_flags(socket_t sock
, u_int8_t flags
)
1193 socket_lock(sock
, 1);
1194 socket_set_traffic_mgt_flags_locked(sock
, flags
);
1195 socket_unlock(sock
, 1);
1199 * Caller must have ensured socket is valid and won't be going away.
1202 socket_clear_traffic_mgt_flags_locked(socket_t sock
, u_int8_t flags
)
1204 u_int32_t soflags1
= 0;
1206 if ((flags
& TRAFFIC_MGT_SO_BACKGROUND
)) {
1207 soflags1
|= SOF1_TRAFFIC_MGT_SO_BACKGROUND
;
1209 if ((flags
& TRAFFIC_MGT_TCP_RECVBG
)) {
1210 soflags1
|= SOF1_TRAFFIC_MGT_TCP_RECVBG
;
1213 (void) OSBitAndAtomic(~soflags1
, &sock
->so_flags1
);
1215 sock_set_tcp_stream_priority(sock
);
1219 socket_clear_traffic_mgt_flags(socket_t sock
, u_int8_t flags
)
1221 socket_lock(sock
, 1);
1222 socket_clear_traffic_mgt_flags_locked(sock
, flags
);
1223 socket_unlock(sock
, 1);
1228 * Caller must have ensured socket is valid and won't be going away.
1231 socket_defunct(struct proc
*p
, socket_t so
, int level
)
1235 if (level
!= SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC
&&
1236 level
!= SHUTDOWN_SOCKET_LEVEL_DISCONNECT_ALL
) {
1242 * SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC level is meant to tear down
1243 * all of mDNSResponder IPC sockets, currently those of AF_UNIX; note
1244 * that this is an implementation artifact of mDNSResponder. We do
1245 * a quick test against the socket buffers for SB_UNIX, since that
1246 * would have been set by unp_attach() at socket creation time.
1248 if (level
== SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC
&&
1249 (so
->so_rcv
.sb_flags
& so
->so_snd
.sb_flags
& SB_UNIX
) != SB_UNIX
) {
1250 socket_unlock(so
, 1);
1253 retval
= sosetdefunct(p
, so
, level
, TRUE
);
1255 retval
= sodefunct(p
, so
, level
);
1257 socket_unlock(so
, 1);
1262 sock_setupcalls_locked(socket_t sock
, sock_upcall rcallback
, void *rcontext
,
1263 sock_upcall wcallback
, void *wcontext
, int locked
)
1265 if (rcallback
!= NULL
) {
1266 sock
->so_rcv
.sb_flags
|= SB_UPCALL
;
1268 sock
->so_rcv
.sb_flags
|= SB_UPCALL_LOCK
;
1270 sock
->so_rcv
.sb_upcall
= rcallback
;
1271 sock
->so_rcv
.sb_upcallarg
= rcontext
;
1273 sock
->so_rcv
.sb_flags
&= ~(SB_UPCALL
| SB_UPCALL_LOCK
);
1274 sock
->so_rcv
.sb_upcall
= NULL
;
1275 sock
->so_rcv
.sb_upcallarg
= NULL
;
1278 if (wcallback
!= NULL
) {
1279 sock
->so_snd
.sb_flags
|= SB_UPCALL
;
1281 sock
->so_snd
.sb_flags
|= SB_UPCALL_LOCK
;
1283 sock
->so_snd
.sb_upcall
= wcallback
;
1284 sock
->so_snd
.sb_upcallarg
= wcontext
;
1286 sock
->so_snd
.sb_flags
&= ~(SB_UPCALL
| SB_UPCALL_LOCK
);
1287 sock
->so_snd
.sb_upcall
= NULL
;
1288 sock
->so_snd
.sb_upcallarg
= NULL
;
1293 sock_setupcall(socket_t sock
, sock_upcall callback
, void *context
)
1300 * Note that we don't wait for any in progress upcall to complete.
1301 * On embedded, sock_setupcall() causes both read and write
1302 * callbacks to be set; on desktop, only read callback is set
1303 * to maintain legacy KPI behavior.
1305 * The newer sock_setupcalls() KPI should be used instead to set
1306 * the read and write callbacks and their respective parameters.
1308 socket_lock(sock
, 1);
1309 #if (defined(__arm__) || defined(__arm64__))
1310 sock_setupcalls_locked(sock
, callback
, context
, callback
, context
, 0);
1311 #else /* (defined(__arm__) || defined(__arm64__)) */
1312 sock_setupcalls_locked(sock
, callback
, context
, NULL
, NULL
, 0);
1313 #endif /* (defined(__arm__) || defined(__arm64__)) */
1314 socket_unlock(sock
, 1);
1320 sock_setupcalls(socket_t sock
, sock_upcall rcallback
, void *rcontext
,
1321 sock_upcall wcallback
, void *wcontext
)
1328 * Note that we don't wait for any in progress upcall to complete.
1330 socket_lock(sock
, 1);
1331 sock_setupcalls_locked(sock
, rcallback
, rcontext
, wcallback
, wcontext
, 0);
1332 socket_unlock(sock
, 1);
1338 sock_catchevents_locked(socket_t sock
, sock_evupcall ecallback
, void *econtext
,
1341 socket_lock_assert_owned(sock
);
1344 * Note that we don't wait for any in progress upcall to complete.
1346 if (ecallback
!= NULL
) {
1347 sock
->so_event
= ecallback
;
1348 sock
->so_eventarg
= econtext
;
1349 sock
->so_eventmask
= (uint32_t)emask
;
1351 sock
->so_event
= sonullevent
;
1352 sock
->so_eventarg
= NULL
;
1353 sock
->so_eventmask
= 0;
1358 sock_catchevents(socket_t sock
, sock_evupcall ecallback
, void *econtext
,
1365 socket_lock(sock
, 1);
1366 sock_catchevents_locked(sock
, ecallback
, econtext
, emask
);
1367 socket_unlock(sock
, 1);
1373 * Returns true whether or not a socket belongs to the kernel.
1376 sock_iskernel(socket_t so
)
1378 return so
&& so
->last_pid
== 0;