2 * Copyright (c) 2003-2016 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 <netinet/in.h>
48 #include <libkern/OSAtomic.h>
50 static errno_t
sock_send_internal(socket_t
, const struct msghdr
*,
51 mbuf_t
, int, size_t *);
52 static void sock_setupcalls_common(socket_t
, sock_upcall
, void *,
56 sock_accept(socket_t sock
, struct sockaddr
*from
, int fromlen
, int flags
,
57 sock_upcall callback
, void *cookie
, socket_t
*new_sock
)
60 struct socket
*new_so
;
61 lck_mtx_t
*mutex_held
;
65 if (sock
== NULL
|| new_sock
== NULL
)
69 if ((sock
->so_options
& SO_ACCEPTCONN
) == 0) {
70 socket_unlock(sock
, 1);
73 if ((flags
& ~(MSG_DONTWAIT
)) != 0) {
74 socket_unlock(sock
, 1);
77 if (((flags
& MSG_DONTWAIT
) != 0 || (sock
->so_state
& SS_NBIO
) != 0) &&
78 sock
->so_comp
.tqh_first
== NULL
) {
79 socket_unlock(sock
, 1);
83 if (sock
->so_proto
->pr_getlock
!= NULL
) {
84 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, 0);
87 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
91 while (TAILQ_EMPTY(&sock
->so_comp
) && sock
->so_error
== 0) {
92 if (sock
->so_state
& SS_CANTRCVMORE
) {
93 sock
->so_error
= ECONNABORTED
;
96 error
= msleep((caddr_t
)&sock
->so_timeo
, mutex_held
,
97 PSOCK
| PCATCH
, "sock_accept", NULL
);
99 socket_unlock(sock
, 1);
103 if (sock
->so_error
!= 0) {
104 error
= sock
->so_error
;
106 socket_unlock(sock
, 1);
110 new_so
= TAILQ_FIRST(&sock
->so_comp
);
111 TAILQ_REMOVE(&sock
->so_comp
, new_so
, so_list
);
112 new_so
->so_state
&= ~SS_COMP
;
113 new_so
->so_head
= NULL
;
117 * Pass the pre-accepted socket to any interested socket filter(s).
118 * Upon failure, the socket would have been closed by the callee.
120 if (new_so
->so_filt
!= NULL
) {
122 * Temporarily drop the listening socket's lock before we
123 * hand off control over to the socket filter(s), but keep
124 * a reference so that it won't go away. We'll grab it
125 * again once we're done with the filter(s).
127 socket_unlock(sock
, 0);
128 if ((error
= soacceptfilter(new_so
, sock
)) != 0) {
129 /* Drop reference on listening socket */
133 socket_lock(sock
, 0);
137 lck_mtx_assert(new_so
->so_proto
->pr_getlock(new_so
, 0),
138 LCK_MTX_ASSERT_NOTOWNED
);
139 socket_lock(new_so
, 1);
142 (void) soacceptlock(new_so
, &sa
, 0);
144 socket_unlock(sock
, 1); /* release the head */
146 /* see comments in sock_setupcall() */
147 if (callback
!= NULL
) {
148 sock_setupcalls_common(new_so
, callback
, cookie
, NULL
, NULL
);
151 if (sa
!= NULL
&& from
!= NULL
) {
152 if (fromlen
> sa
->sa_len
)
153 fromlen
= sa
->sa_len
;
154 memcpy(from
, sa
, fromlen
);
160 * If the socket has been marked as inactive by sosetdefunct(),
161 * disallow further operations on it.
163 if (new_so
->so_flags
& SOF_DEFUNCT
) {
164 (void) sodefunct(current_proc(), new_so
,
165 SHUTDOWN_SOCKET_LEVEL_DISCONNECT_INTERNAL
);
169 socket_unlock(new_so
, 1);
174 sock_bind(socket_t sock
, const struct sockaddr
*to
)
177 struct sockaddr
*sa
= NULL
;
178 struct sockaddr_storage ss
;
179 boolean_t want_free
= TRUE
;
181 if (sock
== NULL
|| to
== NULL
)
184 if (to
->sa_len
> sizeof (ss
)) {
185 MALLOC(sa
, struct sockaddr
*, to
->sa_len
, M_SONAME
, M_WAITOK
);
189 sa
= (struct sockaddr
*)&ss
;
192 memcpy(sa
, to
, to
->sa_len
);
194 error
= sobindlock(sock
, sa
, 1); /* will lock socket */
196 if (sa
!= NULL
&& want_free
== TRUE
)
203 sock_connect(socket_t sock
, const struct sockaddr
*to
, int flags
)
206 lck_mtx_t
*mutex_held
;
207 struct sockaddr
*sa
= NULL
;
208 struct sockaddr_storage ss
;
209 boolean_t want_free
= TRUE
;
211 if (sock
== NULL
|| to
== NULL
)
214 if (to
->sa_len
> sizeof (ss
)) {
215 MALLOC(sa
, struct sockaddr
*, to
->sa_len
, M_SONAME
,
216 (flags
& MSG_DONTWAIT
) ? M_NOWAIT
: M_WAITOK
);
220 sa
= (struct sockaddr
*)&ss
;
223 memcpy(sa
, to
, to
->sa_len
);
225 socket_lock(sock
, 1);
227 if ((sock
->so_state
& SS_ISCONNECTING
) &&
228 ((sock
->so_state
& SS_NBIO
) != 0 || (flags
& MSG_DONTWAIT
) != 0)) {
232 error
= soconnectlock(sock
, sa
, 0);
234 if ((sock
->so_state
& SS_ISCONNECTING
) &&
235 ((sock
->so_state
& SS_NBIO
) != 0 ||
236 (flags
& MSG_DONTWAIT
) != 0)) {
241 if (sock
->so_proto
->pr_getlock
!= NULL
)
242 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, 0);
244 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
246 while ((sock
->so_state
& SS_ISCONNECTING
) &&
247 sock
->so_error
== 0) {
248 error
= msleep((caddr_t
)&sock
->so_timeo
,
249 mutex_held
, PSOCK
| PCATCH
, "sock_connect", NULL
);
255 error
= sock
->so_error
;
259 sock
->so_state
&= ~SS_ISCONNECTING
;
262 socket_unlock(sock
, 1);
264 if (sa
!= NULL
&& want_free
== TRUE
)
271 sock_connectwait(socket_t sock
, const struct timeval
*tv
)
273 lck_mtx_t
*mutex_held
;
277 socket_lock(sock
, 1);
279 /* Check if we're already connected or if we've already errored out */
280 if ((sock
->so_state
& SS_ISCONNECTING
) == 0 || sock
->so_error
!= 0) {
281 if (sock
->so_error
!= 0) {
282 retval
= sock
->so_error
;
285 if ((sock
->so_state
& SS_ISCONNECTED
) != 0)
293 /* copied translation from timeval to hertz from SO_RCVTIMEO handling */
294 if (tv
->tv_sec
< 0 || tv
->tv_sec
> SHRT_MAX
/ hz
||
295 tv
->tv_usec
< 0 || tv
->tv_usec
>= 1000000) {
300 ts
.tv_sec
= tv
->tv_sec
;
301 ts
.tv_nsec
= (tv
->tv_usec
* (integer_t
)NSEC_PER_USEC
);
302 if ((ts
.tv_sec
+ (ts
.tv_nsec
/(long)NSEC_PER_SEC
))/100 > SHRT_MAX
) {
307 if (sock
->so_proto
->pr_getlock
!= NULL
)
308 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, 0);
310 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
312 msleep((caddr_t
)&sock
->so_timeo
, mutex_held
,
313 PSOCK
, "sock_connectwait", &ts
);
315 /* Check if we're still waiting to connect */
316 if ((sock
->so_state
& SS_ISCONNECTING
) && sock
->so_error
== 0) {
317 retval
= EINPROGRESS
;
321 if (sock
->so_error
!= 0) {
322 retval
= sock
->so_error
;
327 socket_unlock(sock
, 1);
332 sock_nointerrupt(socket_t sock
, int on
)
334 socket_lock(sock
, 1);
337 sock
->so_rcv
.sb_flags
|= SB_NOINTR
; /* This isn't safe */
338 sock
->so_snd
.sb_flags
|= SB_NOINTR
; /* This isn't safe */
340 sock
->so_rcv
.sb_flags
&= ~SB_NOINTR
; /* This isn't safe */
341 sock
->so_snd
.sb_flags
&= ~SB_NOINTR
; /* This isn't safe */
344 socket_unlock(sock
, 1);
350 sock_getpeername(socket_t sock
, struct sockaddr
*peername
, int peernamelen
)
353 struct sockaddr
*sa
= NULL
;
355 if (sock
== NULL
|| peername
== NULL
|| peernamelen
< 0)
358 socket_lock(sock
, 1);
359 if (!(sock
->so_state
& (SS_ISCONNECTED
|SS_ISCONFIRMING
))) {
360 socket_unlock(sock
, 1);
363 error
= sogetaddr_locked(sock
, &sa
, 1);
364 socket_unlock(sock
, 1);
366 if (peernamelen
> sa
->sa_len
)
367 peernamelen
= sa
->sa_len
;
368 memcpy(peername
, sa
, peernamelen
);
375 sock_getsockname(socket_t sock
, struct sockaddr
*sockname
, int socknamelen
)
378 struct sockaddr
*sa
= NULL
;
380 if (sock
== NULL
|| sockname
== NULL
|| socknamelen
< 0)
383 socket_lock(sock
, 1);
384 error
= sogetaddr_locked(sock
, &sa
, 0);
385 socket_unlock(sock
, 1);
387 if (socknamelen
> sa
->sa_len
)
388 socknamelen
= sa
->sa_len
;
389 memcpy(sockname
, sa
, socknamelen
);
395 __private_extern__
int
396 sogetaddr_locked(struct socket
*so
, struct sockaddr
**psa
, int peer
)
400 if (so
== NULL
|| psa
== NULL
)
404 error
= peer
? so
->so_proto
->pr_usrreqs
->pru_peeraddr(so
, psa
) :
405 so
->so_proto
->pr_usrreqs
->pru_sockaddr(so
, psa
);
407 if (error
== 0 && *psa
== NULL
) {
409 } else if (error
!= 0 && *psa
!= NULL
) {
410 FREE(*psa
, M_SONAME
);
417 sock_getaddr(socket_t sock
, struct sockaddr
**psa
, int peer
)
421 if (sock
== NULL
|| psa
== NULL
)
424 socket_lock(sock
, 1);
425 error
= sogetaddr_locked(sock
, psa
, peer
);
426 socket_unlock(sock
, 1);
432 sock_freeaddr(struct sockaddr
*sa
)
439 sock_getsockopt(socket_t sock
, int level
, int optname
, void *optval
,
445 if (sock
== NULL
|| optval
== NULL
|| optlen
== NULL
)
448 sopt
.sopt_dir
= SOPT_GET
;
449 sopt
.sopt_level
= level
;
450 sopt
.sopt_name
= optname
;
451 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
452 sopt
.sopt_valsize
= *optlen
;
453 sopt
.sopt_p
= kernproc
;
454 error
= sogetoptlock(sock
, &sopt
, 1); /* will lock socket */
456 *optlen
= sopt
.sopt_valsize
;
461 sock_ioctl(socket_t sock
, unsigned long request
, void *argp
)
463 return (soioctl(sock
, request
, argp
, kernproc
)); /* will lock socket */
467 sock_setsockopt(socket_t sock
, int level
, int optname
, const void *optval
,
472 if (sock
== NULL
|| optval
== NULL
)
475 sopt
.sopt_dir
= SOPT_SET
;
476 sopt
.sopt_level
= level
;
477 sopt
.sopt_name
= optname
;
478 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
479 sopt
.sopt_valsize
= optlen
;
480 sopt
.sopt_p
= kernproc
;
481 return (sosetoptlock(sock
, &sopt
, 1)); /* will lock socket */
485 * This follows the recommended mappings between DSCP code points
486 * and WMM access classes.
488 static u_int32_t
so_tc_from_dscp(u_int8_t dscp
);
490 so_tc_from_dscp(u_int8_t dscp
)
494 if (dscp
>= 0x30 && dscp
<= 0x3f)
496 else if (dscp
>= 0x20 && dscp
<= 0x2f)
498 else if (dscp
>= 0x08 && dscp
<= 0x17)
507 sock_settclassopt(socket_t sock
, const void *optval
, size_t optlen
)
513 if (sock
== NULL
|| optval
== NULL
|| optlen
!= sizeof (int))
516 socket_lock(sock
, 1);
517 if (!(sock
->so_state
& SS_ISCONNECTED
)) {
519 * If the socket is not connected then we don't know
520 * if the destination is on LAN or not. Skip
521 * setting traffic class in this case
527 if (sock
->so_proto
== NULL
|| sock
->so_proto
->pr_domain
== NULL
||
528 sock
->so_pcb
== NULL
) {
534 * Set the socket traffic class based on the passed DSCP code point
535 * regardless of the scope of the destination
537 sotc
= so_tc_from_dscp((*(const int *)optval
) >> 2);
539 sopt
.sopt_dir
= SOPT_SET
;
540 sopt
.sopt_val
= CAST_USER_ADDR_T(&sotc
);
541 sopt
.sopt_valsize
= sizeof (sotc
);
542 sopt
.sopt_p
= kernproc
;
543 sopt
.sopt_level
= SOL_SOCKET
;
544 sopt
.sopt_name
= SO_TRAFFIC_CLASS
;
546 error
= sosetoptlock(sock
, &sopt
, 0); /* already locked */
549 printf("%s: sosetopt SO_TRAFFIC_CLASS failed %d\n",
555 * Check if the destination address is LAN or link local address.
556 * We do not want to set traffic class bits if the destination
559 if (!so_isdstlocal(sock
))
562 sopt
.sopt_dir
= SOPT_SET
;
563 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
564 sopt
.sopt_valsize
= optlen
;
565 sopt
.sopt_p
= kernproc
;
567 switch (SOCK_DOM(sock
)) {
569 sopt
.sopt_level
= IPPROTO_IP
;
570 sopt
.sopt_name
= IP_TOS
;
573 sopt
.sopt_level
= IPPROTO_IPV6
;
574 sopt
.sopt_name
= IPV6_TCLASS
;
581 error
= sosetoptlock(sock
, &sopt
, 0); /* already locked */
582 socket_unlock(sock
, 1);
585 socket_unlock(sock
, 1);
590 sock_gettclassopt(socket_t sock
, void *optval
, size_t *optlen
)
595 if (sock
== NULL
|| optval
== NULL
|| optlen
== NULL
)
598 sopt
.sopt_dir
= SOPT_GET
;
599 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
600 sopt
.sopt_valsize
= *optlen
;
601 sopt
.sopt_p
= kernproc
;
603 socket_lock(sock
, 1);
604 if (sock
->so_proto
== NULL
|| sock
->so_proto
->pr_domain
== NULL
) {
605 socket_unlock(sock
, 1);
609 switch (SOCK_DOM(sock
)) {
611 sopt
.sopt_level
= IPPROTO_IP
;
612 sopt
.sopt_name
= IP_TOS
;
615 sopt
.sopt_level
= IPPROTO_IPV6
;
616 sopt
.sopt_name
= IPV6_TCLASS
;
619 socket_unlock(sock
, 1);
623 error
= sogetoptlock(sock
, &sopt
, 0); /* already locked */
624 socket_unlock(sock
, 1);
626 *optlen
= sopt
.sopt_valsize
;
631 sock_listen(socket_t sock
, int backlog
)
636 return (solisten(sock
, backlog
)); /* will lock socket */
640 sock_receive_internal(socket_t sock
, struct msghdr
*msg
, mbuf_t
*data
,
641 int flags
, size_t *recvdlen
)
644 struct mbuf
*control
= NULL
;
647 struct sockaddr
*fromsa
= NULL
;
648 char uio_buf
[ UIO_SIZEOF((msg
!= NULL
) ? msg
->msg_iovlen
: 0) ];
653 auio
= uio_createwithbuffer(((msg
!= NULL
) ? msg
->msg_iovlen
: 0),
654 0, UIO_SYSSPACE
, UIO_READ
, &uio_buf
[0], sizeof (uio_buf
));
655 if (msg
!= NULL
&& data
== NULL
) {
657 struct iovec
*tempp
= msg
->msg_iov
;
659 for (i
= 0; i
< msg
->msg_iovlen
; i
++) {
661 CAST_USER_ADDR_T((tempp
+ i
)->iov_base
),
662 (tempp
+ i
)->iov_len
);
664 if (uio_resid(auio
) < 0)
666 } else if (recvdlen
!= NULL
) {
667 uio_setresid(auio
, (uio_resid(auio
) + *recvdlen
));
669 length
= uio_resid(auio
);
671 if (recvdlen
!= NULL
)
674 /* let pru_soreceive handle the socket locking */
675 error
= sock
->so_proto
->pr_usrreqs
->pru_soreceive(sock
, &fromsa
, auio
,
676 data
, (msg
&& msg
->msg_control
) ? &control
: NULL
, &flags
);
680 if (recvdlen
!= NULL
)
681 *recvdlen
= length
- uio_resid(auio
);
683 msg
->msg_flags
= flags
;
685 if (msg
->msg_name
!= NULL
) {
687 salen
= msg
->msg_namelen
;
688 if (msg
->msg_namelen
> 0 && fromsa
!= NULL
) {
689 salen
= MIN(salen
, fromsa
->sa_len
);
690 memcpy(msg
->msg_name
, fromsa
,
691 msg
->msg_namelen
> fromsa
->sa_len
?
692 fromsa
->sa_len
: msg
->msg_namelen
);
696 if (msg
->msg_control
!= NULL
) {
697 struct mbuf
*m
= control
;
698 u_char
*ctlbuf
= msg
->msg_control
;
699 int clen
= msg
->msg_controllen
;
701 msg
->msg_controllen
= 0;
703 while (m
!= NULL
&& clen
> 0) {
706 if (clen
>= m
->m_len
) {
709 msg
->msg_flags
|= MSG_CTRUNC
;
712 memcpy(ctlbuf
, mtod(m
, caddr_t
), tocopy
);
717 msg
->msg_controllen
=
718 (uintptr_t)ctlbuf
- (uintptr_t)msg
->msg_control
;
726 FREE(fromsa
, M_SONAME
);
731 sock_receive(socket_t sock
, struct msghdr
*msg
, int flags
, size_t *recvdlen
)
733 if ((msg
== NULL
) || (msg
->msg_iovlen
< 1) ||
734 (msg
->msg_iov
[0].iov_len
== 0) ||
735 (msg
->msg_iov
[0].iov_base
== NULL
))
738 return (sock_receive_internal(sock
, msg
, NULL
, flags
, recvdlen
));
742 sock_receivembuf(socket_t sock
, struct msghdr
*msg
, mbuf_t
*data
, int flags
,
745 if (data
== NULL
|| recvlen
== 0 || *recvlen
<= 0 || (msg
!= NULL
&&
746 (msg
->msg_iov
!= NULL
|| msg
->msg_iovlen
!= 0)))
749 return (sock_receive_internal(sock
, msg
, data
, flags
, recvlen
));
753 sock_send_internal(socket_t sock
, const struct msghdr
*msg
, mbuf_t data
,
754 int flags
, size_t *sentlen
)
757 struct mbuf
*control
= NULL
;
760 char uio_buf
[ UIO_SIZEOF((msg
!= NULL
? msg
->msg_iovlen
: 1)) ];
767 if (data
== NULL
&& msg
!= NULL
) {
768 struct iovec
*tempp
= msg
->msg_iov
;
770 auio
= uio_createwithbuffer(msg
->msg_iovlen
, 0,
771 UIO_SYSSPACE
, UIO_WRITE
, &uio_buf
[0], sizeof (uio_buf
));
775 for (i
= 0; i
< msg
->msg_iovlen
; i
++) {
777 CAST_USER_ADDR_T((tempp
+ i
)->iov_base
),
778 (tempp
+ i
)->iov_len
);
781 if (uio_resid(auio
) < 0) {
792 datalen
= uio_resid(auio
);
794 datalen
= data
->m_pkthdr
.len
;
796 if (msg
!= NULL
&& msg
->msg_control
) {
797 if ((size_t)msg
->msg_controllen
< sizeof (struct cmsghdr
)) {
802 if ((size_t)msg
->msg_controllen
> MLEN
) {
807 control
= m_get(M_NOWAIT
, MT_CONTROL
);
808 if (control
== NULL
) {
812 memcpy(mtod(control
, caddr_t
), msg
->msg_control
,
813 msg
->msg_controllen
);
814 control
->m_len
= msg
->msg_controllen
;
817 error
= sock
->so_proto
->pr_usrreqs
->pru_sosend(sock
, msg
!= NULL
?
818 (struct sockaddr
*)msg
->msg_name
: NULL
, auio
, data
,
822 * Residual data is possible in the case of IO vectors but not
823 * in the mbuf case since the latter is treated as atomic send.
824 * If pru_sosend() consumed a portion of the iovecs data and
825 * the error returned is transient, treat it as success; this
826 * is consistent with sendit() behavior.
828 if (auio
!= NULL
&& uio_resid(auio
) != datalen
&&
829 (error
== ERESTART
|| error
== EINTR
|| error
== EWOULDBLOCK
))
832 if (error
== 0 && sentlen
!= NULL
) {
834 *sentlen
= datalen
- uio_resid(auio
);
842 * In cases where we detect an error before returning, we need to
843 * free the mbuf chain if there is one. sosend (and pru_sosend) will
844 * free the mbuf chain if they encounter an error.
857 sock_send(socket_t sock
, const struct msghdr
*msg
, int flags
, size_t *sentlen
)
859 if (msg
== NULL
|| msg
->msg_iov
== NULL
|| msg
->msg_iovlen
< 1)
862 return (sock_send_internal(sock
, msg
, NULL
, flags
, sentlen
));
866 sock_sendmbuf(socket_t sock
, const struct msghdr
*msg
, mbuf_t data
,
867 int flags
, size_t *sentlen
)
869 if (data
== NULL
|| (msg
!= NULL
&& (msg
->msg_iov
!= NULL
||
870 msg
->msg_iovlen
!= 0))) {
875 return (sock_send_internal(sock
, msg
, data
, flags
, sentlen
));
879 sock_shutdown(socket_t sock
, int how
)
884 return (soshutdown(sock
, how
));
889 sock_socket(int domain
, int type
, int protocol
, sock_upcall callback
,
890 void *context
, socket_t
*new_so
)
897 /* socreate will create an initial so_count */
898 error
= socreate(domain
, new_so
, type
, protocol
);
900 /* see comments in sock_setupcall() */
901 if (callback
!= NULL
) {
902 sock_setupcalls_common(*new_so
, callback
, context
,
906 * last_pid and last_upid should be zero for sockets
907 * created using sock_socket
909 (*new_so
)->last_pid
= 0;
910 (*new_so
)->last_upid
= 0;
916 sock_close(socket_t sock
)
924 /* Do we want this to be APPLE_PRIVATE API?: YES (LD 12/23/04) */
926 sock_retain(socket_t sock
)
931 socket_lock(sock
, 1);
932 sock
->so_retaincnt
++;
933 sock
->so_usecount
++; /* add extra reference for holding the socket */
934 socket_unlock(sock
, 1);
937 /* Do we want this to be APPLE_PRIVATE API? */
939 sock_release(socket_t sock
)
944 socket_lock(sock
, 1);
945 if (sock
->so_upcallusecount
> 0)
946 soclose_wait_locked(sock
);
948 sock
->so_retaincnt
--;
949 if (sock
->so_retaincnt
< 0) {
950 panic("%s: negative retain count (%d) for sock=%p\n",
951 __func__
, sock
->so_retaincnt
, sock
);
955 * Check SS_NOFDREF in case a close happened as sock_retain()
956 * was grabbing the lock
958 if ((sock
->so_retaincnt
== 0) && (sock
->so_usecount
== 2) &&
959 (!(sock
->so_state
& SS_NOFDREF
) ||
960 (sock
->so_flags
& SOF_MP_SUBFLOW
))) {
961 /* close socket only if the FD is not holding it */
962 soclose_locked(sock
);
964 /* remove extra reference holding the socket */
965 VERIFY(sock
->so_usecount
> 1);
968 socket_unlock(sock
, 1);
972 sock_setpriv(socket_t sock
, int on
)
977 socket_lock(sock
, 1);
979 sock
->so_state
|= SS_PRIV
;
981 sock
->so_state
&= ~SS_PRIV
;
982 socket_unlock(sock
, 1);
987 sock_isconnected(socket_t sock
)
991 socket_lock(sock
, 1);
992 retval
= ((sock
->so_state
& SS_ISCONNECTED
) ? 1 : 0);
993 socket_unlock(sock
, 1);
998 sock_isnonblocking(socket_t sock
)
1002 socket_lock(sock
, 1);
1003 retval
= ((sock
->so_state
& SS_NBIO
) ? 1 : 0);
1004 socket_unlock(sock
, 1);
1009 sock_gettype(socket_t sock
, int *outDomain
, int *outType
, int *outProtocol
)
1011 socket_lock(sock
, 1);
1012 if (outDomain
!= NULL
)
1013 *outDomain
= SOCK_DOM(sock
);
1014 if (outType
!= NULL
)
1015 *outType
= sock
->so_type
;
1016 if (outProtocol
!= NULL
)
1017 *outProtocol
= SOCK_PROTO(sock
);
1018 socket_unlock(sock
, 1);
1023 * Return the listening socket of a pre-accepted socket. It returns the
1024 * listener (so_head) value of a given socket. This is intended to be
1025 * called by a socket filter during a filter attach (sf_attach) callback.
1026 * The value returned by this routine is safe to be used only in the
1027 * context of that callback, because we hold the listener's lock across
1028 * the sflt_initsock() call.
1031 sock_getlistener(socket_t sock
)
1033 return (sock
->so_head
);
1037 sock_set_tcp_stream_priority(socket_t sock
)
1039 if ((SOCK_DOM(sock
) == PF_INET
|| SOCK_DOM(sock
) == PF_INET6
) &&
1040 SOCK_TYPE(sock
) == SOCK_STREAM
) {
1041 set_tcp_stream_priority(sock
);
1046 * Caller must have ensured socket is valid and won't be going away.
1049 socket_set_traffic_mgt_flags_locked(socket_t sock
, u_int8_t flags
)
1051 u_int32_t soflags1
= 0;
1053 if ((flags
& TRAFFIC_MGT_SO_BACKGROUND
))
1054 soflags1
|= SOF1_TRAFFIC_MGT_SO_BACKGROUND
;
1055 if ((flags
& TRAFFIC_MGT_TCP_RECVBG
))
1056 soflags1
|= SOF1_TRAFFIC_MGT_TCP_RECVBG
;
1058 (void) OSBitOrAtomic(soflags1
, &sock
->so_flags1
);
1060 sock_set_tcp_stream_priority(sock
);
1064 socket_set_traffic_mgt_flags(socket_t sock
, u_int8_t flags
)
1066 socket_lock(sock
, 1);
1067 socket_set_traffic_mgt_flags_locked(sock
, flags
);
1068 socket_unlock(sock
, 1);
1072 * Caller must have ensured socket is valid and won't be going away.
1075 socket_clear_traffic_mgt_flags_locked(socket_t sock
, u_int8_t flags
)
1077 u_int32_t soflags1
= 0;
1079 if ((flags
& TRAFFIC_MGT_SO_BACKGROUND
))
1080 soflags1
|= SOF1_TRAFFIC_MGT_SO_BACKGROUND
;
1081 if ((flags
& TRAFFIC_MGT_TCP_RECVBG
))
1082 soflags1
|= SOF1_TRAFFIC_MGT_TCP_RECVBG
;
1084 (void) OSBitAndAtomic(~soflags1
, &sock
->so_flags1
);
1086 sock_set_tcp_stream_priority(sock
);
1090 socket_clear_traffic_mgt_flags(socket_t sock
, u_int8_t flags
)
1092 socket_lock(sock
, 1);
1093 socket_clear_traffic_mgt_flags_locked(sock
, flags
);
1094 socket_unlock(sock
, 1);
1099 * Caller must have ensured socket is valid and won't be going away.
1102 socket_defunct(struct proc
*p
, socket_t so
, int level
)
1106 if (level
!= SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC
&&
1107 level
!= SHUTDOWN_SOCKET_LEVEL_DISCONNECT_ALL
)
1112 * SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC level is meant to tear down
1113 * all of mDNSResponder IPC sockets, currently those of AF_UNIX; note
1114 * that this is an implementation artifact of mDNSResponder. We do
1115 * a quick test against the socket buffers for SB_UNIX, since that
1116 * would have been set by unp_attach() at socket creation time.
1118 if (level
== SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC
&&
1119 (so
->so_rcv
.sb_flags
& so
->so_snd
.sb_flags
& SB_UNIX
) != SB_UNIX
) {
1120 socket_unlock(so
, 1);
1121 return (EOPNOTSUPP
);
1123 retval
= sosetdefunct(p
, so
, level
, TRUE
);
1125 retval
= sodefunct(p
, so
, level
);
1126 socket_unlock(so
, 1);
1131 sock_setupcalls_common(socket_t sock
, sock_upcall rcallback
, void *rcontext
,
1132 sock_upcall wcallback
, void *wcontext
)
1134 if (rcallback
!= NULL
) {
1135 sock
->so_rcv
.sb_flags
|= SB_UPCALL
;
1136 sock
->so_rcv
.sb_upcall
= rcallback
;
1137 sock
->so_rcv
.sb_upcallarg
= rcontext
;
1139 sock
->so_rcv
.sb_flags
&= ~SB_UPCALL
;
1140 sock
->so_rcv
.sb_upcall
= NULL
;
1141 sock
->so_rcv
.sb_upcallarg
= NULL
;
1144 if (wcallback
!= NULL
) {
1145 sock
->so_snd
.sb_flags
|= SB_UPCALL
;
1146 sock
->so_snd
.sb_upcall
= wcallback
;
1147 sock
->so_snd
.sb_upcallarg
= wcontext
;
1149 sock
->so_snd
.sb_flags
&= ~SB_UPCALL
;
1150 sock
->so_snd
.sb_upcall
= NULL
;
1151 sock
->so_snd
.sb_upcallarg
= NULL
;
1156 sock_setupcall(socket_t sock
, sock_upcall callback
, void *context
)
1162 * Note that we don't wait for any in progress upcall to complete.
1163 * On embedded, sock_setupcall() causes both read and write
1164 * callbacks to be set; on desktop, only read callback is set
1165 * to maintain legacy KPI behavior.
1167 * The newer sock_setupcalls() KPI should be used instead to set
1168 * the read and write callbacks and their respective parameters.
1170 socket_lock(sock
, 1);
1171 sock_setupcalls_common(sock
, callback
, context
, NULL
, NULL
);
1172 socket_unlock(sock
, 1);
1178 sock_setupcalls(socket_t sock
, sock_upcall rcallback
, void *rcontext
,
1179 sock_upcall wcallback
, void *wcontext
)
1185 * Note that we don't wait for any in progress upcall to complete.
1187 socket_lock(sock
, 1);
1188 sock_setupcalls_common(sock
, rcallback
, rcontext
, wcallback
, wcontext
);
1189 socket_unlock(sock
, 1);
1195 sock_catchevents(socket_t sock
, sock_evupcall ecallback
, void *econtext
,
1202 * Note that we don't wait for any in progress upcall to complete.
1204 socket_lock(sock
, 1);
1205 if (ecallback
!= NULL
) {
1206 sock
->so_event
= ecallback
;
1207 sock
->so_eventarg
= econtext
;
1208 sock
->so_eventmask
= emask
;
1210 sock
->so_event
= sonullevent
;
1211 sock
->so_eventarg
= NULL
;
1212 sock
->so_eventmask
= 0;
1214 socket_unlock(sock
, 1);
1220 * Returns true whether or not a socket belongs to the kernel.
1223 sock_iskernel(socket_t so
)
1225 return (so
&& so
->last_pid
== 0);