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