]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kpi_socket.c
2 * Copyright (c) 2003-2007 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/fcntl.h>
43 #include <sys/filio.h>
44 #include <sys/uio_internal.h>
45 #include <kern/lock.h>
47 extern int soclose_locked(struct socket
*so
);
48 extern void soclose_wait_locked(struct socket
*so
);
50 errno_t
sock_send_internal(
52 const struct msghdr
*msg
,
57 typedef void (*so_upcall
)(struct socket
*, caddr_t
, int );
63 struct sockaddr
*from
,
71 struct socket
*new_so
;
72 lck_mtx_t
*mutex_held
;
76 if (sock
== NULL
|| new_sock
== NULL
) return EINVAL
;
78 if ((sock
->so_options
& SO_ACCEPTCONN
) == 0) {
79 socket_unlock(sock
, 1);
82 if ((flags
& ~(MSG_DONTWAIT
)) != 0) {
83 socket_unlock(sock
, 1);
86 if (((flags
& MSG_DONTWAIT
) != 0 || (sock
->so_state
& SS_NBIO
) != 0) &&
87 sock
->so_comp
.tqh_first
== NULL
) {
88 socket_unlock(sock
, 1);
92 if (sock
->so_proto
->pr_getlock
!= NULL
) {
93 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, 0);
97 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
101 while (TAILQ_EMPTY(&sock
->so_comp
) && sock
->so_error
== 0) {
102 if (sock
->so_state
& SS_CANTRCVMORE
) {
103 sock
->so_error
= ECONNABORTED
;
106 error
= msleep((caddr_t
)&sock
->so_timeo
, mutex_held
, PSOCK
| PCATCH
, "sock_accept", NULL
);
108 socket_unlock(sock
, 1);
112 if (sock
->so_error
) {
113 error
= sock
->so_error
;
115 socket_unlock(sock
, 1);
119 new_so
= TAILQ_FIRST(&sock
->so_comp
);
120 TAILQ_REMOVE(&sock
->so_comp
, new_so
, so_list
);
124 * Pass the pre-accepted socket to any interested socket filter(s).
125 * Upon failure, the socket would have been closed by the callee.
127 if (new_so
->so_filt
!= NULL
) {
129 * Temporarily drop the listening socket's lock before we
130 * hand off control over to the socket filter(s), but keep
131 * a reference so that it won't go away. We'll grab it
132 * again once we're done with the filter(s).
134 socket_unlock(sock
, 0);
135 if ((error
= soacceptfilter(new_so
)) != 0) {
136 /* Drop reference on listening socket */
140 socket_lock(sock
, 0);
144 lck_mtx_assert(new_so
->so_proto
->pr_getlock(new_so
, 0),
145 LCK_MTX_ASSERT_NOTOWNED
);
146 socket_lock(new_so
, 1);
149 new_so
->so_state
&= ~SS_COMP
;
150 new_so
->so_head
= NULL
;
151 (void) soacceptlock(new_so
, &sa
, 0);
153 socket_unlock(sock
, 1); /* release the head */
156 new_so
->so_upcall
= (so_upcall
) callback
;
157 new_so
->so_upcallarg
= cookie
;
158 new_so
->so_rcv
.sb_flags
|= SB_UPCALL
;
160 new_so
->so_snd
.sb_flags
|= SB_UPCALL
;
166 if (fromlen
> sa
->sa_len
) fromlen
= sa
->sa_len
;
167 memcpy(from
, sa
, fromlen
);
169 if (sa
) FREE(sa
, M_SONAME
);
172 * If the socket has been marked as inactive by soacceptfilter(),
173 * disallow further operations on it. We explicitly call shutdown
174 * on both data directions to ensure that SS_CANT{RCV,SEND}MORE
175 * states are set for the socket. This would also flush out data
176 * hanging off the receive list of this socket.
178 if (new_so
->so_flags
& SOF_DEFUNCT
) {
179 (void) soshutdownlock(new_so
, SHUT_RD
);
180 (void) soshutdownlock(new_so
, SHUT_WR
);
181 (void) sodisconnectlocked(new_so
);
186 socket_unlock(new_so
, 1);
193 const struct sockaddr
*to
)
195 if (sock
== NULL
|| to
== NULL
) return EINVAL
;
197 return sobind(sock
, (struct sockaddr
*)to
);
203 const struct sockaddr
*to
,
207 lck_mtx_t
*mutex_held
;
209 if (sock
== NULL
|| to
== NULL
) return EINVAL
;
211 socket_lock(sock
, 1);
213 if ((sock
->so_state
& SS_ISCONNECTING
) &&
214 ((sock
->so_state
& SS_NBIO
) != 0 ||
215 (flags
& MSG_DONTWAIT
) != 0)) {
216 socket_unlock(sock
, 1);
219 error
= soconnectlock(sock
, (struct sockaddr
*)to
, 0);
221 if ((sock
->so_state
& SS_ISCONNECTING
) &&
222 ((sock
->so_state
& SS_NBIO
) != 0 || (flags
& MSG_DONTWAIT
) != 0)) {
223 socket_unlock(sock
, 1);
227 if (sock
->so_proto
->pr_getlock
!= NULL
)
228 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, 0);
230 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
232 while ((sock
->so_state
& SS_ISCONNECTING
) && sock
->so_error
== 0) {
233 error
= msleep((caddr_t
)&sock
->so_timeo
, mutex_held
, PSOCK
| PCATCH
,
234 "sock_connect", NULL
);
240 error
= sock
->so_error
;
245 sock
->so_state
&= ~SS_ISCONNECTING
;
247 socket_unlock(sock
, 1);
254 const struct timeval
*tv
)
256 lck_mtx_t
* mutex_held
;
260 socket_lock(sock
, 1);
262 // Check if we're already connected or if we've already errored out
263 if ((sock
->so_state
& SS_ISCONNECTING
) == 0 || sock
->so_error
) {
264 if (sock
->so_error
) {
265 retval
= sock
->so_error
;
269 if ((sock
->so_state
& SS_ISCONNECTED
) != 0)
277 // copied translation from timeval to hertz from SO_RCVTIMEO handling
278 if (tv
->tv_sec
< 0 || tv
->tv_sec
> SHRT_MAX
/ hz
||
279 tv
->tv_usec
< 0 || tv
->tv_usec
>= 1000000) {
284 ts
.tv_sec
= tv
->tv_sec
;
285 ts
.tv_nsec
= (tv
->tv_usec
* NSEC_PER_USEC
);
286 if ( (ts
.tv_sec
+ (ts
.tv_nsec
/NSEC_PER_SEC
))/100 > SHRT_MAX
) {
291 if (sock
->so_proto
->pr_getlock
!= NULL
)
292 mutex_held
= (*sock
->so_proto
->pr_getlock
)(sock
, 0);
294 mutex_held
= sock
->so_proto
->pr_domain
->dom_mtx
;
296 msleep((caddr_t
)&sock
->so_timeo
, mutex_held
, PSOCK
, "sock_connectwait", &ts
);
298 // Check if we're still waiting to connect
299 if ((sock
->so_state
& SS_ISCONNECTING
) && sock
->so_error
== 0) {
300 retval
= EINPROGRESS
;
304 if (sock
->so_error
) {
305 retval
= sock
->so_error
;
310 socket_unlock(sock
, 1);
319 socket_lock(sock
, 1);
322 sock
->so_rcv
.sb_flags
|= SB_NOINTR
; // This isn't safe
323 sock
->so_snd
.sb_flags
|= SB_NOINTR
; // This isn't safe
326 sock
->so_rcv
.sb_flags
&= ~SB_NOINTR
; // This isn't safe
327 sock
->so_snd
.sb_flags
&= ~SB_NOINTR
; // This isn't safe
330 socket_unlock(sock
, 1);
336 sock_getpeername(socket_t sock
, struct sockaddr
*peername
, int peernamelen
)
339 struct sockaddr
*sa
= NULL
;
341 if (sock
== NULL
|| peername
== NULL
|| peernamelen
< 0)
344 socket_lock(sock
, 1);
345 if (!(sock
->so_state
& (SS_ISCONNECTED
|SS_ISCONFIRMING
))) {
346 socket_unlock(sock
, 1);
349 error
= sock_getaddr(sock
, &sa
, 1);
350 socket_unlock(sock
, 1);
352 if (peernamelen
> sa
->sa_len
)
353 peernamelen
= sa
->sa_len
;
354 memcpy(peername
, sa
, peernamelen
);
361 sock_getsockname(socket_t sock
, struct sockaddr
*sockname
, int socknamelen
)
364 struct sockaddr
*sa
= NULL
;
366 if (sock
== NULL
|| sockname
== NULL
|| socknamelen
< 0)
369 socket_lock(sock
, 1);
370 error
= sock_getaddr(sock
, &sa
, 0);
371 socket_unlock(sock
, 1);
373 if (socknamelen
> sa
->sa_len
)
374 socknamelen
= sa
->sa_len
;
375 memcpy(sockname
, sa
, socknamelen
);
382 sock_getaddr(socket_t sock
, struct sockaddr
**psa
, int peer
)
386 if (sock
== NULL
|| psa
== NULL
)
390 error
= peer
? sock
->so_proto
->pr_usrreqs
->pru_peeraddr(sock
, psa
) :
391 sock
->so_proto
->pr_usrreqs
->pru_sockaddr(sock
, psa
);
393 if (error
== 0 && *psa
== NULL
) {
395 } else if (error
!= 0 && *psa
!= NULL
) {
396 FREE(*psa
, M_SONAME
);
403 sock_freeaddr(struct sockaddr
*sa
)
420 if (sock
== NULL
|| optval
== NULL
|| optlen
== NULL
) return EINVAL
;
421 sopt
.sopt_dir
= SOPT_GET
;
422 sopt
.sopt_level
= level
;
423 sopt
.sopt_name
= optname
;
424 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
425 sopt
.sopt_valsize
= *optlen
;
427 error
= sogetopt(sock
, &sopt
); /* will lock socket */
428 if (error
== 0) *optlen
= sopt
.sopt_valsize
;
435 unsigned long request
,
438 return soioctl(sock
, request
, argp
, NULL
); /* will lock socket */
451 if (sock
== NULL
|| optval
== NULL
) return EINVAL
;
452 sopt
.sopt_dir
= SOPT_SET
;
453 sopt
.sopt_level
= level
;
454 sopt
.sopt_name
= optname
;
455 sopt
.sopt_val
= CAST_USER_ADDR_T(optval
);
456 sopt
.sopt_valsize
= optlen
;
458 return sosetopt(sock
, &sopt
); /* will lock socket */
466 if (sock
== NULL
) return EINVAL
;
467 return solisten(sock
, backlog
); /* will lock socket */
471 sock_receive_internal(
479 struct mbuf
*control
= NULL
;
482 struct sockaddr
*fromsa
;
483 char uio_buf
[ UIO_SIZEOF((msg
!= NULL
) ? msg
->msg_iovlen
: 0) ];
485 if (sock
== NULL
) return EINVAL
;
487 auio
= uio_createwithbuffer(((msg
!= NULL
) ? msg
->msg_iovlen
: 0),
488 0, UIO_SYSSPACE
, UIO_READ
,
489 &uio_buf
[0], sizeof(uio_buf
));
490 if (msg
&& data
== NULL
) {
492 struct iovec_32
*tempp
= (struct iovec_32
*) msg
->msg_iov
;
494 for (i
= 0; i
< msg
->msg_iovlen
; i
++) {
495 uio_addiov(auio
, CAST_USER_ADDR_T((tempp
+ i
)->iov_base
), (tempp
+ i
)->iov_len
);
497 if (uio_resid(auio
) < 0) return EINVAL
;
500 uio_setresid(auio
, (uio_resid(auio
) + *recvdlen
));
502 length
= uio_resid(auio
);
507 if (msg
&& msg
->msg_control
) {
508 if ((size_t)msg
->msg_controllen
< sizeof(struct cmsghdr
)) return EINVAL
;
509 if ((size_t)msg
->msg_controllen
> MLEN
) return EINVAL
;
510 control
= m_get(M_NOWAIT
, MT_CONTROL
);
511 if (control
== NULL
) return ENOMEM
;
512 memcpy(mtod(control
, caddr_t
), msg
->msg_control
, msg
->msg_controllen
);
513 control
->m_len
= msg
->msg_controllen
;
516 /* let pru_soreceive handle the socket locking */
517 error
= sock
->so_proto
->pr_usrreqs
->pru_soreceive(sock
, &fromsa
, auio
,
518 data
, control
? &control
: NULL
, &flags
);
519 if (error
) goto cleanup
;
522 *recvdlen
= length
- uio_resid(auio
);
524 msg
->msg_flags
= flags
;
529 salen
= msg
->msg_namelen
;
530 if (msg
->msg_namelen
> 0 && fromsa
!= 0)
532 salen
= MIN(salen
, fromsa
->sa_len
);
533 memcpy(msg
->msg_name
, fromsa
,
534 msg
->msg_namelen
> fromsa
->sa_len
? fromsa
->sa_len
: msg
->msg_namelen
);
538 if (msg
->msg_control
)
540 struct mbuf
* m
= control
;
541 u_char
* ctlbuf
= msg
->msg_control
;
542 int clen
= msg
->msg_controllen
;
543 msg
->msg_controllen
= 0;
545 while (m
&& clen
> 0)
548 if (clen
>= m
->m_len
)
554 msg
->msg_flags
|= MSG_CTRUNC
;
557 memcpy(ctlbuf
, mtod(m
, caddr_t
), tocopy
);
562 msg
->msg_controllen
= (u_int32_t
)ctlbuf
- (u_int32_t
)msg
->msg_control
;
567 if (control
) m_freem(control
);
568 if (fromsa
) FREE(fromsa
, M_SONAME
);
580 (msg
->msg_iovlen
< 1) ||
581 (msg
->msg_iov
[0].iov_len
== 0) ||
582 (msg
->msg_iov
[0].iov_base
== NULL
))
584 return sock_receive_internal(sock
, msg
, NULL
, flags
, recvdlen
);
595 if (data
== NULL
|| recvlen
== 0 || *recvlen
<= 0 || (msg
&&
596 (msg
->msg_iov
!= NULL
|| msg
->msg_iovlen
!= 0)))
598 return sock_receive_internal(sock
, msg
, data
, flags
, recvlen
);
604 const struct msghdr
*msg
,
610 struct mbuf
*control
= NULL
;
613 char uio_buf
[ UIO_SIZEOF((msg
!= NULL
? msg
->msg_iovlen
: 1)) ];
620 if (data
== 0 && msg
!= NULL
) {
621 struct iovec_32
*tempp
= (struct iovec_32
*) msg
->msg_iov
;
623 auio
= uio_createwithbuffer(msg
->msg_iovlen
, 0, UIO_SYSSPACE
, UIO_WRITE
,
624 &uio_buf
[0], sizeof(uio_buf
));
629 for (i
= 0; i
< msg
->msg_iovlen
; i
++) {
630 uio_addiov(auio
, CAST_USER_ADDR_T((tempp
+ i
)->iov_base
), (tempp
+ i
)->iov_len
);
633 if (uio_resid(auio
) < 0) {
644 datalen
= uio_resid(auio
);
646 datalen
= data
->m_pkthdr
.len
;
648 if (msg
&& msg
->msg_control
)
650 if ((size_t)msg
->msg_controllen
< sizeof(struct cmsghdr
)) return EINVAL
;
651 if ((size_t)msg
->msg_controllen
> MLEN
) return EINVAL
;
652 control
= m_get(M_NOWAIT
, MT_CONTROL
);
653 if (control
== NULL
) {
657 memcpy(mtod(control
, caddr_t
), msg
->msg_control
, msg
->msg_controllen
);
658 control
->m_len
= msg
->msg_controllen
;
661 error
= sock
->so_proto
->pr_usrreqs
->pru_sosend(sock
, msg
!= NULL
?
662 (struct sockaddr
*)msg
->msg_name
: NULL
, auio
, data
, control
, flags
);
665 * Residual data is possible in the case of IO vectors but not
666 * in the mbuf case since the latter is treated as atomic send.
667 * If pru_sosend() consumed a portion of the iovecs data and
668 * the error returned is transient, treat it as success; this
669 * is consistent with sendit() behavior.
671 if (auio
!= NULL
&& uio_resid(auio
) != datalen
&&
672 (error
== ERESTART
|| error
== EINTR
|| error
== EWOULDBLOCK
))
675 if (error
== 0 && sentlen
!= NULL
) {
677 *sentlen
= datalen
- uio_resid(auio
);
685 * In cases where we detect an error before returning, we need to
686 * free the mbuf chain if there is one. sosend (and pru_sosend) will
687 * free the mbuf chain if they encounter an error.
702 const struct msghdr
*msg
,
706 if (msg
== NULL
|| msg
->msg_iov
== NULL
|| msg
->msg_iovlen
< 1)
708 return sock_send_internal(sock
, msg
, NULL
, flags
, sentlen
);
714 const struct msghdr
*msg
,
719 if (data
== NULL
|| (msg
&&
720 (msg
->msg_iov
!= NULL
|| msg
->msg_iovlen
!= 0))) {
725 return sock_send_internal(sock
, msg
, data
, flags
, sentlen
);
733 if (sock
== NULL
) return EINVAL
;
734 return soshutdown(sock
, how
);
743 sock_upcall callback
,
748 if (new_so
== NULL
) return EINVAL
;
749 /* socreate will create an initial so_count */
750 error
= socreate(domain
, new_so
, type
, protocol
);
751 if (error
== 0 && callback
)
753 (*new_so
)->so_rcv
.sb_flags
|= SB_UPCALL
;
755 (*new_so
)->so_snd
.sb_flags
|= SB_UPCALL
;
757 (*new_so
)->so_upcall
= (so_upcall
)callback
;
758 (*new_so
)->so_upcallarg
= context
;
767 if (sock
== NULL
) return;
771 /* Do we want this to be APPLE_PRIVATE API?: YES (LD 12/23/04)*/
776 if (sock
== NULL
) return;
777 socket_lock(sock
, 1);
778 sock
->so_retaincnt
++;
779 sock
->so_usecount
++; /* add extra reference for holding the socket */
780 socket_unlock(sock
, 1);
783 /* Do we want this to be APPLE_PRIVATE API? */
785 sock_release(socket_t sock
)
789 socket_lock(sock
, 1);
791 if (sock
->so_flags
& SOF_UPCALLINUSE
)
792 soclose_wait_locked(sock
);
794 sock
->so_retaincnt
--;
795 if (sock
->so_retaincnt
< 0)
796 panic("sock_release: negative retain count for sock=%p "
797 "cnt=%x\n", sock
, sock
->so_retaincnt
);
798 if ((sock
->so_retaincnt
== 0) && (sock
->so_usecount
== 2)) {
799 /* close socket only if the FD is not holding it */
800 soclose_locked(sock
);
802 /* remove extra reference holding the socket */
805 socket_unlock(sock
, 1);
813 if (sock
== NULL
) return EINVAL
;
814 socket_lock(sock
, 1);
817 sock
->so_state
|= SS_PRIV
;
821 sock
->so_state
&= ~SS_PRIV
;
823 socket_unlock(sock
, 1);
832 socket_lock(sock
, 1);
833 retval
= (sock
->so_state
& SS_ISCONNECTED
) != 0;
834 socket_unlock(sock
, 1);
843 socket_lock(sock
, 1);
844 retval
= (sock
->so_state
& SS_NBIO
) != 0;
845 socket_unlock(sock
, 1);
856 socket_lock(sock
, 1);
858 *outDomain
= sock
->so_proto
->pr_domain
->dom_family
;
860 *outType
= sock
->so_type
;
862 *outProtocol
= sock
->so_proto
->pr_protocol
;
863 socket_unlock(sock
, 1);
868 * Return the listening socket of a pre-accepted socket. It returns the
869 * listener (so_head) value of a given socket. This is intended to be
870 * called by a socket filter during a filter attach (sf_attach) callback.
871 * The value returned by this routine is safe to be used only in the
872 * context of that callback, because we hold the listener's lock across
873 * the sflt_initsock() call.
876 sock_getlistener(socket_t sock
)
878 return (sock
->so_head
);