]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/uipc_syscalls.c
xnu-792.6.56.tar.gz
[apple/xnu.git] / bsd / kern / uipc_syscalls.c
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Copyright (c) 1982, 1986, 1989, 1990, 1993
25 * The Regents of the University of California. All rights reserved.
26 *
27 * sendfile(2) and related extensions:
28 * Copyright (c) 1998, David Greenman. All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 *
58 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
59 */
60
61
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/filedesc.h>
66 #include <sys/proc_internal.h>
67 #include <sys/file_internal.h>
68 #include <sys/malloc.h>
69 #include <sys/mbuf.h>
70 #include <kern/lock.h>
71 #include <sys/domain.h>
72 #include <sys/protosw.h>
73 #include <sys/signalvar.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
76 #if KTRACE
77 #include <sys/ktrace.h>
78 #endif
79 #include <sys/kernel.h>
80 #include <sys/uio_internal.h>
81
82 #include <bsm/audit_kernel.h>
83
84 #include <sys/kdebug.h>
85 #include <sys/sysproto.h>
86
87 #define f_flag f_fglob->fg_flag
88 #define f_type f_fglob->fg_type
89 #define f_msgcount f_fglob->fg_msgcount
90 #define f_cred f_fglob->fg_cred
91 #define f_ops f_fglob->fg_ops
92 #define f_offset f_fglob->fg_offset
93 #define f_data f_fglob->fg_data
94 #if KDEBUG
95
96 #define DBG_LAYER_IN_BEG NETDBG_CODE(DBG_NETSOCK, 0)
97 #define DBG_LAYER_IN_END NETDBG_CODE(DBG_NETSOCK, 2)
98 #define DBG_LAYER_OUT_BEG NETDBG_CODE(DBG_NETSOCK, 1)
99 #define DBG_LAYER_OUT_END NETDBG_CODE(DBG_NETSOCK, 3)
100 #define DBG_FNC_SENDMSG NETDBG_CODE(DBG_NETSOCK, (1 << 8) | 1)
101 #define DBG_FNC_SENDTO NETDBG_CODE(DBG_NETSOCK, (2 << 8) | 1)
102 #define DBG_FNC_SENDIT NETDBG_CODE(DBG_NETSOCK, (3 << 8) | 1)
103 #define DBG_FNC_RECVFROM NETDBG_CODE(DBG_NETSOCK, (5 << 8))
104 #define DBG_FNC_RECVMSG NETDBG_CODE(DBG_NETSOCK, (6 << 8))
105 #define DBG_FNC_RECVIT NETDBG_CODE(DBG_NETSOCK, (7 << 8))
106
107 #endif
108
109
110 #define HACK_FOR_4056224 1
111 #if HACK_FOR_4056224
112 static pid_t last_pid_4056224 = 0;
113 #endif /* HACK_FOR_4056224 */
114
115
116 #if SENDFILE
117 static void sf_buf_init(void *arg);
118 SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL)
119 static struct sf_buf *sf_buf_alloc(void);
120 static void sf_buf_ref(caddr_t addr, u_int size);
121 static void sf_buf_free(caddr_t addr, u_int size);
122
123 static SLIST_HEAD(, sf_buf) sf_freelist;
124 static vm_offset_t sf_base;
125 static struct sf_buf *sf_bufs;
126 static int sf_buf_alloc_want;
127 #endif
128
129 static int sendit(struct proc *p, int s, struct user_msghdr *mp, uio_t uiop,
130 int flags, register_t *retval);
131 static int recvit(struct proc *p, int s, struct user_msghdr *mp, uio_t uiop,
132 user_addr_t namelenp, register_t *retval);
133
134 static int accept1(struct proc *p, struct accept_args *uap, register_t *retval, int compat);
135 static int getsockname1(struct proc *p, struct getsockname_args *uap,
136 register_t *retval, int compat);
137 static int getpeername1(struct proc *p, struct getpeername_args *uap,
138 register_t *retval, int compat);
139
140
141 #if COMPAT_43_SOCKET
142 struct orecvmsg_args {
143 int s;
144 struct omsghdr *msg;
145 int flags;
146 };
147 struct osendmsg_args {
148 int s;
149 caddr_t msg;
150 int flags;
151 };
152 struct osend_args {
153 int s;
154 caddr_t buf;
155 int len;
156 int flags;
157 };
158 struct orecv_args {
159 int s;
160 caddr_t buf;
161 int len;
162 int flags;
163 };
164
165 int oaccept(struct proc *p, struct accept_args *uap, register_t *retval);
166 int ogetpeername(struct proc *p, struct getpeername_args *uap, register_t *retval);
167 int ogetsockname(struct proc *p, struct getsockname_args *uap, register_t *retval);
168 int orecv(struct proc *p, struct orecv_args *uap, register_t *retval);
169 int orecvfrom(struct proc *p, struct recvfrom_args *uap, register_t *retval);
170 int orecvmsg(struct proc *p, struct orecvmsg_args *uap, register_t *retval);
171 int osend(struct proc *p, struct osend_args *uap, register_t *retval);
172 int osendmsg(struct proc *p, struct osendmsg_args *uap, register_t *retval);
173 #endif // COMPAT_43_SOCKET
174
175 /*
176 * System call interface to the socket abstraction.
177 */
178
179 extern struct fileops socketops;
180
181 int
182 socket(p, uap, retval)
183 struct proc *p;
184 register struct socket_args *uap;
185 register_t *retval;
186 {
187 struct socket *so;
188 struct fileproc *fp;
189 int fd, error;
190
191 AUDIT_ARG(socket, uap->domain, uap->type, uap->protocol);
192
193 error = falloc(p, &fp, &fd);
194 if (error) {
195 return (error);
196 }
197 fp->f_flag = FREAD|FWRITE;
198 fp->f_type = DTYPE_SOCKET;
199 fp->f_ops = &socketops;
200
201 error = socreate(uap->domain, &so, uap->type, uap->protocol);
202 if (error) {
203 fp_free(p, fd, fp);
204 } else {
205 fp->f_data = (caddr_t)so;
206
207 proc_fdlock(p);
208 *fdflags(p, fd) &= ~UF_RESERVED;
209
210 fp_drop(p, fd, fp, 1);
211 proc_fdunlock(p);
212
213 *retval = fd;
214 }
215 return (error);
216 }
217
218 /* ARGSUSED */
219 int
220 bind(struct proc *p, struct bind_args *uap, __unused register_t *retval)
221 {
222 struct sockaddr *sa;
223 struct socket *so;
224 int error;
225
226 AUDIT_ARG(fd, uap->s);
227 error = file_socket(uap->s, &so);
228 if (error)
229 return (error);
230 error = getsockaddr(&sa, uap->name, uap->namelen);
231 if (error)
232 goto out;
233 AUDIT_ARG(sockaddr, p, sa);
234 if (so != NULL)
235 error = sobind(so, sa);
236 else
237 error = EBADF;
238 FREE(sa, M_SONAME);
239 out:
240 file_drop(uap->s);
241 return (error);
242 }
243
244
245 int
246 listen(__unused struct proc *p, register struct listen_args *uap,
247 __unused register_t *retval)
248 {
249 int error;
250 struct socket * so;
251
252 AUDIT_ARG(fd, uap->s);
253 error = file_socket(uap->s, &so);
254 if (error)
255 return (error);
256 if (so != NULL)
257 error = solisten(so, uap->backlog);
258 else
259 error = EBADF;
260 file_drop(uap->s);
261 return (error);
262 }
263
264 #if !COMPAT_43_SOCKET
265 #define accept1 accept
266 #endif
267
268
269
270 int
271 accept1(struct proc *p, struct accept_args *uap, register_t *retval, int compat)
272 {
273 struct fileproc *fp;
274 struct sockaddr *sa;
275 socklen_t namelen;
276 int error;
277 struct socket *head, *so = NULL;
278 lck_mtx_t *mutex_held;
279 int fd = uap->s;
280 int newfd;;
281 short fflag; /* type must match fp->f_flag */
282 int dosocklock = 0;
283
284 AUDIT_ARG(fd, uap->s);
285 if (uap->name) {
286 error = copyin(uap->anamelen, (caddr_t)&namelen,
287 sizeof(socklen_t));
288 if(error)
289 return (error);
290 }
291 error = fp_getfsock(p, fd, &fp, &head);
292 if (error) {
293 if (error == EOPNOTSUPP)
294 error = ENOTSOCK;
295 return (error);
296 }
297 if (head == NULL) {
298 error = EBADF;
299 goto out;
300 }
301
302 socket_lock(head, 1);
303
304 if (head->so_proto->pr_getlock != NULL) {
305 mutex_held = (*head->so_proto->pr_getlock)(head, 0);
306 dosocklock = 1;
307 }
308 else {
309 mutex_held = head->so_proto->pr_domain->dom_mtx;
310 dosocklock = 0;
311 }
312
313
314 if ((head->so_options & SO_ACCEPTCONN) == 0) {
315 socket_unlock(head, 1);
316 error = EINVAL;
317 goto out;
318 }
319 if ((head->so_state & SS_NBIO) && head->so_comp.tqh_first == NULL) {
320 socket_unlock(head, 1);
321 error = EWOULDBLOCK;
322 goto out;
323 }
324 while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
325 if (head->so_state & SS_CANTRCVMORE) {
326 head->so_error = ECONNABORTED;
327 break;
328 }
329 if (head->so_usecount < 1)
330 panic("accept1: head=%x refcount=%d\n", head, head->so_usecount);
331 error = msleep((caddr_t)&head->so_timeo, mutex_held, PSOCK | PCATCH,
332 "accept", 0);
333 if (head->so_usecount < 1)
334 panic("accept1: 2 head=%x refcount=%d\n", head, head->so_usecount);
335 if ((head->so_state & SS_DRAINING)) {
336 error = ECONNABORTED;
337 }
338 if (error) {
339 socket_unlock(head, 1);
340 goto out;
341 }
342 }
343 if (head->so_error) {
344 error = head->so_error;
345 head->so_error = 0;
346 socket_unlock(head, 1);
347 goto out;
348 }
349
350
351 /*
352 * At this point we know that there is at least one connection
353 * ready to be accepted. Remove it from the queue prior to
354 * allocating the file descriptor for it since falloc() may
355 * block allowing another process to accept the connection
356 * instead.
357 */
358 lck_mtx_assert(mutex_held, LCK_MTX_ASSERT_OWNED);
359 so = TAILQ_FIRST(&head->so_comp);
360 TAILQ_REMOVE(&head->so_comp, so, so_list);
361 head->so_qlen--;
362 socket_unlock(head, 0); /* unlock head to avoid deadlock with select, keep a ref on head */
363 fflag = fp->f_flag;
364 proc_fdlock(p);
365 error = falloc_locked(p, &fp, &newfd, 1);
366 if (error) {
367 /*
368 * Probably ran out of file descriptors. Put the
369 * unaccepted connection back onto the queue and
370 * do another wakeup so some other process might
371 * have a chance at it.
372 */
373 proc_fdunlock(p);
374 socket_lock(head, 0);
375 TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
376 head->so_qlen++;
377 wakeup_one((caddr_t)&head->so_timeo);
378 socket_unlock(head, 1);
379 goto out;
380 }
381 *fdflags(p, newfd) &= ~UF_RESERVED;
382 *retval = newfd;
383 fp->f_type = DTYPE_SOCKET;
384 fp->f_flag = fflag;
385 fp->f_ops = &socketops;
386 fp->f_data = (caddr_t)so;
387 fp_drop(p, newfd, fp, 1);
388 proc_fdunlock(p);
389 socket_lock(head, 0);
390 if (dosocklock)
391 socket_lock(so, 1);
392 so->so_state &= ~SS_COMP;
393 so->so_head = NULL;
394 sa = 0;
395 (void) soacceptlock(so, &sa, 0);
396 socket_unlock(head, 1);
397 if (sa == 0) {
398 namelen = 0;
399 if (uap->name)
400 goto gotnoname;
401 if (dosocklock)
402 socket_unlock(so, 1);
403 error = 0;
404 goto out;
405 }
406 AUDIT_ARG(sockaddr, p, sa);
407 if (uap->name) {
408 /* check sa_len before it is destroyed */
409 if (namelen > sa->sa_len)
410 namelen = sa->sa_len;
411 #if COMPAT_43_SOCKET
412 if (compat)
413 ((struct osockaddr *)sa)->sa_family =
414 sa->sa_family;
415 #endif
416 error = copyout(sa, uap->name, namelen);
417 if (!error)
418 gotnoname:
419 error = copyout((caddr_t)&namelen, uap->anamelen,
420 sizeof(socklen_t));
421 }
422 FREE(sa, M_SONAME);
423 if (dosocklock)
424 socket_unlock(so, 1);
425 out:
426 file_drop(fd);
427 return (error);
428 }
429
430 int
431 accept(struct proc *p, struct accept_args *uap, register_t *retval)
432 {
433
434 return (accept1(p, uap, retval, 0));
435 }
436
437 #if COMPAT_43_SOCKET
438 int
439 oaccept(struct proc *p, struct accept_args *uap, register_t *retval)
440 {
441
442 return (accept1(p, uap, retval, 1));
443 }
444 #endif /* COMPAT_43_SOCKET */
445
446 /* ARGSUSED */
447 int
448 connect(struct proc *p, struct connect_args *uap, __unused register_t *retval)
449 {
450 struct socket *so;
451 struct sockaddr *sa;
452 lck_mtx_t *mutex_held;
453 int error;
454 int fd = uap->s;
455
456 AUDIT_ARG(fd, uap->s);
457 error = file_socket( fd, &so);
458 if (error)
459 return (error);
460 if (so == NULL) {
461 error = EBADF;
462 goto out;
463 }
464
465 socket_lock(so, 1);
466
467 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
468 socket_unlock(so, 1);
469 error = EALREADY;
470 goto out;
471 }
472 error = getsockaddr(&sa, uap->name, uap->namelen);
473 if (error) {
474 socket_unlock(so, 1);
475 goto out;
476 }
477 AUDIT_ARG(sockaddr, p, sa);
478 error = soconnectlock(so, sa, 0);
479 if (error)
480 goto bad;
481 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
482 FREE(sa, M_SONAME);
483 socket_unlock(so, 1);
484 error = EINPROGRESS;
485 goto out;
486 }
487 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
488 if (so->so_proto->pr_getlock != NULL)
489 mutex_held = (*so->so_proto->pr_getlock)(so, 0);
490 else
491 mutex_held = so->so_proto->pr_domain->dom_mtx;
492 error = msleep((caddr_t)&so->so_timeo, mutex_held, PSOCK | PCATCH,
493 "connec", 0);
494 if ((so->so_state & SS_DRAINING)) {
495 error = ECONNABORTED;
496 }
497 if (error)
498 break;
499 }
500 if (error == 0) {
501 error = so->so_error;
502 so->so_error = 0;
503 }
504 bad:
505 so->so_state &= ~SS_ISCONNECTING;
506 socket_unlock(so, 1);
507 FREE(sa, M_SONAME);
508 if (error == ERESTART)
509 error = EINTR;
510 out:
511 file_drop(fd);
512 return (error);
513 }
514
515 int
516 socketpair(struct proc *p, struct socketpair_args *uap, __unused register_t *retval)
517 {
518 struct fileproc *fp1, *fp2;
519 struct socket *so1, *so2;
520 int fd, error, sv[2];
521
522 AUDIT_ARG(socket, uap->domain, uap->type, uap->protocol);
523 error = socreate(uap->domain, &so1, uap->type, uap->protocol);
524 if (error)
525 return (error);
526 error = socreate(uap->domain, &so2, uap->type, uap->protocol);
527 if (error)
528 goto free1;
529
530 error = falloc(p, &fp1, &fd);
531 if (error) {
532 goto free2;
533 }
534 fp1->f_flag = FREAD|FWRITE;
535 fp1->f_type = DTYPE_SOCKET;
536 fp1->f_ops = &socketops;
537 fp1->f_data = (caddr_t)so1;
538 sv[0] = fd;
539
540 error = falloc(p, &fp2, &fd);
541 if (error) {
542 goto free3;
543 }
544 fp2->f_flag = FREAD|FWRITE;
545 fp2->f_type = DTYPE_SOCKET;
546 fp2->f_ops = &socketops;
547 fp2->f_data = (caddr_t)so2;
548 sv[1] = fd;
549
550 error = soconnect2(so1, so2);
551 if (error) {
552 goto free4;
553 }
554 if (uap->type == SOCK_DGRAM) {
555 /*
556 * Datagram socket connection is asymmetric.
557 */
558 error = soconnect2(so2, so1);
559 if (error) {
560 goto free4;
561 }
562 }
563
564 proc_fdlock(p);
565 *fdflags(p, sv[0]) &= ~UF_RESERVED;
566 *fdflags(p, sv[1]) &= ~UF_RESERVED;
567 fp_drop(p, sv[0], fp1, 1);
568 fp_drop(p, sv[1], fp2, 1);
569 proc_fdunlock(p);
570
571 error = copyout((caddr_t)sv, uap->rsv, 2 * sizeof(int));
572 #if 0 /* old pipe(2) syscall compatability, unused these days */
573 retval[0] = sv[0]; /* XXX ??? */
574 retval[1] = sv[1]; /* XXX ??? */
575 #endif /* 0 */
576 return (error);
577 free4:
578 fp_free(p, sv[1], fp2);
579 free3:
580 fp_free(p, sv[0], fp1);
581 free2:
582 (void)soclose(so2);
583 free1:
584 (void)soclose(so1);
585 return (error);
586 }
587
588 static int
589 sendit(struct proc *p, int s, struct user_msghdr *mp, uio_t uiop,
590 int flags, register_t *retval)
591 {
592 struct mbuf *control;
593 struct sockaddr *to;
594 int error;
595 struct socket *so;
596 user_ssize_t len;
597 #if KTRACE
598 uio_t ktruio = NULL;
599 #endif
600
601 KERNEL_DEBUG(DBG_FNC_SENDIT | DBG_FUNC_START, 0,0,0,0,0);
602
603 error = file_socket(s, &so);
604 if (error )
605 {
606 KERNEL_DEBUG(DBG_FNC_SENDIT | DBG_FUNC_END, error,0,0,0,0);
607 return (error);
608 }
609
610 if (mp->msg_name) {
611 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
612 if (error) {
613 KERNEL_DEBUG(DBG_FNC_SENDIT | DBG_FUNC_END, error,0,0,0,0);
614 goto out;
615 }
616 AUDIT_ARG(sockaddr, p, to);
617 } else {
618 to = 0;
619 }
620 if (mp->msg_control) {
621 if (mp->msg_controllen < ((socklen_t)sizeof(struct cmsghdr))
622 #if COMPAT_43_SOCKET
623 && !(mp->msg_flags & MSG_COMPAT)
624 #endif
625 ) {
626 error = EINVAL;
627 goto bad;
628 }
629 error = sockargs(&control, mp->msg_control,
630 mp->msg_controllen, MT_CONTROL);
631 if (error)
632 goto bad;
633 #if COMPAT_43_SOCKET
634 if (mp->msg_flags & MSG_COMPAT) {
635 register struct cmsghdr *cm;
636
637 M_PREPEND(control, sizeof(*cm), M_WAIT);
638 if (control == 0) {
639 error = ENOBUFS;
640 goto bad;
641 } else {
642 cm = mtod(control, struct cmsghdr *);
643 cm->cmsg_len = control->m_len;
644 cm->cmsg_level = SOL_SOCKET;
645 cm->cmsg_type = SCM_RIGHTS;
646 }
647 }
648 #endif
649 } else {
650 control = 0;
651 }
652
653 #if KTRACE
654 if (KTRPOINT(p, KTR_GENIO)) {
655 ktruio = uio_duplicate(uiop);
656 }
657 #endif
658
659 len = uio_resid(uiop);
660 if (so == NULL)
661 error = EBADF;
662 else
663 error = so->so_proto->pr_usrreqs->pru_sosend(so, to, uiop, 0, control,
664 flags);
665 if (error) {
666 if (uio_resid(uiop) != len && (error == ERESTART ||
667 error == EINTR || error == EWOULDBLOCK))
668 error = 0;
669 /* Generation of SIGPIPE can be controlled per socket */
670 if (error == EPIPE && !(so->so_flags & SOF_NOSIGPIPE))
671 psignal(p, SIGPIPE);
672 }
673 if (error == 0)
674 *retval = (int)(len - uio_resid(uiop));
675 bad:
676 #if KTRACE
677 if (ktruio != NULL) {
678 if (error == 0) {
679 uio_setresid(ktruio, retval[0]);
680 ktrgenio(p->p_tracep, s, UIO_WRITE, ktruio, error);
681 }
682 uio_free(ktruio);
683 }
684 #endif
685 if (to)
686 FREE(to, M_SONAME);
687 KERNEL_DEBUG(DBG_FNC_SENDIT | DBG_FUNC_END, error,0,0,0,0);
688 out:
689 file_drop(s);
690 return (error);
691 }
692
693
694 int
695 sendto(struct proc *p, struct sendto_args *uap, register_t *retval)
696 {
697 struct user_msghdr msg;
698 int error;
699 uio_t auio = NULL;
700
701 KERNEL_DEBUG(DBG_FNC_SENDTO | DBG_FUNC_START, 0,0,0,0,0);
702 AUDIT_ARG(fd, uap->s);
703
704 auio = uio_create(1, 0,
705 (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
706 UIO_WRITE);
707 if (auio == NULL) {
708 return (ENOMEM);
709 }
710 uio_addiov(auio, uap->buf, uap->len);
711
712 msg.msg_name = uap->to;
713 msg.msg_namelen = uap->tolen;
714 /* no need to set up msg_iov. sendit uses uio_t we send it */
715 msg.msg_iov = 0;
716 msg.msg_iovlen = 0;
717 msg.msg_control = 0;
718 msg.msg_flags = 0;
719
720 error = sendit(p, uap->s, &msg, auio, uap->flags, retval);
721
722 if (auio != NULL) {
723 uio_free(auio);
724 }
725
726 #if HACK_FOR_4056224
727 /*
728 * Radar 4056224
729 * Temporary workaround to let send() and recv() work over a pipe for binary compatibility
730 * This will be removed in the release following Tiger
731 */
732 if (error == ENOTSOCK) {
733 struct fileproc *fp;
734
735 if (fp_lookup(p, uap->s, &fp, 0) == 0) {
736 (void) fp_drop(p, uap->s, fp,0);
737
738 if (fp->f_type == DTYPE_PIPE) {
739 struct write_args write_uap;
740 user_ssize_t write_retval;
741
742 if (p->p_pid > last_pid_4056224) {
743 last_pid_4056224 = p->p_pid;
744
745 printf("%s[%d] uses send/recv on a pipe\n",
746 p->p_comm, p->p_pid);
747 }
748
749 bzero(&write_uap, sizeof(struct write_args));
750 write_uap.fd = uap->s;
751 write_uap.cbuf = uap->buf;
752 write_uap.nbyte = uap->len;
753
754 error = write(p, &write_uap, &write_retval);
755 *retval = (int)write_retval;
756 }
757 }
758 }
759 #endif /* HACK_FOR_4056224 */
760
761 KERNEL_DEBUG(DBG_FNC_SENDTO | DBG_FUNC_END, error, *retval,0,0,0);
762
763 return(error);
764 }
765
766 #if COMPAT_43_SOCKET
767 int
768 osend(__unused struct proc *p,
769 __unused struct osend_args *uap,
770 __unused register_t *retval)
771 {
772 /* these are no longer supported and in fact
773 * there is no way to call it directly.
774 * LP64todo - remove this once we're sure there are no clients
775 */
776 return (ENOTSUP);
777 }
778
779 int
780 osendmsg(__unused struct proc *p,
781 __unused struct osendmsg_args *uap,
782 __unused register_t *retval)
783 {
784 /* these are no longer supported and in fact
785 * there is no way to call it directly.
786 * LP64todo - remove this once we're sure there are no clients
787 */
788 return (ENOTSUP);
789 }
790 #endif
791
792
793 int
794 sendmsg(struct proc *p, register struct sendmsg_args *uap, register_t *retval)
795 {
796 struct msghdr msg;
797 struct user_msghdr user_msg;
798 caddr_t msghdrp;
799 int size_of_msghdr;
800 int error;
801 int size_of_iovec;
802 uio_t auio = NULL;
803 struct user_iovec *iovp;
804
805 KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_START, 0,0,0,0,0);
806 AUDIT_ARG(fd, uap->s);
807 if (IS_64BIT_PROCESS(p)) {
808 msghdrp = (caddr_t) &user_msg;
809 size_of_msghdr = sizeof(user_msg);
810 size_of_iovec = sizeof(struct user_iovec);
811 }
812 else {
813 msghdrp = (caddr_t) &msg;
814 size_of_msghdr = sizeof(msg);
815 size_of_iovec = sizeof(struct iovec);
816 }
817 error = copyin(uap->msg, msghdrp, size_of_msghdr);
818 if (error)
819 {
820 KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, error,0,0,0,0);
821 return (error);
822 }
823
824 /* only need to copy if user process is not 64-bit */
825 if (!IS_64BIT_PROCESS(p)) {
826 user_msg.msg_flags = msg.msg_flags;
827 user_msg.msg_controllen = msg.msg_controllen;
828 user_msg.msg_control = CAST_USER_ADDR_T(msg.msg_control);
829 user_msg.msg_iovlen = msg.msg_iovlen;
830 user_msg.msg_iov = CAST_USER_ADDR_T(msg.msg_iov);
831 user_msg.msg_namelen = msg.msg_namelen;
832 user_msg.msg_name = CAST_USER_ADDR_T(msg.msg_name);
833 }
834
835 if (user_msg.msg_iovlen <= 0 || user_msg.msg_iovlen > UIO_MAXIOV) {
836 KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, EMSGSIZE,0,0,0,0);
837 return (EMSGSIZE);
838 }
839
840 /* allocate a uio large enough to hold the number of iovecs passed */
841 auio = uio_create(user_msg.msg_iovlen, 0,
842 (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
843 UIO_WRITE);
844 if (auio == NULL) {
845 error = ENOBUFS;
846 goto done;
847 }
848
849 if (user_msg.msg_iovlen) {
850 /* get location of iovecs within the uio. then copyin the iovecs from
851 * user space.
852 */
853 iovp = uio_iovsaddr(auio);
854 if (iovp == NULL) {
855 error = ENOBUFS;
856 goto done;
857 }
858 error = copyin(user_msg.msg_iov, (caddr_t)iovp, (user_msg.msg_iovlen * size_of_iovec));
859 if (error)
860 goto done;
861 user_msg.msg_iov = CAST_USER_ADDR_T(iovp);
862
863 /* finish setup of uio_t */
864 uio_calculateresid(auio);
865 }
866 else {
867 user_msg.msg_iov = 0;
868 }
869
870 #if COMPAT_43_SOCKET
871 user_msg.msg_flags = 0;
872 #endif
873 error = sendit(p, uap->s, &user_msg, auio, uap->flags, retval);
874 done:
875 if (auio != NULL) {
876 uio_free(auio);
877 }
878 KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, error,0,0,0,0);
879
880 return (error);
881 }
882
883 static int
884 recvit(p, s, mp, uiop, namelenp, retval)
885 register struct proc *p;
886 int s;
887 register struct user_msghdr *mp;
888 uio_t uiop;
889 user_addr_t namelenp;
890 register_t *retval;
891 {
892 int len, error;
893 struct mbuf *m, *control = 0;
894 user_addr_t ctlbuf;
895 struct socket *so;
896 struct sockaddr *fromsa = 0;
897 struct fileproc *fp;
898 #if KTRACE
899 uio_t ktruio = NULL;
900 #endif
901
902 KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_START, 0,0,0,0,0);
903 proc_fdlock(p);
904 if ( (error = fp_lookup(p, s, &fp, 1)) ) {
905 KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_END, error,0,0,0,0);
906 proc_fdunlock(p);
907 return (error);
908 }
909 if (fp->f_type != DTYPE_SOCKET) {
910 fp_drop(p, s, fp,1);
911 proc_fdunlock(p);
912 return(ENOTSOCK);
913 }
914
915 so = (struct socket *)fp->f_data;
916
917 proc_fdunlock(p);
918 if (uio_resid(uiop) < 0) {
919 KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_END, EINVAL,0,0,0,0);
920 error = EINVAL;
921 goto out1;
922 }
923 #if KTRACE
924 if (KTRPOINT(p, KTR_GENIO)) {
925 ktruio = uio_duplicate(uiop);
926 }
927 #endif
928
929 len = uio_resid(uiop);
930 if (so == NULL)
931 error = EBADF;
932 else {
933 error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, uiop,
934 (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0,
935 &mp->msg_flags);
936 }
937 AUDIT_ARG(sockaddr, p, fromsa);
938 if (error) {
939 if (uio_resid(uiop) != len && (error == ERESTART ||
940 error == EINTR || error == EWOULDBLOCK))
941 error = 0;
942 }
943 #if KTRACE
944 if (ktruio != NULL) {
945 if (error == 0) {
946 uio_setresid(ktruio, len - uio_resid(uiop));
947 ktrgenio(p->p_tracep, s, UIO_WRITE, ktruio, error);
948 }
949 uio_free(ktruio);
950 }
951 #endif
952 if (error)
953 goto out;
954 *retval = len - uio_resid(uiop);
955 if (mp->msg_name) {
956 len = mp->msg_namelen;
957 if (len <= 0 || fromsa == 0)
958 len = 0;
959 else {
960 #ifndef MIN
961 #define MIN(a,b) ((a)>(b)?(b):(a))
962 #endif
963 /* save sa_len before it is destroyed by MSG_COMPAT */
964 len = MIN(len, fromsa->sa_len);
965 #if COMPAT_43_SOCKET
966 if (mp->msg_flags & MSG_COMPAT)
967 ((struct osockaddr *)fromsa)->sa_family =
968 fromsa->sa_family;
969 #endif
970 error = copyout(fromsa, mp->msg_name, (unsigned)len);
971 if (error)
972 goto out;
973 }
974 mp->msg_namelen = len;
975 if (namelenp &&
976 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
977 #if COMPAT_43_SOCKET
978 if (mp->msg_flags & MSG_COMPAT)
979 error = 0; /* old recvfrom didn't check */
980 else
981 #endif
982 goto out;
983 }
984 }
985 if (mp->msg_control) {
986 #if COMPAT_43_SOCKET
987 /*
988 * We assume that old recvmsg calls won't receive access
989 * rights and other control info, esp. as control info
990 * is always optional and those options didn't exist in 4.3.
991 * If we receive rights, trim the cmsghdr; anything else
992 * is tossed.
993 */
994 if (control && mp->msg_flags & MSG_COMPAT) {
995 if (mtod(control, struct cmsghdr *)->cmsg_level !=
996 SOL_SOCKET ||
997 mtod(control, struct cmsghdr *)->cmsg_type !=
998 SCM_RIGHTS) {
999 mp->msg_controllen = 0;
1000 goto out;
1001 }
1002 control->m_len -= sizeof (struct cmsghdr);
1003 control->m_data += sizeof (struct cmsghdr);
1004 }
1005 #endif
1006 len = mp->msg_controllen;
1007 m = control;
1008 mp->msg_controllen = 0;
1009 ctlbuf = mp->msg_control;
1010
1011 while (m && len > 0) {
1012 unsigned int tocopy;
1013
1014 if (len >= m->m_len)
1015 tocopy = m->m_len;
1016 else {
1017 mp->msg_flags |= MSG_CTRUNC;
1018 tocopy = len;
1019 }
1020
1021 error = copyout((caddr_t)mtod(m, caddr_t), ctlbuf, tocopy);
1022 if (error)
1023 goto out;
1024
1025 ctlbuf += tocopy;
1026 len -= tocopy;
1027 m = m->m_next;
1028 }
1029 mp->msg_controllen = ctlbuf - mp->msg_control;
1030 }
1031 out:
1032 if (fromsa)
1033 FREE(fromsa, M_SONAME);
1034 if (control)
1035 m_freem(control);
1036 KERNEL_DEBUG(DBG_FNC_RECVIT | DBG_FUNC_END, error,0,0,0,0);
1037 out1:
1038 fp_drop(p, s, fp, 0);
1039 return (error);
1040 }
1041
1042
1043 int
1044 recvfrom(p, uap, retval)
1045 struct proc *p;
1046 register struct recvfrom_args /* {
1047 int s;
1048 caddr_t buf;
1049 size_t len;
1050 int flags;
1051 caddr_t from;
1052 int *fromlenaddr;
1053 } */ *uap;
1054 register_t *retval;
1055 {
1056 struct user_msghdr msg;
1057 int error;
1058 uio_t auio = NULL;
1059
1060 KERNEL_DEBUG(DBG_FNC_RECVFROM | DBG_FUNC_START, 0,0,0,0,0);
1061 AUDIT_ARG(fd, uap->s);
1062
1063 if (uap->fromlenaddr) {
1064 error = copyin(uap->fromlenaddr,
1065 (caddr_t)&msg.msg_namelen, sizeof (msg.msg_namelen));
1066 if (error)
1067 return (error);
1068 } else
1069 msg.msg_namelen = 0;
1070 msg.msg_name = uap->from;
1071 auio = uio_create(1, 0,
1072 (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
1073 UIO_READ);
1074 if (auio == NULL) {
1075 return (ENOMEM);
1076 }
1077
1078 uio_addiov(auio, uap->buf, uap->len);
1079 /* no need to set up msg_iov. recvit uses uio_t we send it */
1080 msg.msg_iov = 0;
1081 msg.msg_iovlen = 0;
1082 msg.msg_control = 0;
1083 msg.msg_controllen = 0;
1084 msg.msg_flags = uap->flags;
1085 error = recvit(p, uap->s, &msg, auio, uap->fromlenaddr, retval);
1086 if (auio != NULL) {
1087 uio_free(auio);
1088 }
1089
1090 #if HACK_FOR_4056224
1091 /*
1092 * Radar 4056224
1093 * Temporary workaround to let send() and recv() work over a pipe for binary compatibility
1094 * This will be removed in the release following Tiger
1095 */
1096 if (error == ENOTSOCK && proc_is64bit(p) == 0) {
1097 struct fileproc *fp;
1098
1099 if (fp_lookup(p, uap->s, &fp, 0) == 0) {
1100 (void) fp_drop(p, uap->s, fp,0);
1101
1102 if (fp->f_type == DTYPE_PIPE) {
1103 struct read_args read_uap;
1104 user_ssize_t read_retval;
1105
1106 if (p->p_pid > last_pid_4056224) {
1107 last_pid_4056224 = p->p_pid;
1108
1109 printf("%s[%d] uses send/recv on a pipe\n",
1110 p->p_comm, p->p_pid);
1111 }
1112
1113 bzero(&read_uap, sizeof(struct read_args));
1114 read_uap.fd = uap->s;
1115 read_uap.cbuf = uap->buf;
1116 read_uap.nbyte = uap->len;
1117
1118 error = read(p, &read_uap, &read_retval);
1119 *retval = (int)read_retval;
1120 }
1121 }
1122 }
1123 #endif /* HACK_FOR_4056224 */
1124
1125 KERNEL_DEBUG(DBG_FNC_RECVFROM | DBG_FUNC_END, error,0,0,0,0);
1126
1127 return (error);
1128 }
1129
1130 #if COMPAT_43_SOCKET
1131 int
1132 orecvfrom(struct proc *p, struct recvfrom_args *uap, register_t *retval)
1133 {
1134
1135 uap->flags |= MSG_COMPAT;
1136 return (recvfrom(p, uap, retval));
1137 }
1138 #endif
1139
1140
1141 #if COMPAT_43_SOCKET
1142 int
1143 orecv(__unused struct proc *p, __unused struct orecv_args *uap,
1144 __unused register_t *retval)
1145 {
1146 /* these are no longer supported and in fact
1147 * there is no way to call it directly.
1148 * LP64todo - remove this once we're sure there are no clients
1149 */
1150
1151 return (ENOTSUP);
1152 }
1153
1154 /*
1155 * Old recvmsg. This code takes advantage of the fact that the old msghdr
1156 * overlays the new one, missing only the flags, and with the (old) access
1157 * rights where the control fields are now.
1158 */
1159 int
1160 orecvmsg(__unused struct proc *p, __unused struct orecvmsg_args *uap,
1161 __unused register_t *retval)
1162 {
1163 /* these are no longer supported and in fact
1164 * there is no way to call it directly.
1165 * LP64todo - remove this once we're sure there are no clients
1166 */
1167
1168 return (ENOTSUP);
1169
1170 }
1171 #endif
1172
1173 int
1174 recvmsg(p, uap, retval)
1175 struct proc *p;
1176 struct recvmsg_args *uap;
1177 register_t *retval;
1178 {
1179 struct msghdr msg;
1180 struct user_msghdr user_msg;
1181 caddr_t msghdrp;
1182 int size_of_msghdr;
1183 user_addr_t uiov;
1184 register int error;
1185 int size_of_iovec;
1186 uio_t auio = NULL;
1187 struct user_iovec *iovp;
1188
1189 KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_START, 0,0,0,0,0);
1190 AUDIT_ARG(fd, uap->s);
1191 if (IS_64BIT_PROCESS(p)) {
1192 msghdrp = (caddr_t) &user_msg;
1193 size_of_msghdr = sizeof(user_msg);
1194 size_of_iovec = sizeof(struct user_iovec);
1195 }
1196 else {
1197 msghdrp = (caddr_t) &msg;
1198 size_of_msghdr = sizeof(msg);
1199 size_of_iovec = sizeof(struct iovec);
1200 }
1201 error = copyin(uap->msg, msghdrp, size_of_msghdr);
1202 if (error)
1203 {
1204 KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_END, error,0,0,0,0);
1205 return (error);
1206 }
1207
1208 /* only need to copy if user process is not 64-bit */
1209 if (!IS_64BIT_PROCESS(p)) {
1210 user_msg.msg_flags = msg.msg_flags;
1211 user_msg.msg_controllen = msg.msg_controllen;
1212 user_msg.msg_control = CAST_USER_ADDR_T(msg.msg_control);
1213 user_msg.msg_iovlen = msg.msg_iovlen;
1214 user_msg.msg_iov = CAST_USER_ADDR_T(msg.msg_iov);
1215 user_msg.msg_namelen = msg.msg_namelen;
1216 user_msg.msg_name = CAST_USER_ADDR_T(msg.msg_name);
1217 }
1218
1219 if (user_msg.msg_iovlen <= 0 || user_msg.msg_iovlen > UIO_MAXIOV) {
1220 KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_END, EMSGSIZE,0,0,0,0);
1221 return (EMSGSIZE);
1222 }
1223
1224 #if COMPAT_43_SOCKET
1225 user_msg.msg_flags = uap->flags &~ MSG_COMPAT;
1226 #else
1227 user_msg.msg_flags = uap->flags;
1228 #endif
1229
1230 /* allocate a uio large enough to hold the number of iovecs passed */
1231 auio = uio_create(user_msg.msg_iovlen, 0,
1232 (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
1233 UIO_READ);
1234 if (auio == NULL) {
1235 error = ENOMEM;
1236 goto done;
1237 }
1238
1239 /* get location of iovecs within the uio. then copyin the iovecs from
1240 * user space.
1241 */
1242 iovp = uio_iovsaddr(auio);
1243 if (iovp == NULL) {
1244 error = ENOMEM;
1245 goto done;
1246 }
1247 uiov = user_msg.msg_iov;
1248 user_msg.msg_iov = CAST_USER_ADDR_T(iovp);
1249 error = copyin(uiov, (caddr_t)iovp, (user_msg.msg_iovlen * size_of_iovec));
1250 if (error)
1251 goto done;
1252
1253 /* finish setup of uio_t */
1254 uio_calculateresid(auio);
1255
1256 error = recvit(p, uap->s, &user_msg, auio, 0, retval);
1257 if (!error) {
1258 user_msg.msg_iov = uiov;
1259 /* only need to copy if user process is not 64-bit */
1260 if (!IS_64BIT_PROCESS(p)) {
1261 // LP64todo - do all these change? if not, then no need to copy all of them!
1262 msg.msg_flags = user_msg.msg_flags;
1263 msg.msg_controllen = user_msg.msg_controllen;
1264 msg.msg_control = CAST_DOWN(caddr_t, user_msg.msg_control);
1265 msg.msg_iovlen = user_msg.msg_iovlen;
1266 msg.msg_iov = (struct iovec *) CAST_DOWN(caddr_t, user_msg.msg_iov);
1267 msg.msg_namelen = user_msg.msg_namelen;
1268 msg.msg_name = CAST_DOWN(caddr_t, user_msg.msg_name);
1269 }
1270 error = copyout(msghdrp, uap->msg, size_of_msghdr);
1271 }
1272 done:
1273 if (auio != NULL) {
1274 uio_free(auio);
1275 }
1276 KERNEL_DEBUG(DBG_FNC_RECVMSG | DBG_FUNC_END, error,0,0,0,0);
1277 return (error);
1278 }
1279
1280 /* ARGSUSED */
1281 int
1282 shutdown(__unused struct proc *p, struct shutdown_args *uap, __unused register_t *retval)
1283 {
1284 struct socket * so;
1285 int error;
1286
1287 AUDIT_ARG(fd, uap->s);
1288 error = file_socket(uap->s, &so);
1289 if (error)
1290 return (error);
1291 if (so == NULL) {
1292 error = EBADF;
1293 goto out;
1294 }
1295 error = soshutdown((struct socket *)so, uap->how);
1296 out:
1297 file_drop(uap->s);
1298 return(error);
1299 }
1300
1301
1302
1303
1304
1305 /* ARGSUSED */
1306 int
1307 setsockopt(struct proc *p, struct setsockopt_args *uap, __unused register_t *retval)
1308 {
1309 struct socket * so;
1310 struct sockopt sopt;
1311 int error;
1312
1313 AUDIT_ARG(fd, uap->s);
1314 if (uap->val == 0 && uap->valsize != 0)
1315 return (EFAULT);
1316 if (uap->valsize < 0)
1317 return (EINVAL);
1318
1319 error = file_socket(uap->s, &so);
1320 if (error)
1321 return (error);
1322
1323 sopt.sopt_dir = SOPT_SET;
1324 sopt.sopt_level = uap->level;
1325 sopt.sopt_name = uap->name;
1326 sopt.sopt_val = uap->val;
1327 sopt.sopt_valsize = uap->valsize;
1328 sopt.sopt_p = p;
1329
1330 if (so == NULL) {
1331 error = EINVAL;
1332 goto out;
1333 }
1334 error = sosetopt(so, &sopt);
1335 out:
1336 file_drop(uap->s);
1337 return(error);
1338 }
1339
1340
1341
1342 int
1343 getsockopt(struct proc *p, struct getsockopt_args *uap, __unused register_t *retval)
1344 {
1345 int error;
1346 socklen_t valsize;
1347 struct sockopt sopt;
1348 struct socket * so;
1349
1350 error = file_socket(uap->s, &so);
1351 if (error)
1352 return (error);
1353 if (uap->val) {
1354 error = copyin(uap->avalsize, (caddr_t)&valsize, sizeof (valsize));
1355 if (error)
1356 goto out;
1357 if (valsize < 0) {
1358 error = EINVAL;
1359 goto out;
1360 }
1361 } else
1362 valsize = 0;
1363
1364 sopt.sopt_dir = SOPT_GET;
1365 sopt.sopt_level = uap->level;
1366 sopt.sopt_name = uap->name;
1367 sopt.sopt_val = uap->val;
1368 sopt.sopt_valsize = (size_t)valsize; /* checked non-negative above */
1369 sopt.sopt_p = p;
1370
1371 if (so == NULL) {
1372 error = EBADF;
1373 goto out;
1374 }
1375 error = sogetopt((struct socket *)so, &sopt);
1376 if (error == 0) {
1377 valsize = sopt.sopt_valsize;
1378 error = copyout((caddr_t)&valsize, uap->avalsize, sizeof (valsize));
1379 }
1380 out:
1381 file_drop(uap->s);
1382 return (error);
1383 }
1384
1385
1386 /*
1387 * Get socket name.
1388 */
1389 /* ARGSUSED */
1390 static int
1391 getsockname1(__unused struct proc *p, struct getsockname_args *uap, __unused register_t *retval,
1392 int compat)
1393 {
1394 struct socket *so;
1395 struct sockaddr *sa;
1396 socklen_t len;
1397 int error;
1398
1399 error = file_socket(uap->fdes, &so);
1400 if (error)
1401 return (error);
1402 error = copyin(uap->alen, (caddr_t)&len, sizeof(socklen_t));
1403 if (error)
1404 goto out;
1405 if (so == NULL) {
1406 error = EBADF;
1407 goto out;
1408 }
1409 sa = 0;
1410 socket_lock(so, 1);
1411 error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &sa);
1412 if (error == 0)
1413 {
1414 struct socket_filter_entry *filter;
1415 int filtered = 0;
1416 for (filter = so->so_filt; filter && error == 0;
1417 filter = filter->sfe_next_onsocket) {
1418 if (filter->sfe_filter->sf_filter.sf_getsockname) {
1419 if (!filtered) {
1420 filtered = 1;
1421 sflt_use(so);
1422 socket_unlock(so, 0);
1423 }
1424 error = filter->sfe_filter->sf_filter.sf_getsockname(filter->sfe_cookie,
1425 so, &sa);
1426 }
1427 }
1428
1429 if (error == EJUSTRETURN)
1430 error = 0;
1431
1432 if (filtered) {
1433 socket_lock(so, 0);
1434 sflt_unuse(so);
1435 }
1436 }
1437 socket_unlock(so, 1);
1438 if (error)
1439 goto bad;
1440 if (sa == 0) {
1441 len = 0;
1442 goto gotnothing;
1443 }
1444
1445 len = MIN(len, sa->sa_len);
1446 #if COMPAT_43_SOCKET
1447 if (compat)
1448 ((struct osockaddr *)sa)->sa_family = sa->sa_family;
1449 #endif
1450 error = copyout((caddr_t)sa, uap->asa, len);
1451 if (error == 0)
1452 gotnothing:
1453 error = copyout((caddr_t)&len, uap->alen, sizeof(socklen_t));
1454 bad:
1455 if (sa)
1456 FREE(sa, M_SONAME);
1457 out:
1458 file_drop(uap->fdes);
1459 return (error);
1460 }
1461
1462 int
1463 getsockname(struct proc *p, struct getsockname_args *uap, register_t *retval)
1464 {
1465 return (getsockname1(p, uap, retval, 0));
1466 }
1467
1468 #if COMPAT_43_SOCKET
1469 int
1470 ogetsockname(struct proc *p, struct getsockname_args *uap, register_t *retval)
1471 {
1472 return (getsockname1(p, uap, retval, 1));
1473 }
1474 #endif /* COMPAT_43_SOCKET */
1475
1476 /*
1477 * Get name of peer for connected socket.
1478 */
1479 /* ARGSUSED */
1480 int
1481 getpeername1(__unused struct proc *p, struct getpeername_args *uap, __unused register_t *retval,
1482 int compat)
1483 {
1484 struct socket *so;
1485 struct sockaddr *sa;
1486 socklen_t len;
1487 int error;
1488
1489 error = file_socket(uap->fdes, &so);
1490 if (error)
1491 return (error);
1492 if (so == NULL) {
1493 error = EBADF;
1494 goto out;
1495 }
1496
1497 socket_lock(so, 1);
1498
1499 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
1500 socket_unlock(so, 1);
1501 error = ENOTCONN;
1502 goto out;
1503 }
1504 error = copyin(uap->alen, (caddr_t)&len, sizeof(socklen_t));
1505 if (error) {
1506 socket_unlock(so, 1);
1507 goto out;
1508 }
1509 sa = 0;
1510 error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa);
1511 if (error == 0)
1512 {
1513 struct socket_filter_entry *filter;
1514 int filtered = 0;
1515 for (filter = so->so_filt; filter && error == 0;
1516 filter = filter->sfe_next_onsocket) {
1517 if (filter->sfe_filter->sf_filter.sf_getpeername) {
1518 if (!filtered) {
1519 filtered = 1;
1520 sflt_use(so);
1521 socket_unlock(so, 0);
1522 }
1523 error = filter->sfe_filter->sf_filter.sf_getpeername(filter->sfe_cookie,
1524 so, &sa);
1525 }
1526 }
1527
1528 if (error == EJUSTRETURN)
1529 error = 0;
1530
1531 if (filtered) {
1532 socket_lock(so, 0);
1533 sflt_unuse(so);
1534 }
1535 }
1536 socket_unlock(so, 1);
1537 if (error)
1538 goto bad;
1539 if (sa == 0) {
1540 len = 0;
1541 goto gotnothing;
1542 }
1543 len = MIN(len, sa->sa_len);
1544 #if COMPAT_43_SOCKET
1545 if (compat)
1546 ((struct osockaddr *)sa)->sa_family =
1547 sa->sa_family;
1548 #endif
1549 error = copyout(sa, uap->asa, len);
1550 if (error)
1551 goto bad;
1552 gotnothing:
1553 error = copyout((caddr_t)&len, uap->alen, sizeof(socklen_t));
1554 bad:
1555 if (sa) FREE(sa, M_SONAME);
1556 out:
1557 file_drop(uap->fdes);
1558 return (error);
1559 }
1560
1561 int
1562 getpeername(struct proc *p, struct getpeername_args *uap, register_t *retval)
1563 {
1564
1565 return (getpeername1(p, uap, retval, 0));
1566 }
1567
1568 #if COMPAT_43_SOCKET
1569 int
1570 ogetpeername(struct proc *p, struct getpeername_args *uap, register_t *retval)
1571 {
1572
1573 return (getpeername1(p, uap, retval, 1));
1574 }
1575 #endif /* COMPAT_43_SOCKET */
1576
1577 int
1578 sockargs(mp, data, buflen, type)
1579 struct mbuf **mp;
1580 user_addr_t data;
1581 int buflen, type;
1582 {
1583 register struct sockaddr *sa;
1584 register struct mbuf *m;
1585 int error;
1586
1587 if ((u_int)buflen > MLEN) {
1588 #if COMPAT_43_SOCKET
1589 if (type == MT_SONAME && (u_int)buflen <= 112)
1590 buflen = MLEN; /* unix domain compat. hack */
1591 else
1592 #endif
1593 if ((u_int)buflen > MCLBYTES)
1594 return (EINVAL);
1595 }
1596 m = m_get(M_WAIT, type);
1597 if (m == NULL)
1598 return (ENOBUFS);
1599 if ((u_int)buflen > MLEN) {
1600 MCLGET(m, M_WAIT);
1601 if ((m->m_flags & M_EXT) == 0) {
1602 m_free(m);
1603 return ENOBUFS;
1604 }
1605 }
1606 m->m_len = buflen;
1607 error = copyin(data, mtod(m, caddr_t), (u_int)buflen);
1608 if (error)
1609 (void) m_free(m);
1610 else {
1611 *mp = m;
1612 if (type == MT_SONAME) {
1613 sa = mtod(m, struct sockaddr *);
1614
1615 #if COMPAT_43_SOCKET && BYTE_ORDER != BIG_ENDIAN
1616 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1617 sa->sa_family = sa->sa_len;
1618 #endif
1619 sa->sa_len = buflen;
1620 }
1621 }
1622 return (error);
1623 }
1624
1625 /*
1626 * Given a user_addr_t of length len, allocate and fill out a *sa.
1627 */
1628 int
1629 getsockaddr(struct sockaddr **namp, user_addr_t uaddr, size_t len)
1630 {
1631 struct sockaddr *sa;
1632 int error;
1633
1634 if (len > SOCK_MAXADDRLEN)
1635 return ENAMETOOLONG;
1636
1637 if (len == 0)
1638 return EINVAL;
1639
1640 MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK);
1641 if (sa == NULL) {
1642 return ENOMEM;
1643 }
1644 error = copyin(uaddr, (caddr_t)sa, len);
1645 if (error) {
1646 FREE(sa, M_SONAME);
1647 } else {
1648 #if COMPAT_43_SOCKET && BYTE_ORDER != BIG_ENDIAN
1649 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1650 sa->sa_family = sa->sa_len;
1651 #endif
1652 sa->sa_len = len;
1653 *namp = sa;
1654 }
1655 return error;
1656 }
1657
1658
1659 #if SENDFILE
1660 /*
1661 * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-))
1662 * XXX - The sf_buf functions are currently private to sendfile(2), so have
1663 * been made static, but may be useful in the future for doing zero-copy in
1664 * other parts of the networking code.
1665 */
1666 static void
1667 sf_buf_init(void *arg)
1668 {
1669 int i;
1670
1671 SLIST_INIT(&sf_freelist);
1672 kmem_alloc_pageable(kernel_map, &sf_base, nsfbufs * PAGE_SIZE);
1673 MALLOC(sf_bufs, struct sf_buf *, nsfbufs * sizeof(struct sf_buf), M_TEMP, M_NOWAIT|M_ZERO);
1674 if (sf_bufs == NULL)
1675 return; /* XXX silently fail leaving sf_bufs NULL */
1676
1677 for (i = 0; i < nsfbufs; i++) {
1678 sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
1679 SLIST_INSERT_HEAD(&sf_freelist, &sf_bufs[i], free_list);
1680 }
1681 }
1682
1683 /*
1684 * Get an sf_buf from the freelist. Will block if none are available.
1685 */
1686 static struct sf_buf *
1687 sf_buf_alloc()
1688 {
1689 struct sf_buf *sf;
1690
1691 while ((sf = SLIST_FIRST(&sf_freelist)) == NULL) {
1692 sf_buf_alloc_want = 1;
1693 tsleep(&sf_freelist, PVM, "sfbufa", 0);
1694 }
1695 SLIST_REMOVE_HEAD(&sf_freelist, free_list);
1696 sf->refcnt = 1;
1697 return (sf);
1698 }
1699
1700 #define dtosf(x) (&sf_bufs[((uintptr_t)(x) - (uintptr_t)sf_base) >> PAGE_SHIFT])
1701 static void
1702 sf_buf_ref(caddr_t addr, u_int size)
1703 {
1704 struct sf_buf *sf;
1705
1706 sf = dtosf(addr);
1707 if (sf->refcnt == 0)
1708 panic("sf_buf_ref: referencing a free sf_buf");
1709 sf->refcnt++;
1710 }
1711
1712 /*
1713 * Lose a reference to an sf_buf. When none left, detach mapped page
1714 * and release resources back to the system.
1715 *
1716 * Must be called at splimp.
1717 */
1718 static void
1719 sf_buf_free(caddr_t addr, u_int size)
1720 {
1721 struct sf_buf *sf;
1722 struct vm_page *m;
1723
1724 sf = dtosf(addr);
1725 if (sf->refcnt == 0)
1726 panic("sf_buf_free: freeing free sf_buf");
1727 sf->refcnt--;
1728 if (sf->refcnt == 0) {
1729 pmap_qremove((vm_offset_t)addr, 1);
1730 m = sf->m;
1731 vm_page_unwire(m, 0);
1732 /*
1733 * Check for the object going away on us. This can
1734 * happen since we don't hold a reference to it.
1735 * If so, we're responsible for freeing the page.
1736 */
1737 if (m->wire_count == 0 && m->object == NULL)
1738 vm_page_lock_queues();
1739 vm_page_free(m);
1740 vm_page_unlock_queues();
1741 sf->m = NULL;
1742 SLIST_INSERT_HEAD(&sf_freelist, sf, free_list);
1743 if (sf_buf_alloc_want) {
1744 sf_buf_alloc_want = 0;
1745 wakeup(&sf_freelist);
1746 }
1747 }
1748 }
1749
1750 /*
1751 * sendfile(2).
1752 * int sendfile(int fd, int s, off_t offset, size_t nbytes,
1753 * struct sf_hdtr *hdtr, off_t *sbytes, int flags)
1754 *
1755 * Send a file specified by 'fd' and starting at 'offset' to a socket
1756 * specified by 's'. Send only 'nbytes' of the file or until EOF if
1757 * nbytes == 0. Optionally add a header and/or trailer to the socket
1758 * output. If specified, write the total number of bytes sent into *sbytes.
1759 */
1760 int
1761 sendfile(struct proc *p, struct sendfile_args *uap)
1762 {
1763 struct fileproc *fp;
1764 struct vnode *vp;
1765 struct vm_object *obj;
1766 struct socket *so;
1767 struct mbuf *m;
1768 struct sf_buf *sf;
1769 struct vm_page *pg;
1770 struct writev_args nuap;
1771 struct sf_hdtr hdtr;
1772 off_t off, xfsize, sbytes = 0;
1773 int error = 0, s;
1774
1775 if (sf_bufs == NULL) {
1776 /* Fail if initialization failed */
1777 return ENOSYS;
1778 }
1779
1780 /*
1781 * Do argument checking. Must be a regular file in, stream
1782 * type and connected socket out, positive offset.
1783 */
1784 if (error = fp_getfvp(p, uap->fd, &fp, &vp))
1785 goto done;
1786 if (fp->f_flag & FREAD) == 0) {
1787 error = EBADF;
1788 goto done1;
1789 }
1790 obj = vp->v_object;
1791 if (vp->v_type != VREG || obj == NULL) {
1792 error = EINVAL;
1793 goto done1;
1794 }
1795 error = file_socket(uap->s, &so);
1796 if (error)
1797 goto done1;
1798 if (so == NULL) {
1799 error = EBADF;
1800 goto done2;
1801 }
1802
1803 socket_lock(so, 1);
1804
1805 if (so->so_type != SOCK_STREAM) {
1806 error = EINVAL;
1807 goto done3;
1808 }
1809 if ((so->so_state & SS_ISCONNECTED) == 0) {
1810 error = ENOTCONN;
1811 goto done3;
1812 }
1813 if (uap->offset < 0) {
1814 error = EINVAL;
1815 goto done3;
1816 }
1817
1818 /*
1819 * If specified, get the pointer to the sf_hdtr struct for
1820 * any headers/trailers.
1821 */
1822 if (uap->hdtr != NULL) {
1823 error = copyin(CAST_USER_ADDR_T(uap->hdtr), &hdtr, sizeof(hdtr));
1824 if (error)
1825 goto done3;
1826 /*
1827 * Send any headers. Wimp out and use writev(2).
1828 */
1829 if (hdtr.headers != NULL) {
1830 nuap.fd = uap->s;
1831 nuap.iovp = hdtr.headers;
1832 nuap.iovcnt = hdtr.hdr_cnt;
1833 error = writev(p, &nuap);
1834 if (error)
1835 goto done3;
1836 sbytes += p->p_retval[0];
1837 }
1838 }
1839
1840 /*
1841 * Protect against multiple writers to the socket.
1842 */
1843 (void) sblock(&so->so_snd, M_WAIT);
1844
1845 /*
1846 * Loop through the pages in the file, starting with the requested
1847 * offset. Get a file page (do I/O if necessary), map the file page
1848 * into an sf_buf, attach an mbuf header to the sf_buf, and queue
1849 * it on the socket.
1850 */
1851 for (off = uap->offset; ; off += xfsize, sbytes += xfsize) {
1852 vm_object_offset_t pindex;
1853 vm_object_offset_t pgoff;
1854
1855 pindex = OFF_TO_IDX(off);
1856 retry_lookup:
1857 /*
1858 * Calculate the amount to transfer. Not to exceed a page,
1859 * the EOF, or the passed in nbytes.
1860 */
1861 xfsize = obj->un_pager.vnp.vnp_size - off;
1862 if (xfsize > PAGE_SIZE_64)
1863 xfsize = PAGE_SIZE;
1864 pgoff = (vm_object_offset_t)(off & PAGE_MASK_64);
1865 if (PAGE_SIZE - pgoff < xfsize)
1866 xfsize = PAGE_SIZE_64 - pgoff;
1867 if (uap->nbytes && xfsize > (uap->nbytes - sbytes))
1868 xfsize = uap->nbytes - sbytes;
1869 if (xfsize <= 0)
1870 break;
1871 /*
1872 * Optimize the non-blocking case by looking at the socket space
1873 * before going to the extra work of constituting the sf_buf.
1874 */
1875 if ((so->so_state & SS_NBIO) && sbspace(&so->so_snd) <= 0) {
1876 if (so->so_state & SS_CANTSENDMORE)
1877 error = EPIPE;
1878 else
1879 error = EAGAIN;
1880 sbunlock(&so->so_snd, 0); /* will release lock */
1881 goto done2;
1882 }
1883 /*
1884 * Attempt to look up the page. If the page doesn't exist or the
1885 * part we're interested in isn't valid, then read it from disk.
1886 * If some other part of the kernel has this page (i.e. it's busy),
1887 * then disk I/O may be occuring on it, so wait and retry.
1888 */
1889 pg = vm_page_lookup(obj, pindex);
1890 if (pg == NULL || (!(pg->flags & PG_BUSY) && !pg->busy &&
1891 !vm_page_is_valid(pg, pgoff, xfsize))) {
1892 struct uio auio;
1893 struct iovec aiov;
1894 int bsize;
1895
1896 if (pg == NULL) {
1897 pg = vm_page_alloc(obj, pindex, VM_ALLOC_NORMAL);
1898 if (pg == NULL) {
1899 VM_WAIT;
1900 goto retry_lookup;
1901 }
1902 /*
1903 * don't just clear PG_BUSY manually -
1904 * vm_page_alloc() should be considered opaque,
1905 * use the VM routine provided to clear
1906 * PG_BUSY.
1907 */
1908 vm_page_wakeup(pg);
1909
1910 }
1911 /*
1912 * Ensure that our page is still around when the I/O completes.
1913 */
1914 vm_page_io_start(pg);
1915 vm_page_wire(pg);
1916 /*
1917 * Get the page from backing store.
1918 */
1919 bsize = vp->v_mount->mnt_vfsstat.f_iosize;
1920 auio.uio_iov = &aiov;
1921 auio.uio_iovcnt = 1;
1922 aiov.iov_base = 0;
1923 aiov.iov_len = MAXBSIZE;
1924 auio.uio_offset = trunc_page(off);
1925 auio.uio_segflg = UIO_NOCOPY;
1926 auio.uio_rw = UIO_READ;
1927 uio_setresid(&auio, MAXBSIZE);
1928 error = VOP_READ(vp, &auio, IO_VMIO | ((MAXBSIZE / bsize) << 16),
1929 p->p_ucred);
1930 vm_page_flag_clear(pg, PG_ZERO);
1931 vm_page_io_finish(pg);
1932 if (error) {
1933 vm_page_unwire(pg, 0);
1934 /*
1935 * See if anyone else might know about this page.
1936 * If not and it is not valid, then free it.
1937 */
1938 if (pg->wire_count == 0 && pg->valid == 0 &&
1939 pg->busy == 0 && !(pg->flags & PG_BUSY) &&
1940 pg->hold_count == 0)
1941 vm_page_lock_queues();
1942 vm_page_free(pg);
1943 vm_page_unlock_queues();
1944 sbunlock(&so->so_snd, 0); /* will release socket lock */
1945 goto done2;
1946 }
1947 } else {
1948 if ((pg->flags & PG_BUSY) || pg->busy) {
1949 s = splvm();
1950 if ((pg->flags & PG_BUSY) || pg->busy) {
1951 /*
1952 * Page is busy. Wait and retry.
1953 */
1954 vm_page_flag_set(pg, PG_WANTED);
1955 tsleep(pg, PVM, "sfpbsy", 0);
1956 goto retry_lookup;
1957 }
1958 }
1959 /*
1960 * Protect from having the page ripped out from beneath us.
1961 */
1962 vm_page_wire(pg);
1963 }
1964 /*
1965 * Allocate a kernel virtual page and insert the physical page
1966 * into it.
1967 */
1968 sf = sf_buf_alloc();
1969 sf->m = pg;
1970 pmap_qenter(sf->kva, &pg, 1);
1971 /*
1972 * Get an mbuf header and set it up as having external storage.
1973 */
1974 MGETHDR(m, M_WAIT, MT_DATA);
1975 if (m == NULL) {
1976 error = ENOBUFS;
1977 sbunlock(&so->so_snd, 0); /* will release socket lock */
1978 goto done2;
1979 }
1980 m->m_ext.ext_free = sf_buf_free;
1981 m->m_ext.ext_ref = sf_buf_ref;
1982 m->m_ext.ext_buf = (void *)sf->kva;
1983 m->m_ext.ext_size = PAGE_SIZE;
1984 m->m_data = (char *) sf->kva + pgoff;
1985 m->m_flags |= M_EXT;
1986 m->m_pkthdr.len = m->m_len = xfsize;
1987 /*
1988 * Add the buffer to the socket buffer chain.
1989 */
1990 retry_space:
1991 /*
1992 * Make sure that the socket is still able to take more data.
1993 * CANTSENDMORE being true usually means that the connection
1994 * was closed. so_error is true when an error was sensed after
1995 * a previous send.
1996 * The state is checked after the page mapping and buffer
1997 * allocation above since those operations may block and make
1998 * any socket checks stale. From this point forward, nothing
1999 * blocks before the pru_send (or more accurately, any blocking
2000 * results in a loop back to here to re-check).
2001 */
2002 if ((so->so_state & SS_CANTSENDMORE) || so->so_error) {
2003 if (so->so_state & SS_CANTSENDMORE) {
2004 error = EPIPE;
2005 } else {
2006 error = so->so_error;
2007 so->so_error = 0;
2008 }
2009 m_freem(m);
2010 sbunlock(&so->so_snd, 0); /* will release socket lock */
2011 goto done2;
2012 }
2013 /*
2014 * Wait for socket space to become available. We do this just
2015 * after checking the connection state above in order to avoid
2016 * a race condition with sbwait().
2017 */
2018 if (sbspace(&so->so_snd) < so->so_snd.sb_lowat) {
2019 if (so->so_state & SS_NBIO) {
2020 m_freem(m);
2021 sbunlock(&so->so_snd, 0); /* will release socket lock */
2022 error = EAGAIN;
2023 goto done2;
2024 }
2025 error = sbwait(&so->so_snd);
2026 /*
2027 * An error from sbwait usually indicates that we've
2028 * been interrupted by a signal. If we've sent anything
2029 * then return bytes sent, otherwise return the error.
2030 */
2031 if (error) {
2032 m_freem(m);
2033 sbunlock(&so->so_snd, 0);
2034 goto done2;
2035 }
2036 goto retry_space;
2037 }
2038 error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m, 0, 0, p);
2039 splx(s);
2040 if (error) {
2041 sbunlock(&so->so_snd, 0); /* will release socket lock */
2042 goto done2;
2043 }
2044 }
2045 sbunlock(&so->so_snd, 0); /* will release socket lock */
2046
2047 /*
2048 * Send trailers. Wimp out and use writev(2).
2049 */
2050 if (uap->hdtr != NULL && hdtr.trailers != NULL) {
2051 nuap.fd = uap->s;
2052 nuap.iovp = hdtr.trailers;
2053 nuap.iovcnt = hdtr.trl_cnt;
2054 error = writev(p, &nuap);
2055 if (error)
2056 goto done2;
2057 sbytes += p->p_retval[0];
2058 }
2059 done2:
2060 file_drop(uap->s);
2061 done1:
2062 file_drop(uap->fd);
2063 done:
2064 if (uap->sbytes != NULL) {
2065 /* XXX this appears bogus for some early failure conditions */
2066 copyout(&sbytes, CAST_USER_ADDR_T(uap->sbytes), sizeof(off_t));
2067 }
2068 return (error);
2069 done3:
2070 socket_unlock(so, 1);
2071 goto done2;
2072 }
2073
2074 #endif