[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/uipc_syscalls.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

    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  * 4. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      @(#)uipc_syscalls.c     8.4 (Berkeley) 2/21/94
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD$");
   37 
   38 #include "opt_inet.h"
   39 #include "opt_inet6.h"
   40 #include "opt_sctp.h"
   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/lock.h>
   48 #include <sys/mutex.h>
   49 #include <sys/sysproto.h>
   50 #include <sys/malloc.h>
   51 #include <sys/filedesc.h>
   52 #include <sys/event.h>
   53 #include <sys/proc.h>
   54 #include <sys/fcntl.h>
   55 #include <sys/file.h>
   56 #include <sys/filio.h>
   57 #include <sys/mount.h>
   58 #include <sys/mbuf.h>
   59 #include <sys/protosw.h>
   60 #include <sys/sf_buf.h>
   61 #include <sys/socket.h>
   62 #include <sys/socketvar.h>
   63 #include <sys/signalvar.h>
   64 #include <sys/syscallsubr.h>
   65 #include <sys/sysctl.h>
   66 #include <sys/uio.h>
   67 #include <sys/vimage.h>
   68 #include <sys/vnode.h>
   69 #ifdef KTRACE
   70 #include <sys/ktrace.h>
   71 #endif
   72 
   73 #include <security/mac/mac_framework.h>
   74 
   75 #include <vm/vm.h>
   76 #include <vm/vm_object.h>
   77 #include <vm/vm_page.h>
   78 #include <vm/vm_pageout.h>
   79 #include <vm/vm_kern.h>
   80 #include <vm/vm_extern.h>
   81 
   82 #if defined(INET) || defined(INET6)
   83 #ifdef SCTP
   84 #include <netinet/sctp.h>
   85 #include <netinet/sctp_peeloff.h>
   86 #endif /* SCTP */
   87 #endif /* INET || INET6 */
   88 
   89 static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
   90 static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
   91 
   92 static int accept1(struct thread *td, struct accept_args *uap, int compat);
   93 static int do_sendfile(struct thread *td, struct sendfile_args *uap, int compat);
   94 static int getsockname1(struct thread *td, struct getsockname_args *uap,
   95                         int compat);
   96 static int getpeername1(struct thread *td, struct getpeername_args *uap,
   97                         int compat);
   98 
   99 /*
  100  * NSFBUFS-related variables and associated sysctls
  101  */
  102 int nsfbufs;
  103 int nsfbufspeak;
  104 int nsfbufsused;
  105 
  106 SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufs, CTLFLAG_RDTUN, &nsfbufs, 0,
  107     "Maximum number of sendfile(2) sf_bufs available");
  108 SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufspeak, CTLFLAG_RD, &nsfbufspeak, 0,
  109     "Number of sendfile(2) sf_bufs at peak usage");
  110 SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0,
  111     "Number of sendfile(2) sf_bufs in use");
  112 
  113 /*
  114  * Convert a user file descriptor to a kernel file entry.  A reference on the
  115  * file entry is held upon returning.  This is lighter weight than
  116  * fgetsock(), which bumps the socket reference drops the file reference
  117  * count instead, as this approach avoids several additional mutex operations
  118  * associated with the additional reference count.  If requested, return the
  119  * open file flags.
  120  */
  121 static int
  122 getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp)
  123 {
  124         struct file *fp;
  125         int error;
  126 
  127         fp = NULL;
  128         if (fdp == NULL || (fp = fget_unlocked(fdp, fd)) == NULL) {
  129                 error = EBADF;
  130         } else if (fp->f_type != DTYPE_SOCKET) {
  131                 fdrop(fp, curthread);
  132                 fp = NULL;
  133                 error = ENOTSOCK;
  134         } else {
  135                 if (fflagp != NULL)
  136                         *fflagp = fp->f_flag;
  137                 error = 0;
  138         }
  139         *fpp = fp;
  140         return (error);
  141 }
  142 
  143 /*
  144  * System call interface to the socket abstraction.
  145  */
  146 #if defined(COMPAT_43)
  147 #define COMPAT_OLDSOCK
  148 #endif
  149 
  150 int
  151 socket(td, uap)
  152         struct thread *td;
  153         struct socket_args /* {
  154                 int     domain;
  155                 int     type;
  156                 int     protocol;
  157         } */ *uap;
  158 {
  159         struct filedesc *fdp;
  160         struct socket *so;
  161         struct file *fp;
  162         int fd, error;
  163 
  164 #ifdef MAC
  165         error = mac_socket_check_create(td->td_ucred, uap->domain, uap->type,
  166             uap->protocol);
  167         if (error)
  168                 return (error);
  169 #endif
  170         fdp = td->td_proc->p_fd;
  171         error = falloc(td, &fp, &fd);
  172         if (error)
  173                 return (error);
  174         /* An extra reference on `fp' has been held for us by falloc(). */
  175         error = socreate(uap->domain, &so, uap->type, uap->protocol,
  176             td->td_ucred, td);
  177         if (error) {
  178                 fdclose(fdp, fp, fd, td);
  179         } else {
  180                 finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops);
  181                 td->td_retval[0] = fd;
  182         }
  183         fdrop(fp, td);
  184         return (error);
  185 }
  186 
  187 /* ARGSUSED */
  188 int
  189 bind(td, uap)
  190         struct thread *td;
  191         struct bind_args /* {
  192                 int     s;
  193                 caddr_t name;
  194                 int     namelen;
  195         } */ *uap;
  196 {
  197         struct sockaddr *sa;
  198         int error;
  199 
  200         if ((error = getsockaddr(&sa, uap->name, uap->namelen)) != 0)
  201                 return (error);
  202 
  203         error = kern_bind(td, uap->s, sa);
  204         free(sa, M_SONAME);
  205         return (error);
  206 }
  207 
  208 int
  209 kern_bind(td, fd, sa)
  210         struct thread *td;
  211         int fd;
  212         struct sockaddr *sa;
  213 {
  214         struct socket *so;
  215         struct file *fp;
  216         int error;
  217 
  218         error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
  219         if (error)
  220                 return (error);
  221         so = fp->f_data;
  222 #ifdef KTRACE
  223         if (KTRPOINT(td, KTR_STRUCT))
  224                 ktrsockaddr(sa);
  225 #endif
  226 #ifdef MAC
  227         error = mac_socket_check_bind(td->td_ucred, so, sa);
  228         if (error == 0)
  229 #endif
  230                 error = sobind(so, sa, td);
  231         fdrop(fp, td);
  232         return (error);
  233 }
  234 
  235 /* ARGSUSED */
  236 int
  237 listen(td, uap)
  238         struct thread *td;
  239         struct listen_args /* {
  240                 int     s;
  241                 int     backlog;
  242         } */ *uap;
  243 {
  244         struct socket *so;
  245         struct file *fp;
  246         int error;
  247 
  248         error = getsock(td->td_proc->p_fd, uap->s, &fp, NULL);
  249         if (error == 0) {
  250                 so = fp->f_data;
  251 #ifdef MAC
  252                 error = mac_socket_check_listen(td->td_ucred, so);
  253                 if (error == 0) {
  254 #endif
  255                         CURVNET_SET(so->so_vnet);
  256                         error = solisten(so, uap->backlog, td);
  257                         CURVNET_RESTORE();
  258 #ifdef MAC
  259                 }
  260 #endif
  261                 fdrop(fp, td);
  262         }
  263         return(error);
  264 }
  265 
  266 /*
  267  * accept1()
  268  */
  269 static int
  270 accept1(td, uap, compat)
  271         struct thread *td;
  272         struct accept_args /* {
  273                 int     s;
  274                 struct sockaddr * __restrict name;
  275                 socklen_t       * __restrict anamelen;
  276         } */ *uap;
  277         int compat;
  278 {
  279         struct sockaddr *name;
  280         socklen_t namelen;
  281         struct file *fp;
  282         int error;
  283 
  284         if (uap->name == NULL)
  285                 return (kern_accept(td, uap->s, NULL, NULL, NULL));
  286 
  287         error = copyin(uap->anamelen, &namelen, sizeof (namelen));
  288         if (error)
  289                 return (error);
  290 
  291         error = kern_accept(td, uap->s, &name, &namelen, &fp);
  292 
  293         /*
  294          * return a namelen of zero for older code which might
  295          * ignore the return value from accept.
  296          */
  297         if (error) {
  298                 (void) copyout(&namelen,
  299                     uap->anamelen, sizeof(*uap->anamelen));
  300                 return (error);
  301         }
  302 
  303         if (error == 0 && name != NULL) {
  304 #ifdef COMPAT_OLDSOCK
  305                 if (compat)
  306                         ((struct osockaddr *)name)->sa_family =
  307                             name->sa_family;
  308 #endif
  309                 error = copyout(name, uap->name, namelen);
  310         }
  311         if (error == 0)
  312                 error = copyout(&namelen, uap->anamelen,
  313                     sizeof(namelen));
  314         if (error)
  315                 fdclose(td->td_proc->p_fd, fp, td->td_retval[0], td);
  316         fdrop(fp, td);
  317         free(name, M_SONAME);
  318         return (error);
  319 }
  320 
  321 int
  322 kern_accept(struct thread *td, int s, struct sockaddr **name,
  323     socklen_t *namelen, struct file **fp)
  324 {
  325         struct filedesc *fdp;
  326         struct file *headfp, *nfp = NULL;
  327         struct sockaddr *sa = NULL;
  328         int error;
  329         struct socket *head, *so;
  330         int fd;
  331         u_int fflag;
  332         pid_t pgid;
  333         int tmp;
  334 
  335         if (name) {
  336                 *name = NULL;
  337                 if (*namelen < 0)
  338                         return (EINVAL);
  339         }
  340 
  341         fdp = td->td_proc->p_fd;
  342         error = getsock(fdp, s, &headfp, &fflag);
  343         if (error)
  344                 return (error);
  345         head = headfp->f_data;
  346         if ((head->so_options & SO_ACCEPTCONN) == 0) {
  347                 error = EINVAL;
  348                 goto done;
  349         }
  350 #ifdef MAC
  351         error = mac_socket_check_accept(td->td_ucred, head);
  352         if (error != 0)
  353                 goto done;
  354 #endif
  355         error = falloc(td, &nfp, &fd);
  356         if (error)
  357                 goto done;
  358         ACCEPT_LOCK();
  359         if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
  360                 ACCEPT_UNLOCK();
  361                 error = EWOULDBLOCK;
  362                 goto noconnection;
  363         }
  364         while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
  365                 if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
  366                         head->so_error = ECONNABORTED;
  367                         break;
  368                 }
  369                 error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH,
  370                     "accept", 0);
  371                 if (error) {
  372                         ACCEPT_UNLOCK();
  373                         goto noconnection;
  374                 }
  375         }
  376         if (head->so_error) {
  377                 error = head->so_error;
  378                 head->so_error = 0;
  379                 ACCEPT_UNLOCK();
  380                 goto noconnection;
  381         }
  382         so = TAILQ_FIRST(&head->so_comp);
  383         KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
  384         KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
  385 
  386         /*
  387          * Before changing the flags on the socket, we have to bump the
  388          * reference count.  Otherwise, if the protocol calls sofree(),
  389          * the socket will be released due to a zero refcount.
  390          */
  391         SOCK_LOCK(so);                  /* soref() and so_state update */
  392         soref(so);                      /* file descriptor reference */
  393 
  394         TAILQ_REMOVE(&head->so_comp, so, so_list);
  395         head->so_qlen--;
  396         so->so_state |= (head->so_state & SS_NBIO);
  397         so->so_qstate &= ~SQ_COMP;
  398         so->so_head = NULL;
  399 
  400         SOCK_UNLOCK(so);
  401         ACCEPT_UNLOCK();
  402 
  403         /* An extra reference on `nfp' has been held for us by falloc(). */
  404         td->td_retval[0] = fd;
  405 
  406         /* connection has been removed from the listen queue */
  407         KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0);
  408 
  409         pgid = fgetown(&head->so_sigio);
  410         if (pgid != 0)
  411                 fsetown(pgid, &so->so_sigio);
  412 
  413         finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
  414         /* Sync socket nonblocking/async state with file flags */
  415         tmp = fflag & FNONBLOCK;
  416         (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
  417         tmp = fflag & FASYNC;
  418         (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
  419         sa = 0;
  420         CURVNET_SET(so->so_vnet);
  421         error = soaccept(so, &sa);
  422         CURVNET_RESTORE();
  423         if (error) {
  424                 /*
  425                  * return a namelen of zero for older code which might
  426                  * ignore the return value from accept.
  427                  */
  428                 if (name)
  429                         *namelen = 0;
  430                 goto noconnection;
  431         }
  432         if (sa == NULL) {
  433                 if (name)
  434                         *namelen = 0;
  435                 goto done;
  436         }
  437         if (name) {
  438                 /* check sa_len before it is destroyed */
  439                 if (*namelen > sa->sa_len)
  440                         *namelen = sa->sa_len;
  441 #ifdef KTRACE
  442                 if (KTRPOINT(td, KTR_STRUCT))
  443                         ktrsockaddr(sa);
  444 #endif
  445                 *name = sa;
  446                 sa = NULL;
  447         }
  448 noconnection:
  449         if (sa)
  450                 free(sa, M_SONAME);
  451 
  452         /*
  453          * close the new descriptor, assuming someone hasn't ripped it
  454          * out from under us.
  455          */
  456         if (error)
  457                 fdclose(fdp, nfp, fd, td);
  458 
  459         /*
  460          * Release explicitly held references before returning.  We return
  461          * a reference on nfp to the caller on success if they request it.
  462          */
  463 done:
  464         if (fp != NULL) {
  465                 if (error == 0) {
  466                         *fp = nfp;
  467                         nfp = NULL;
  468                 } else
  469                         *fp = NULL;
  470         }
  471         if (nfp != NULL)
  472                 fdrop(nfp, td);
  473         fdrop(headfp, td);
  474         return (error);
  475 }
  476 
  477 int
  478 accept(td, uap)
  479         struct thread *td;
  480         struct accept_args *uap;
  481 {
  482 
  483         return (accept1(td, uap, 0));
  484 }
  485 
  486 #ifdef COMPAT_OLDSOCK
  487 int
  488 oaccept(td, uap)
  489         struct thread *td;
  490         struct accept_args *uap;
  491 {
  492 
  493         return (accept1(td, uap, 1));
  494 }
  495 #endif /* COMPAT_OLDSOCK */
  496 
  497 /* ARGSUSED */
  498 int
  499 connect(td, uap)
  500         struct thread *td;
  501         struct connect_args /* {
  502                 int     s;
  503                 caddr_t name;
  504                 int     namelen;
  505         } */ *uap;
  506 {
  507         struct sockaddr *sa;
  508         int error;
  509 
  510         error = getsockaddr(&sa, uap->name, uap->namelen);
  511         if (error)
  512                 return (error);
  513 
  514         error = kern_connect(td, uap->s, sa);
  515         free(sa, M_SONAME);
  516         return (error);
  517 }
  518 
  519 
  520 int
  521 kern_connect(td, fd, sa)
  522         struct thread *td;
  523         int fd;
  524         struct sockaddr *sa;
  525 {
  526         struct socket *so;
  527         struct file *fp;
  528         int error;
  529         int interrupted = 0;
  530 
  531         error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
  532         if (error)
  533                 return (error);
  534         so = fp->f_data;
  535         if (so->so_state & SS_ISCONNECTING) {
  536                 error = EALREADY;
  537                 goto done1;
  538         }
  539 #ifdef KTRACE
  540         if (KTRPOINT(td, KTR_STRUCT))
  541                 ktrsockaddr(sa);
  542 #endif
  543 #ifdef MAC
  544         error = mac_socket_check_connect(td->td_ucred, so, sa);
  545         if (error)
  546                 goto bad;
  547 #endif
  548         error = soconnect(so, sa, td);
  549         if (error)
  550                 goto bad;
  551         if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
  552                 error = EINPROGRESS;
  553                 goto done1;
  554         }
  555         SOCK_LOCK(so);
  556         while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
  557                 error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH,
  558                     "connec", 0);
  559                 if (error) {
  560                         if (error == EINTR || error == ERESTART)
  561                                 interrupted = 1;
  562                         break;
  563                 }
  564         }
  565         if (error == 0) {
  566                 error = so->so_error;
  567                 so->so_error = 0;
  568         }
  569         SOCK_UNLOCK(so);
  570 bad:
  571         if (!interrupted)
  572                 so->so_state &= ~SS_ISCONNECTING;
  573         if (error == ERESTART)
  574                 error = EINTR;
  575 done1:
  576         fdrop(fp, td);
  577         return (error);
  578 }
  579 
  580 int
  581 kern_socketpair(struct thread *td, int domain, int type, int protocol,
  582     int *rsv)
  583 {
  584         struct filedesc *fdp = td->td_proc->p_fd;
  585         struct file *fp1, *fp2;
  586         struct socket *so1, *so2;
  587         int fd, error;
  588 
  589 #ifdef MAC
  590         /* We might want to have a separate check for socket pairs. */
  591         error = mac_socket_check_create(td->td_ucred, domain, type,
  592             protocol);
  593         if (error)
  594                 return (error);
  595 #endif
  596         error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
  597         if (error)
  598                 return (error);
  599         error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
  600         if (error)
  601                 goto free1;
  602         /* On success extra reference to `fp1' and 'fp2' is set by falloc. */
  603         error = falloc(td, &fp1, &fd);
  604         if (error)
  605                 goto free2;
  606         rsv[0] = fd;
  607         fp1->f_data = so1;      /* so1 already has ref count */
  608         error = falloc(td, &fp2, &fd);
  609         if (error)
  610                 goto free3;
  611         fp2->f_data = so2;      /* so2 already has ref count */
  612         rsv[1] = fd;
  613         error = soconnect2(so1, so2);
  614         if (error)
  615                 goto free4;
  616         if (type == SOCK_DGRAM) {
  617                 /*
  618                  * Datagram socket connection is asymmetric.
  619                  */
  620                  error = soconnect2(so2, so1);
  621                  if (error)
  622                         goto free4;
  623         }
  624         finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops);
  625         finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops);
  626         fdrop(fp1, td);
  627         fdrop(fp2, td);
  628         return (0);
  629 free4:
  630         fdclose(fdp, fp2, rsv[1], td);
  631         fdrop(fp2, td);
  632 free3:
  633         fdclose(fdp, fp1, rsv[0], td);
  634         fdrop(fp1, td);
  635 free2:
  636         if (so2 != NULL)
  637                 (void)soclose(so2);
  638 free1:
  639         if (so1 != NULL)
  640                 (void)soclose(so1);
  641         return (error);
  642 }
  643 
  644 int
  645 socketpair(struct thread *td, struct socketpair_args *uap)
  646 {
  647         int error, sv[2];
  648 
  649         error = kern_socketpair(td, uap->domain, uap->type,
  650             uap->protocol, sv);
  651         if (error)
  652                 return (error);
  653         error = copyout(sv, uap->rsv, 2 * sizeof(int));
  654         if (error) {
  655                 (void)kern_close(td, sv[0]);
  656                 (void)kern_close(td, sv[1]);
  657         }
  658         return (error);
  659 }
  660 
  661 static int
  662 sendit(td, s, mp, flags)
  663         struct thread *td;
  664         int s;
  665         struct msghdr *mp;
  666         int flags;
  667 {
  668         struct mbuf *control;
  669         struct sockaddr *to;
  670         int error;
  671 
  672         if (mp->msg_name != NULL) {
  673                 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
  674                 if (error) {
  675                         to = NULL;
  676                         goto bad;
  677                 }
  678                 mp->msg_name = to;
  679         } else {
  680                 to = NULL;
  681         }
  682 
  683         if (mp->msg_control) {
  684                 if (mp->msg_controllen < sizeof(struct cmsghdr)
  685 #ifdef COMPAT_OLDSOCK
  686                     && mp->msg_flags != MSG_COMPAT
  687 #endif
  688                 ) {
  689                         error = EINVAL;
  690                         goto bad;
  691                 }
  692                 error = sockargs(&control, mp->msg_control,
  693                     mp->msg_controllen, MT_CONTROL);
  694                 if (error)
  695                         goto bad;
  696 #ifdef COMPAT_OLDSOCK
  697                 if (mp->msg_flags == MSG_COMPAT) {
  698                         struct cmsghdr *cm;
  699 
  700                         M_PREPEND(control, sizeof(*cm), M_WAIT);
  701                         cm = mtod(control, struct cmsghdr *);
  702                         cm->cmsg_len = control->m_len;
  703                         cm->cmsg_level = SOL_SOCKET;
  704                         cm->cmsg_type = SCM_RIGHTS;
  705                 }
  706 #endif
  707         } else {
  708                 control = NULL;
  709         }
  710 
  711         error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
  712 
  713 bad:
  714         if (to)
  715                 free(to, M_SONAME);
  716         return (error);
  717 }
  718 
  719 int
  720 kern_sendit(td, s, mp, flags, control, segflg)
  721         struct thread *td;
  722         int s;
  723         struct msghdr *mp;
  724         int flags;
  725         struct mbuf *control;
  726         enum uio_seg segflg;
  727 {
  728         struct file *fp;
  729         struct uio auio;
  730         struct iovec *iov;
  731         struct socket *so;
  732         int i;
  733         int len, error;
  734 #ifdef KTRACE
  735         struct uio *ktruio = NULL;
  736 #endif
  737 
  738         error = getsock(td->td_proc->p_fd, s, &fp, NULL);
  739         if (error)
  740                 return (error);
  741         so = (struct socket *)fp->f_data;
  742 
  743 #ifdef MAC
  744         if (mp->msg_name != NULL) {
  745                 error = mac_socket_check_connect(td->td_ucred, so,
  746                     mp->msg_name);
  747                 if (error)
  748                         goto bad;
  749         }
  750         error = mac_socket_check_send(td->td_ucred, so);
  751         if (error)
  752                 goto bad;
  753 #endif
  754 
  755         auio.uio_iov = mp->msg_iov;
  756         auio.uio_iovcnt = mp->msg_iovlen;
  757         auio.uio_segflg = segflg;
  758         auio.uio_rw = UIO_WRITE;
  759         auio.uio_td = td;
  760         auio.uio_offset = 0;                    /* XXX */
  761         auio.uio_resid = 0;
  762         iov = mp->msg_iov;
  763         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  764                 if ((auio.uio_resid += iov->iov_len) < 0) {
  765                         error = EINVAL;
  766                         goto bad;
  767                 }
  768         }
  769 #ifdef KTRACE
  770         if (KTRPOINT(td, KTR_GENIO))
  771                 ktruio = cloneuio(&auio);
  772 #endif
  773         len = auio.uio_resid;
  774         error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
  775         if (error) {
  776                 if (auio.uio_resid != len && (error == ERESTART ||
  777                     error == EINTR || error == EWOULDBLOCK))
  778                         error = 0;
  779                 /* Generation of SIGPIPE can be controlled per socket */
  780                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
  781                     !(flags & MSG_NOSIGNAL)) {
  782                         PROC_LOCK(td->td_proc);
  783                         psignal(td->td_proc, SIGPIPE);
  784                         PROC_UNLOCK(td->td_proc);
  785                 }
  786         }
  787         if (error == 0)
  788                 td->td_retval[0] = len - auio.uio_resid;
  789 #ifdef KTRACE
  790         if (ktruio != NULL) {
  791                 ktruio->uio_resid = td->td_retval[0];
  792                 ktrgenio(s, UIO_WRITE, ktruio, error);
  793         }
  794 #endif
  795 bad:
  796         fdrop(fp, td);
  797         return (error);
  798 }
  799 
  800 int
  801 sendto(td, uap)
  802         struct thread *td;
  803         struct sendto_args /* {
  804                 int     s;
  805                 caddr_t buf;
  806                 size_t  len;
  807                 int     flags;
  808                 caddr_t to;
  809                 int     tolen;
  810         } */ *uap;
  811 {
  812         struct msghdr msg;
  813         struct iovec aiov;
  814         int error;
  815 
  816         msg.msg_name = uap->to;
  817         msg.msg_namelen = uap->tolen;
  818         msg.msg_iov = &aiov;
  819         msg.msg_iovlen = 1;
  820         msg.msg_control = 0;
  821 #ifdef COMPAT_OLDSOCK
  822         msg.msg_flags = 0;
  823 #endif
  824         aiov.iov_base = uap->buf;
  825         aiov.iov_len = uap->len;
  826         error = sendit(td, uap->s, &msg, uap->flags);
  827         return (error);
  828 }
  829 
  830 #ifdef COMPAT_OLDSOCK
  831 int
  832 osend(td, uap)
  833         struct thread *td;
  834         struct osend_args /* {
  835                 int     s;
  836                 caddr_t buf;
  837                 int     len;
  838                 int     flags;
  839         } */ *uap;
  840 {
  841         struct msghdr msg;
  842         struct iovec aiov;
  843         int error;
  844 
  845         msg.msg_name = 0;
  846         msg.msg_namelen = 0;
  847         msg.msg_iov = &aiov;
  848         msg.msg_iovlen = 1;
  849         aiov.iov_base = uap->buf;
  850         aiov.iov_len = uap->len;
  851         msg.msg_control = 0;
  852         msg.msg_flags = 0;
  853         error = sendit(td, uap->s, &msg, uap->flags);
  854         return (error);
  855 }
  856 
  857 int
  858 osendmsg(td, uap)
  859         struct thread *td;
  860         struct osendmsg_args /* {
  861                 int     s;
  862                 caddr_t msg;
  863                 int     flags;
  864         } */ *uap;
  865 {
  866         struct msghdr msg;
  867         struct iovec *iov;
  868         int error;
  869 
  870         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
  871         if (error)
  872                 return (error);
  873         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
  874         if (error)
  875                 return (error);
  876         msg.msg_iov = iov;
  877         msg.msg_flags = MSG_COMPAT;
  878         error = sendit(td, uap->s, &msg, uap->flags);
  879         free(iov, M_IOV);
  880         return (error);
  881 }
  882 #endif
  883 
  884 int
  885 sendmsg(td, uap)
  886         struct thread *td;
  887         struct sendmsg_args /* {
  888                 int     s;
  889                 caddr_t msg;
  890                 int     flags;
  891         } */ *uap;
  892 {
  893         struct msghdr msg;
  894         struct iovec *iov;
  895         int error;
  896 
  897         error = copyin(uap->msg, &msg, sizeof (msg));
  898         if (error)
  899                 return (error);
  900         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
  901         if (error)
  902                 return (error);
  903         msg.msg_iov = iov;
  904 #ifdef COMPAT_OLDSOCK
  905         msg.msg_flags = 0;
  906 #endif
  907         error = sendit(td, uap->s, &msg, uap->flags);
  908         free(iov, M_IOV);
  909         return (error);
  910 }
  911 
  912 int
  913 kern_recvit(td, s, mp, fromseg, controlp)
  914         struct thread *td;
  915         int s;
  916         struct msghdr *mp;
  917         enum uio_seg fromseg;
  918         struct mbuf **controlp;
  919 {
  920         struct uio auio;
  921         struct iovec *iov;
  922         int i;
  923         socklen_t len;
  924         int error;
  925         struct mbuf *m, *control = 0;
  926         caddr_t ctlbuf;
  927         struct file *fp;
  928         struct socket *so;
  929         struct sockaddr *fromsa = 0;
  930 #ifdef KTRACE
  931         struct uio *ktruio = NULL;
  932 #endif
  933 
  934         if(controlp != NULL)
  935                 *controlp = 0;
  936 
  937         error = getsock(td->td_proc->p_fd, s, &fp, NULL);
  938         if (error)
  939                 return (error);
  940         so = fp->f_data;
  941 
  942 #ifdef MAC
  943         error = mac_socket_check_receive(td->td_ucred, so);
  944         if (error) {
  945                 fdrop(fp, td);
  946                 return (error);
  947         }
  948 #endif
  949 
  950         auio.uio_iov = mp->msg_iov;
  951         auio.uio_iovcnt = mp->msg_iovlen;
  952         auio.uio_segflg = UIO_USERSPACE;
  953         auio.uio_rw = UIO_READ;
  954         auio.uio_td = td;
  955         auio.uio_offset = 0;                    /* XXX */
  956         auio.uio_resid = 0;
  957         iov = mp->msg_iov;
  958         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  959                 if ((auio.uio_resid += iov->iov_len) < 0) {
  960                         fdrop(fp, td);
  961                         return (EINVAL);
  962                 }
  963         }
  964 #ifdef KTRACE
  965         if (KTRPOINT(td, KTR_GENIO))
  966                 ktruio = cloneuio(&auio);
  967 #endif
  968         len = auio.uio_resid;
  969         CURVNET_SET(so->so_vnet);
  970         error = soreceive(so, &fromsa, &auio, (struct mbuf **)0,
  971             (mp->msg_control || controlp) ? &control : (struct mbuf **)0,
  972             &mp->msg_flags);
  973         CURVNET_RESTORE();
  974         if (error) {
  975                 if (auio.uio_resid != (int)len && (error == ERESTART ||
  976                     error == EINTR || error == EWOULDBLOCK))
  977                         error = 0;
  978         }
  979 #ifdef KTRACE
  980         if (ktruio != NULL) {
  981                 ktruio->uio_resid = (int)len - auio.uio_resid;
  982                 ktrgenio(s, UIO_READ, ktruio, error);
  983         }
  984 #endif
  985         if (error)
  986                 goto out;
  987         td->td_retval[0] = (int)len - auio.uio_resid;
  988         if (mp->msg_name) {
  989                 len = mp->msg_namelen;
  990                 if (len <= 0 || fromsa == 0)
  991                         len = 0;
  992                 else {
  993                         /* save sa_len before it is destroyed by MSG_COMPAT */
  994                         len = MIN(len, fromsa->sa_len);
  995 #ifdef COMPAT_OLDSOCK
  996                         if (mp->msg_flags & MSG_COMPAT)
  997                                 ((struct osockaddr *)fromsa)->sa_family =
  998                                     fromsa->sa_family;
  999 #endif
 1000                         if (fromseg == UIO_USERSPACE) {
 1001                                 error = copyout(fromsa, mp->msg_name,
 1002                                     (unsigned)len);
 1003                                 if (error)
 1004                                         goto out;
 1005                         } else
 1006                                 bcopy(fromsa, mp->msg_name, len);
 1007                 }
 1008                 mp->msg_namelen = len;
 1009         }
 1010         if (mp->msg_control && controlp == NULL) {
 1011 #ifdef COMPAT_OLDSOCK
 1012                 /*
 1013                  * We assume that old recvmsg calls won't receive access
 1014                  * rights and other control info, esp. as control info
 1015                  * is always optional and those options didn't exist in 4.3.
 1016                  * If we receive rights, trim the cmsghdr; anything else
 1017                  * is tossed.
 1018                  */
 1019                 if (control && mp->msg_flags & MSG_COMPAT) {
 1020                         if (mtod(control, struct cmsghdr *)->cmsg_level !=
 1021                             SOL_SOCKET ||
 1022                             mtod(control, struct cmsghdr *)->cmsg_type !=
 1023                             SCM_RIGHTS) {
 1024                                 mp->msg_controllen = 0;
 1025                                 goto out;
 1026                         }
 1027                         control->m_len -= sizeof (struct cmsghdr);
 1028                         control->m_data += sizeof (struct cmsghdr);
 1029                 }
 1030 #endif
 1031                 len = mp->msg_controllen;
 1032                 m = control;
 1033                 mp->msg_controllen = 0;
 1034                 ctlbuf = mp->msg_control;
 1035 
 1036                 while (m && len > 0) {
 1037                         unsigned int tocopy;
 1038 
 1039                         if (len >= m->m_len)
 1040                                 tocopy = m->m_len;
 1041                         else {
 1042                                 mp->msg_flags |= MSG_CTRUNC;
 1043                                 tocopy = len;
 1044                         }
 1045 
 1046                         if ((error = copyout(mtod(m, caddr_t),
 1047                                         ctlbuf, tocopy)) != 0)
 1048                                 goto out;
 1049 
 1050                         ctlbuf += tocopy;
 1051                         len -= tocopy;
 1052                         m = m->m_next;
 1053                 }
 1054                 mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
 1055         }
 1056 out:
 1057         fdrop(fp, td);
 1058 #ifdef KTRACE
 1059         if (fromsa && KTRPOINT(td, KTR_STRUCT))
 1060                 ktrsockaddr(fromsa);
 1061 #endif
 1062         if (fromsa)
 1063                 free(fromsa, M_SONAME);
 1064 
 1065         if (error == 0 && controlp != NULL)  
 1066                 *controlp = control;
 1067         else  if (control)
 1068                 m_freem(control);
 1069 
 1070         return (error);
 1071 }
 1072 
 1073 static int
 1074 recvit(td, s, mp, namelenp)
 1075         struct thread *td;
 1076         int s;
 1077         struct msghdr *mp;
 1078         void *namelenp;
 1079 {
 1080         int error;
 1081 
 1082         error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL);
 1083         if (error)
 1084                 return (error);
 1085         if (namelenp) {
 1086                 error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
 1087 #ifdef COMPAT_OLDSOCK
 1088                 if (mp->msg_flags & MSG_COMPAT)
 1089                         error = 0;      /* old recvfrom didn't check */
 1090 #endif
 1091         }
 1092         return (error);
 1093 }
 1094 
 1095 int
 1096 recvfrom(td, uap)
 1097         struct thread *td;
 1098         struct recvfrom_args /* {
 1099                 int     s;
 1100                 caddr_t buf;
 1101                 size_t  len;
 1102                 int     flags;
 1103                 struct sockaddr * __restrict    from;
 1104                 socklen_t * __restrict fromlenaddr;
 1105         } */ *uap;
 1106 {
 1107         struct msghdr msg;
 1108         struct iovec aiov;
 1109         int error;
 1110 
 1111         if (uap->fromlenaddr) {
 1112                 error = copyin(uap->fromlenaddr,
 1113                     &msg.msg_namelen, sizeof (msg.msg_namelen));
 1114                 if (error)
 1115                         goto done2;
 1116         } else {
 1117                 msg.msg_namelen = 0;
 1118         }
 1119         msg.msg_name = uap->from;
 1120         msg.msg_iov = &aiov;
 1121         msg.msg_iovlen = 1;
 1122         aiov.iov_base = uap->buf;
 1123         aiov.iov_len = uap->len;
 1124         msg.msg_control = 0;
 1125         msg.msg_flags = uap->flags;
 1126         error = recvit(td, uap->s, &msg, uap->fromlenaddr);
 1127 done2:
 1128         return(error);
 1129 }
 1130 
 1131 #ifdef COMPAT_OLDSOCK
 1132 int
 1133 orecvfrom(td, uap)
 1134         struct thread *td;
 1135         struct recvfrom_args *uap;
 1136 {
 1137 
 1138         uap->flags |= MSG_COMPAT;
 1139         return (recvfrom(td, uap));
 1140 }
 1141 #endif
 1142 
 1143 #ifdef COMPAT_OLDSOCK
 1144 int
 1145 orecv(td, uap)
 1146         struct thread *td;
 1147         struct orecv_args /* {
 1148                 int     s;
 1149                 caddr_t buf;
 1150                 int     len;
 1151                 int     flags;
 1152         } */ *uap;
 1153 {
 1154         struct msghdr msg;
 1155         struct iovec aiov;
 1156         int error;
 1157 
 1158         msg.msg_name = 0;
 1159         msg.msg_namelen = 0;
 1160         msg.msg_iov = &aiov;
 1161         msg.msg_iovlen = 1;
 1162         aiov.iov_base = uap->buf;
 1163         aiov.iov_len = uap->len;
 1164         msg.msg_control = 0;
 1165         msg.msg_flags = uap->flags;
 1166         error = recvit(td, uap->s, &msg, NULL);
 1167         return (error);
 1168 }
 1169 
 1170 /*
 1171  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
 1172  * overlays the new one, missing only the flags, and with the (old) access
 1173  * rights where the control fields are now.
 1174  */
 1175 int
 1176 orecvmsg(td, uap)
 1177         struct thread *td;
 1178         struct orecvmsg_args /* {
 1179                 int     s;
 1180                 struct  omsghdr *msg;
 1181                 int     flags;
 1182         } */ *uap;
 1183 {
 1184         struct msghdr msg;
 1185         struct iovec *iov;
 1186         int error;
 1187 
 1188         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
 1189         if (error)
 1190                 return (error);
 1191         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
 1192         if (error)
 1193                 return (error);
 1194         msg.msg_flags = uap->flags | MSG_COMPAT;
 1195         msg.msg_iov = iov;
 1196         error = recvit(td, uap->s, &msg, &uap->msg->msg_namelen);
 1197         if (msg.msg_controllen && error == 0)
 1198                 error = copyout(&msg.msg_controllen,
 1199                     &uap->msg->msg_accrightslen, sizeof (int));
 1200         free(iov, M_IOV);
 1201         return (error);
 1202 }
 1203 #endif
 1204 
 1205 int
 1206 recvmsg(td, uap)
 1207         struct thread *td;
 1208         struct recvmsg_args /* {
 1209                 int     s;
 1210                 struct  msghdr *msg;
 1211                 int     flags;
 1212         } */ *uap;
 1213 {
 1214         struct msghdr msg;
 1215         struct iovec *uiov, *iov;
 1216         int error;
 1217 
 1218         error = copyin(uap->msg, &msg, sizeof (msg));
 1219         if (error)
 1220                 return (error);
 1221         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
 1222         if (error)
 1223                 return (error);
 1224         msg.msg_flags = uap->flags;
 1225 #ifdef COMPAT_OLDSOCK
 1226         msg.msg_flags &= ~MSG_COMPAT;
 1227 #endif
 1228         uiov = msg.msg_iov;
 1229         msg.msg_iov = iov;
 1230         error = recvit(td, uap->s, &msg, NULL);
 1231         if (error == 0) {
 1232                 msg.msg_iov = uiov;
 1233                 error = copyout(&msg, uap->msg, sizeof(msg));
 1234         }
 1235         free(iov, M_IOV);
 1236         return (error);
 1237 }
 1238 
 1239 /* ARGSUSED */
 1240 int
 1241 shutdown(td, uap)
 1242         struct thread *td;
 1243         struct shutdown_args /* {
 1244                 int     s;
 1245                 int     how;
 1246         } */ *uap;
 1247 {
 1248         struct socket *so;
 1249         struct file *fp;
 1250         int error;
 1251 
 1252         error = getsock(td->td_proc->p_fd, uap->s, &fp, NULL);
 1253         if (error == 0) {
 1254                 so = fp->f_data;
 1255                 error = soshutdown(so, uap->how);
 1256                 fdrop(fp, td);
 1257         }
 1258         return (error);
 1259 }
 1260 
 1261 /* ARGSUSED */
 1262 int
 1263 setsockopt(td, uap)
 1264         struct thread *td;
 1265         struct setsockopt_args /* {
 1266                 int     s;
 1267                 int     level;
 1268                 int     name;
 1269                 caddr_t val;
 1270                 int     valsize;
 1271         } */ *uap;
 1272 {
 1273 
 1274         return (kern_setsockopt(td, uap->s, uap->level, uap->name,
 1275             uap->val, UIO_USERSPACE, uap->valsize));
 1276 }
 1277 
 1278 int
 1279 kern_setsockopt(td, s, level, name, val, valseg, valsize)
 1280         struct thread *td;
 1281         int s;
 1282         int level;
 1283         int name;
 1284         void *val;
 1285         enum uio_seg valseg;
 1286         socklen_t valsize;
 1287 {
 1288         int error;
 1289         struct socket *so;
 1290         struct file *fp;
 1291         struct sockopt sopt;
 1292 
 1293         if (val == NULL && valsize != 0)
 1294                 return (EFAULT);
 1295         if ((int)valsize < 0)
 1296                 return (EINVAL);
 1297 
 1298         sopt.sopt_dir = SOPT_SET;
 1299         sopt.sopt_level = level;
 1300         sopt.sopt_name = name;
 1301         sopt.sopt_val = val;
 1302         sopt.sopt_valsize = valsize;
 1303         switch (valseg) {
 1304         case UIO_USERSPACE:
 1305                 sopt.sopt_td = td;
 1306                 break;
 1307         case UIO_SYSSPACE:
 1308                 sopt.sopt_td = NULL;
 1309                 break;
 1310         default:
 1311                 panic("kern_setsockopt called with bad valseg");
 1312         }
 1313 
 1314         error = getsock(td->td_proc->p_fd, s, &fp, NULL);
 1315         if (error == 0) {
 1316                 so = fp->f_data;
 1317                 CURVNET_SET(so->so_vnet);
 1318                 error = sosetopt(so, &sopt);
 1319                 CURVNET_RESTORE();
 1320                 fdrop(fp, td);
 1321         }
 1322         return(error);
 1323 }
 1324 
 1325 /* ARGSUSED */
 1326 int
 1327 getsockopt(td, uap)
 1328         struct thread *td;
 1329         struct getsockopt_args /* {
 1330                 int     s;
 1331                 int     level;
 1332                 int     name;
 1333                 void * __restrict       val;
 1334                 socklen_t * __restrict avalsize;
 1335         } */ *uap;
 1336 {
 1337         socklen_t valsize;
 1338         int     error;
 1339 
 1340         if (uap->val) {
 1341                 error = copyin(uap->avalsize, &valsize, sizeof (valsize));
 1342                 if (error)
 1343                         return (error);
 1344         }
 1345 
 1346         error = kern_getsockopt(td, uap->s, uap->level, uap->name,
 1347             uap->val, UIO_USERSPACE, &valsize);
 1348 
 1349         if (error == 0)
 1350                 error = copyout(&valsize, uap->avalsize, sizeof (valsize));
 1351         return (error);
 1352 }
 1353 
 1354 /*
 1355  * Kernel version of getsockopt.
 1356  * optval can be a userland or userspace. optlen is always a kernel pointer.
 1357  */
 1358 int
 1359 kern_getsockopt(td, s, level, name, val, valseg, valsize)
 1360         struct thread *td;
 1361         int s;
 1362         int level;
 1363         int name;
 1364         void *val;
 1365         enum uio_seg valseg;
 1366         socklen_t *valsize;
 1367 {
 1368         int error;
 1369         struct  socket *so;
 1370         struct file *fp;
 1371         struct  sockopt sopt;
 1372 
 1373         if (val == NULL)
 1374                 *valsize = 0;
 1375         if ((int)*valsize < 0)
 1376                 return (EINVAL);
 1377 
 1378         sopt.sopt_dir = SOPT_GET;
 1379         sopt.sopt_level = level;
 1380         sopt.sopt_name = name;
 1381         sopt.sopt_val = val;
 1382         sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
 1383         switch (valseg) {
 1384         case UIO_USERSPACE:
 1385                 sopt.sopt_td = td;
 1386                 break;
 1387         case UIO_SYSSPACE:
 1388                 sopt.sopt_td = NULL;
 1389                 break;
 1390         default:
 1391                 panic("kern_getsockopt called with bad valseg");
 1392         }
 1393 
 1394         error = getsock(td->td_proc->p_fd, s, &fp, NULL);
 1395         if (error == 0) {
 1396                 so = fp->f_data;
 1397                 CURVNET_SET(so->so_vnet);
 1398                 error = sogetopt(so, &sopt);
 1399                 CURVNET_RESTORE();
 1400                 *valsize = sopt.sopt_valsize;
 1401                 fdrop(fp, td);
 1402         }
 1403         return (error);
 1404 }
 1405 
 1406 /*
 1407  * getsockname1() - Get socket name.
 1408  */
 1409 /* ARGSUSED */
 1410 static int
 1411 getsockname1(td, uap, compat)
 1412         struct thread *td;
 1413         struct getsockname_args /* {
 1414                 int     fdes;
 1415                 struct sockaddr * __restrict asa;
 1416                 socklen_t * __restrict alen;
 1417         } */ *uap;
 1418         int compat;
 1419 {
 1420         struct sockaddr *sa;
 1421         socklen_t len;
 1422         int error;
 1423 
 1424         error = copyin(uap->alen, &len, sizeof(len));
 1425         if (error)
 1426                 return (error);
 1427 
 1428         error = kern_getsockname(td, uap->fdes, &sa, &len);
 1429         if (error)
 1430                 return (error);
 1431 
 1432         if (len != 0) {
 1433 #ifdef COMPAT_OLDSOCK
 1434                 if (compat)
 1435                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
 1436 #endif
 1437                 error = copyout(sa, uap->asa, (u_int)len);
 1438         }
 1439         free(sa, M_SONAME);
 1440         if (error == 0)
 1441                 error = copyout(&len, uap->alen, sizeof(len));
 1442         return (error);
 1443 }
 1444 
 1445 int
 1446 kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
 1447     socklen_t *alen)
 1448 {
 1449         struct socket *so;
 1450         struct file *fp;
 1451         socklen_t len;
 1452         int error;
 1453 
 1454         if (*alen < 0)
 1455                 return (EINVAL);
 1456 
 1457         error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
 1458         if (error)
 1459                 return (error);
 1460         so = fp->f_data;
 1461         *sa = NULL;
 1462         CURVNET_SET(so->so_vnet);
 1463         error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa);
 1464         CURVNET_RESTORE();
 1465         if (error)
 1466                 goto bad;
 1467         if (*sa == NULL)
 1468                 len = 0;
 1469         else
 1470                 len = MIN(*alen, (*sa)->sa_len);
 1471         *alen = len;
 1472 #ifdef KTRACE
 1473         if (KTRPOINT(td, KTR_STRUCT))
 1474                 ktrsockaddr(*sa);
 1475 #endif
 1476 bad:
 1477         fdrop(fp, td);
 1478         if (error && *sa) {
 1479                 free(*sa, M_SONAME);
 1480                 *sa = NULL;
 1481         }
 1482         return (error);
 1483 }
 1484 
 1485 int
 1486 getsockname(td, uap)
 1487         struct thread *td;
 1488         struct getsockname_args *uap;
 1489 {
 1490 
 1491         return (getsockname1(td, uap, 0));
 1492 }
 1493 
 1494 #ifdef COMPAT_OLDSOCK
 1495 int
 1496 ogetsockname(td, uap)
 1497         struct thread *td;
 1498         struct getsockname_args *uap;
 1499 {
 1500 
 1501         return (getsockname1(td, uap, 1));
 1502 }
 1503 #endif /* COMPAT_OLDSOCK */
 1504 
 1505 /*
 1506  * getpeername1() - Get name of peer for connected socket.
 1507  */
 1508 /* ARGSUSED */
 1509 static int
 1510 getpeername1(td, uap, compat)
 1511         struct thread *td;
 1512         struct getpeername_args /* {
 1513                 int     fdes;
 1514                 struct sockaddr * __restrict    asa;
 1515                 socklen_t * __restrict  alen;
 1516         } */ *uap;
 1517         int compat;
 1518 {
 1519         struct sockaddr *sa;
 1520         socklen_t len;
 1521         int error;
 1522 
 1523         error = copyin(uap->alen, &len, sizeof (len));
 1524         if (error)
 1525                 return (error);
 1526 
 1527         error = kern_getpeername(td, uap->fdes, &sa, &len);
 1528         if (error)
 1529                 return (error);
 1530 
 1531         if (len != 0) {
 1532 #ifdef COMPAT_OLDSOCK
 1533                 if (compat)
 1534                         ((struct osockaddr *)sa)->sa_family = sa->sa_family;
 1535 #endif
 1536                 error = copyout(sa, uap->asa, (u_int)len);
 1537         }
 1538         free(sa, M_SONAME);
 1539         if (error == 0)
 1540                 error = copyout(&len, uap->alen, sizeof(len));
 1541         return (error);
 1542 }
 1543 
 1544 int
 1545 kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
 1546     socklen_t *alen)
 1547 {
 1548         struct socket *so;
 1549         struct file *fp;
 1550         socklen_t len;
 1551         int error;
 1552 
 1553         if (*alen < 0)
 1554                 return (EINVAL);
 1555 
 1556         error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
 1557         if (error)
 1558                 return (error);
 1559         so = fp->f_data;
 1560         if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
 1561                 error = ENOTCONN;
 1562                 goto done;
 1563         }
 1564         *sa = NULL;
 1565         CURVNET_SET(so->so_vnet);
 1566         error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa);
 1567         CURVNET_RESTORE();
 1568         if (error)
 1569                 goto bad;
 1570         if (*sa == NULL)
 1571                 len = 0;
 1572         else
 1573                 len = MIN(*alen, (*sa)->sa_len);
 1574         *alen = len;
 1575 #ifdef KTRACE
 1576         if (KTRPOINT(td, KTR_STRUCT))
 1577                 ktrsockaddr(*sa);
 1578 #endif
 1579 bad:
 1580         if (error && *sa) {
 1581                 free(*sa, M_SONAME);
 1582                 *sa = NULL;
 1583         }
 1584 done:
 1585         fdrop(fp, td);
 1586         return (error);
 1587 }
 1588 
 1589 int
 1590 getpeername(td, uap)
 1591         struct thread *td;
 1592         struct getpeername_args *uap;
 1593 {
 1594 
 1595         return (getpeername1(td, uap, 0));
 1596 }
 1597 
 1598 #ifdef COMPAT_OLDSOCK
 1599 int
 1600 ogetpeername(td, uap)
 1601         struct thread *td;
 1602         struct ogetpeername_args *uap;
 1603 {
 1604 
 1605         /* XXX uap should have type `getpeername_args *' to begin with. */
 1606         return (getpeername1(td, (struct getpeername_args *)uap, 1));
 1607 }
 1608 #endif /* COMPAT_OLDSOCK */
 1609 
 1610 int
 1611 sockargs(mp, buf, buflen, type)
 1612         struct mbuf **mp;
 1613         caddr_t buf;
 1614         int buflen, type;
 1615 {
 1616         struct sockaddr *sa;
 1617         struct mbuf *m;
 1618         int error;
 1619 
 1620         if ((u_int)buflen > MLEN) {
 1621 #ifdef COMPAT_OLDSOCK
 1622                 if (type == MT_SONAME && (u_int)buflen <= 112)
 1623                         buflen = MLEN;          /* unix domain compat. hack */
 1624                 else
 1625 #endif
 1626                         if ((u_int)buflen > MCLBYTES)
 1627                                 return (EINVAL);
 1628         }
 1629         m = m_get(M_WAIT, type);
 1630         if ((u_int)buflen > MLEN)
 1631                 MCLGET(m, M_WAIT);
 1632         m->m_len = buflen;
 1633         error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);
 1634         if (error)
 1635                 (void) m_free(m);
 1636         else {
 1637                 *mp = m;
 1638                 if (type == MT_SONAME) {
 1639                         sa = mtod(m, struct sockaddr *);
 1640 
 1641 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
 1642                         if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
 1643                                 sa->sa_family = sa->sa_len;
 1644 #endif
 1645                         sa->sa_len = buflen;
 1646                 }
 1647         }
 1648         return (error);
 1649 }
 1650 
 1651 int
 1652 getsockaddr(namp, uaddr, len)
 1653         struct sockaddr **namp;
 1654         caddr_t uaddr;
 1655         size_t len;
 1656 {
 1657         struct sockaddr *sa;
 1658         int error;
 1659 
 1660         if (len > SOCK_MAXADDRLEN)
 1661                 return (ENAMETOOLONG);
 1662         if (len < offsetof(struct sockaddr, sa_data[0]))
 1663                 return (EINVAL);
 1664         sa = malloc(len, M_SONAME, M_WAITOK);
 1665         error = copyin(uaddr, sa, len);
 1666         if (error) {
 1667                 free(sa, M_SONAME);
 1668         } else {
 1669 #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN
 1670                 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
 1671                         sa->sa_family = sa->sa_len;
 1672 #endif
 1673                 sa->sa_len = len;
 1674                 *namp = sa;
 1675         }
 1676         return (error);
 1677 }
 1678 
 1679 #include <sys/condvar.h>
 1680 
 1681 struct sendfile_sync {
 1682         struct mtx      mtx;
 1683         struct cv       cv;
 1684         unsigned        count;
 1685 };
 1686 
 1687 /*
 1688  * Detach mapped page and release resources back to the system.
 1689  */
 1690 void
 1691 sf_buf_mext(void *addr, void *args)
 1692 {
 1693         vm_page_t m;
 1694         struct sendfile_sync *sfs;
 1695 
 1696         m = sf_buf_page(args);
 1697         sf_buf_free(args);
 1698         vm_page_lock_queues();
 1699         vm_page_unwire(m, 0);
 1700         /*
 1701          * Check for the object going away on us. This can
 1702          * happen since we don't hold a reference to it.
 1703          * If so, we're responsible for freeing the page.
 1704          */
 1705         if (m->wire_count == 0 && m->object == NULL)
 1706                 vm_page_free(m);
 1707         vm_page_unlock_queues();
 1708         if (addr == NULL)
 1709                 return;
 1710         sfs = addr;
 1711         mtx_lock(&sfs->mtx);
 1712         KASSERT(sfs->count> 0, ("Sendfile sync botchup count == 0"));
 1713         if (--sfs->count == 0)
 1714                 cv_signal(&sfs->cv);
 1715         mtx_unlock(&sfs->mtx);
 1716 }
 1717 
 1718 /*
 1719  * sendfile(2)
 1720  *
 1721  * int sendfile(int fd, int s, off_t offset, size_t nbytes,
 1722  *       struct sf_hdtr *hdtr, off_t *sbytes, int flags)
 1723  *
 1724  * Send a file specified by 'fd' and starting at 'offset' to a socket
 1725  * specified by 's'. Send only 'nbytes' of the file or until EOF if nbytes ==
 1726  * 0.  Optionally add a header and/or trailer to the socket output.  If
 1727  * specified, write the total number of bytes sent into *sbytes.
 1728  */
 1729 int
 1730 sendfile(struct thread *td, struct sendfile_args *uap)
 1731 {
 1732 
 1733         return (do_sendfile(td, uap, 0));
 1734 }
 1735 
 1736 static int
 1737 do_sendfile(struct thread *td, struct sendfile_args *uap, int compat)
 1738 {
 1739         struct sf_hdtr hdtr;
 1740         struct uio *hdr_uio, *trl_uio;
 1741         int error;
 1742 
 1743         hdr_uio = trl_uio = NULL;
 1744 
 1745         if (uap->hdtr != NULL) {
 1746                 error = copyin(uap->hdtr, &hdtr, sizeof(hdtr));
 1747                 if (error)
 1748                         goto out;
 1749                 if (hdtr.headers != NULL) {
 1750                         error = copyinuio(hdtr.headers, hdtr.hdr_cnt, &hdr_uio);
 1751                         if (error)
 1752                                 goto out;
 1753                 }
 1754                 if (hdtr.trailers != NULL) {
 1755                         error = copyinuio(hdtr.trailers, hdtr.trl_cnt, &trl_uio);
 1756                         if (error)
 1757                                 goto out;
 1758 
 1759                 }
 1760         }
 1761 
 1762         error = kern_sendfile(td, uap, hdr_uio, trl_uio, compat);
 1763 out:
 1764         if (hdr_uio)
 1765                 free(hdr_uio, M_IOV);
 1766         if (trl_uio)
 1767                 free(trl_uio, M_IOV);
 1768         return (error);
 1769 }
 1770 
 1771 #ifdef COMPAT_FREEBSD4
 1772 int
 1773 freebsd4_sendfile(struct thread *td, struct freebsd4_sendfile_args *uap)
 1774 {
 1775         struct sendfile_args args;
 1776 
 1777         args.fd = uap->fd;
 1778         args.s = uap->s;
 1779         args.offset = uap->offset;
 1780         args.nbytes = uap->nbytes;
 1781         args.hdtr = uap->hdtr;
 1782         args.sbytes = uap->sbytes;
 1783         args.flags = uap->flags;
 1784 
 1785         return (do_sendfile(td, &args, 1));
 1786 }
 1787 #endif /* COMPAT_FREEBSD4 */
 1788 
 1789 int
 1790 kern_sendfile(struct thread *td, struct sendfile_args *uap,
 1791     struct uio *hdr_uio, struct uio *trl_uio, int compat)
 1792 {
 1793         struct file *sock_fp;
 1794         struct vnode *vp;
 1795         struct vm_object *obj = NULL;
 1796         struct socket *so = NULL;
 1797         struct mbuf *m = NULL;
 1798         struct sf_buf *sf;
 1799         struct vm_page *pg;
 1800         off_t off, xfsize, fsbytes = 0, sbytes = 0, rem = 0;
 1801         int error, hdrlen = 0, mnw = 0;
 1802         int vfslocked;
 1803         struct sendfile_sync *sfs = NULL;
 1804 
 1805         /*
 1806          * The file descriptor must be a regular file and have a
 1807          * backing VM object.
 1808          * File offset must be positive.  If it goes beyond EOF
 1809          * we send only the header/trailer and no payload data.
 1810          */
 1811         if ((error = fgetvp_read(td, uap->fd, &vp)) != 0)
 1812                 goto out;
 1813         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 1814         vn_lock(vp, LK_SHARED | LK_RETRY);
 1815         if (vp->v_type == VREG) {
 1816                 obj = vp->v_object;
 1817                 if (obj != NULL) {
 1818                         /*
 1819                          * Temporarily increase the backing VM
 1820                          * object's reference count so that a forced
 1821                          * reclamation of its vnode does not
 1822                          * immediately destroy it.
 1823                          */
 1824                         VM_OBJECT_LOCK(obj);
 1825                         if ((obj->flags & OBJ_DEAD) == 0) {
 1826                                 vm_object_reference_locked(obj);
 1827                                 VM_OBJECT_UNLOCK(obj);
 1828                         } else {
 1829                                 VM_OBJECT_UNLOCK(obj);
 1830                                 obj = NULL;
 1831                         }
 1832                 }
 1833         }
 1834         VOP_UNLOCK(vp, 0);
 1835         VFS_UNLOCK_GIANT(vfslocked);
 1836         if (obj == NULL) {
 1837                 error = EINVAL;
 1838                 goto out;
 1839         }
 1840         if (uap->offset < 0) {
 1841                 error = EINVAL;
 1842                 goto out;
 1843         }
 1844 
 1845         /*
 1846          * The socket must be a stream socket and connected.
 1847          * Remember if it a blocking or non-blocking socket.
 1848          */
 1849         if ((error = getsock(td->td_proc->p_fd, uap->s, &sock_fp,
 1850             NULL)) != 0)
 1851                 goto out;
 1852         so = sock_fp->f_data;
 1853         if (so->so_type != SOCK_STREAM) {
 1854                 error = EINVAL;
 1855                 goto out;
 1856         }
 1857         if ((so->so_state & SS_ISCONNECTED) == 0) {
 1858                 error = ENOTCONN;
 1859                 goto out;
 1860         }
 1861         /*
 1862          * Do not wait on memory allocations but return ENOMEM for
 1863          * caller to retry later.
 1864          * XXX: Experimental.
 1865          */
 1866         if (uap->flags & SF_MNOWAIT)
 1867                 mnw = 1;
 1868 
 1869         if (uap->flags & SF_SYNC) {
 1870                 sfs = malloc(sizeof *sfs, M_TEMP, M_WAITOK);
 1871                 memset(sfs, 0, sizeof *sfs);
 1872                 mtx_init(&sfs->mtx, "sendfile", MTX_DEF, 0);
 1873                 cv_init(&sfs->cv, "sendfile");
 1874         }
 1875 
 1876 #ifdef MAC
 1877         error = mac_socket_check_send(td->td_ucred, so);
 1878         if (error)
 1879                 goto out;
 1880 #endif
 1881 
 1882         /* If headers are specified copy them into mbufs. */
 1883         if (hdr_uio != NULL) {
 1884                 hdr_uio->uio_td = td;
 1885                 hdr_uio->uio_rw = UIO_WRITE;
 1886                 if (hdr_uio->uio_resid > 0) {
 1887                         /*
 1888                          * In FBSD < 5.0 the nbytes to send also included
 1889                          * the header.  If compat is specified subtract the
 1890                          * header size from nbytes.
 1891                          */
 1892                         if (compat) {
 1893                                 if (uap->nbytes > hdr_uio->uio_resid)
 1894                                         uap->nbytes -= hdr_uio->uio_resid;
 1895                                 else
 1896                                         uap->nbytes = 0;
 1897                         }
 1898                         m = m_uiotombuf(hdr_uio, (mnw ? M_NOWAIT : M_WAITOK),
 1899                             0, 0, 0);
 1900                         if (m == NULL) {
 1901                                 error = mnw ? EAGAIN : ENOBUFS;
 1902                                 goto out;
 1903                         }
 1904                         hdrlen = m_length(m, NULL);
 1905                 }
 1906         }
 1907 
 1908         /*
 1909          * Protect against multiple writers to the socket.
 1910          *
 1911          * XXXRW: Historically this has assumed non-interruptibility, so now
 1912          * we implement that, but possibly shouldn't.
 1913          */
 1914         (void)sblock(&so->so_snd, SBL_WAIT | SBL_NOINTR);
 1915 
 1916         /*
 1917          * Loop through the pages of the file, starting with the requested
 1918          * offset. Get a file page (do I/O if necessary), map the file page
 1919          * into an sf_buf, attach an mbuf header to the sf_buf, and queue
 1920          * it on the socket.
 1921          * This is done in two loops.  The inner loop turns as many pages
 1922          * as it can, up to available socket buffer space, without blocking
 1923          * into mbufs to have it bulk delivered into the socket send buffer.
 1924          * The outer loop checks the state and available space of the socket
 1925          * and takes care of the overall progress.
 1926          */
 1927         for (off = uap->offset, rem = uap->nbytes; ; ) {
 1928                 int loopbytes = 0;
 1929                 int space = 0;
 1930                 int done = 0;
 1931 
 1932                 /*
 1933                  * Check the socket state for ongoing connection,
 1934                  * no errors and space in socket buffer.
 1935                  * If space is low allow for the remainder of the
 1936                  * file to be processed if it fits the socket buffer.
 1937                  * Otherwise block in waiting for sufficient space
 1938                  * to proceed, or if the socket is nonblocking, return
 1939                  * to userland with EAGAIN while reporting how far
 1940                  * we've come.
 1941                  * We wait until the socket buffer has significant free
 1942                  * space to do bulk sends.  This makes good use of file
 1943                  * system read ahead and allows packet segmentation
 1944                  * offloading hardware to take over lots of work.  If
 1945                  * we were not careful here we would send off only one
 1946                  * sfbuf at a time.
 1947                  */
 1948                 SOCKBUF_LOCK(&so->so_snd);
 1949                 if (so->so_snd.sb_lowat < so->so_snd.sb_hiwat / 2)
 1950                         so->so_snd.sb_lowat = so->so_snd.sb_hiwat / 2;
 1951 retry_space:
 1952                 if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
 1953                         error = EPIPE;
 1954                         SOCKBUF_UNLOCK(&so->so_snd);
 1955                         goto done;
 1956                 } else if (so->so_error) {
 1957                         error = so->so_error;
 1958                         so->so_error = 0;
 1959                         SOCKBUF_UNLOCK(&so->so_snd);
 1960                         goto done;
 1961                 }
 1962                 space = sbspace(&so->so_snd);
 1963                 if (space < rem &&
 1964                     (space <= 0 ||
 1965                      space < so->so_snd.sb_lowat)) {
 1966                         if (so->so_state & SS_NBIO) {
 1967                                 SOCKBUF_UNLOCK(&so->so_snd);
 1968                                 error = EAGAIN;
 1969                                 goto done;
 1970                         }
 1971                         /*
 1972                          * sbwait drops the lock while sleeping.
 1973                          * When we loop back to retry_space the
 1974                          * state may have changed and we retest
 1975                          * for it.
 1976                          */
 1977                         error = sbwait(&so->so_snd);
 1978                         /*
 1979                          * An error from sbwait usually indicates that we've
 1980                          * been interrupted by a signal. If we've sent anything
 1981                          * then return bytes sent, otherwise return the error.
 1982                          */
 1983                         if (error) {
 1984                                 SOCKBUF_UNLOCK(&so->so_snd);
 1985                                 goto done;
 1986                         }
 1987                         goto retry_space;
 1988                 }
 1989                 SOCKBUF_UNLOCK(&so->so_snd);
 1990 
 1991                 /*
 1992                  * Reduce space in the socket buffer by the size of
 1993                  * the header mbuf chain.
 1994                  * hdrlen is set to 0 after the first loop.
 1995                  */
 1996                 space -= hdrlen;
 1997 
 1998                 /*
 1999                  * Loop and construct maximum sized mbuf chain to be bulk
 2000                  * dumped into socket buffer.
 2001                  */
 2002                 while(space > loopbytes) {
 2003                         vm_pindex_t pindex;
 2004                         vm_offset_t pgoff;
 2005                         struct mbuf *m0;
 2006 
 2007                         VM_OBJECT_LOCK(obj);
 2008                         /*
 2009                          * Calculate the amount to transfer.
 2010                          * Not to exceed a page, the EOF,
 2011                          * or the passed in nbytes.
 2012                          */
 2013                         pgoff = (vm_offset_t)(off & PAGE_MASK);
 2014                         xfsize = omin(PAGE_SIZE - pgoff,
 2015                             obj->un_pager.vnp.vnp_size - uap->offset -
 2016                             fsbytes - loopbytes);
 2017                         if (uap->nbytes)
 2018                                 rem = (uap->nbytes - fsbytes - loopbytes);
 2019                         else
 2020                                 rem = obj->un_pager.vnp.vnp_size -
 2021                                     uap->offset - fsbytes - loopbytes;
 2022                         xfsize = omin(rem, xfsize);
 2023                         if (xfsize <= 0) {
 2024                                 VM_OBJECT_UNLOCK(obj);
 2025                                 done = 1;               /* all data sent */
 2026                                 break;
 2027                         }
 2028                         /*
 2029                          * Don't overflow the send buffer.
 2030                          * Stop here and send out what we've
 2031                          * already got.
 2032                          */
 2033                         if (space < loopbytes + xfsize) {
 2034                                 VM_OBJECT_UNLOCK(obj);
 2035                                 break;
 2036                         }
 2037 
 2038                         /*
 2039                          * Attempt to look up the page.  Allocate
 2040                          * if not found or wait and loop if busy.
 2041                          */
 2042                         pindex = OFF_TO_IDX(off);
 2043                         pg = vm_page_grab(obj, pindex, VM_ALLOC_NOBUSY |
 2044                             VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_RETRY);
 2045 
 2046                         /*
 2047                          * Check if page is valid for what we need,
 2048                          * otherwise initiate I/O.
 2049                          * If we already turned some pages into mbufs,
 2050                          * send them off before we come here again and
 2051                          * block.
 2052                          */
 2053                         if (pg->valid && vm_page_is_valid(pg, pgoff, xfsize))
 2054                                 VM_OBJECT_UNLOCK(obj);
 2055                         else if (m != NULL)
 2056                                 error = EAGAIN; /* send what we already got */
 2057                         else if (uap->flags & SF_NODISKIO)
 2058                                 error = EBUSY;
 2059                         else {
 2060                                 int bsize, resid;
 2061 
 2062                                 /*
 2063                                  * Ensure that our page is still around
 2064                                  * when the I/O completes.
 2065                                  */
 2066                                 vm_page_io_start(pg);
 2067                                 VM_OBJECT_UNLOCK(obj);
 2068 
 2069                                 /*
 2070                                  * Get the page from backing store.
 2071                                  */
 2072                                 bsize = vp->v_mount->mnt_stat.f_iosize;
 2073                                 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 2074                                 vn_lock(vp, LK_SHARED | LK_RETRY);
 2075 
 2076                                 /*
 2077                                  * XXXMAC: Because we don't have fp->f_cred
 2078                                  * here, we pass in NOCRED.  This is probably
 2079                                  * wrong, but is consistent with our original
 2080                                  * implementation.
 2081                                  */
 2082                                 error = vn_rdwr(UIO_READ, vp, NULL, MAXBSIZE,
 2083                                     trunc_page(off), UIO_NOCOPY, IO_NODELOCKED |
 2084                                     IO_VMIO | ((MAXBSIZE / bsize) << IO_SEQSHIFT),
 2085                                     td->td_ucred, NOCRED, &resid, td);
 2086                                 VOP_UNLOCK(vp, 0);
 2087                                 VFS_UNLOCK_GIANT(vfslocked);
 2088                                 VM_OBJECT_LOCK(obj);
 2089                                 vm_page_io_finish(pg);
 2090                                 if (!error)
 2091                                         VM_OBJECT_UNLOCK(obj);
 2092                                 mbstat.sf_iocnt++;
 2093                         }
 2094                         if (error) {
 2095                                 vm_page_lock_queues();
 2096                                 vm_page_unwire(pg, 0);
 2097                                 /*
 2098                                  * See if anyone else might know about
 2099                                  * this page.  If not and it is not valid,
 2100                                  * then free it.
 2101                                  */
 2102                                 if (pg->wire_count == 0 && pg->valid == 0 &&
 2103                                     pg->busy == 0 && !(pg->oflags & VPO_BUSY) &&
 2104                                     pg->hold_count == 0) {
 2105                                         vm_page_free(pg);
 2106                                 }
 2107                                 vm_page_unlock_queues();
 2108                                 VM_OBJECT_UNLOCK(obj);
 2109                                 if (error == EAGAIN)
 2110                                         error = 0;      /* not a real error */
 2111                                 break;
 2112                         }
 2113 
 2114                         /*
 2115                          * Get a sendfile buf.  We usually wait as long
 2116                          * as necessary, but this wait can be interrupted.
 2117                          */
 2118                         if ((sf = sf_buf_alloc(pg,
 2119                             (mnw ? SFB_NOWAIT : SFB_CATCH))) == NULL) {
 2120                                 mbstat.sf_allocfail++;
 2121                                 vm_page_lock_queues();
 2122                                 vm_page_unwire(pg, 0);
 2123                                 /*
 2124                                  * XXX: Not same check as above!?
 2125                                  */
 2126                                 if (pg->wire_count == 0 && pg->object == NULL)
 2127                                         vm_page_free(pg);
 2128                                 vm_page_unlock_queues();
 2129                                 error = (mnw ? EAGAIN : EINTR);
 2130                                 break;
 2131                         }
 2132 
 2133                         /*
 2134                          * Get an mbuf and set it up as having
 2135                          * external storage.
 2136                          */
 2137                         m0 = m_get((mnw ? M_NOWAIT : M_WAITOK), MT_DATA);
 2138                         if (m0 == NULL) {
 2139                                 error = (mnw ? EAGAIN : ENOBUFS);
 2140                                 sf_buf_mext((void *)sf_buf_kva(sf), sf);
 2141                                 break;
 2142                         }
 2143                         MEXTADD(m0, sf_buf_kva(sf), PAGE_SIZE, sf_buf_mext,
 2144                             sfs, sf, M_RDONLY, EXT_SFBUF);
 2145                         m0->m_data = (char *)sf_buf_kva(sf) + pgoff;
 2146                         m0->m_len = xfsize;
 2147 
 2148                         /* Append to mbuf chain. */
 2149                         if (m != NULL)
 2150                                 m_cat(m, m0);
 2151                         else
 2152                                 m = m0;
 2153 
 2154                         /* Keep track of bits processed. */
 2155                         loopbytes += xfsize;
 2156                         off += xfsize;
 2157 
 2158                         if (sfs != NULL) {
 2159                                 mtx_lock(&sfs->mtx);
 2160                                 sfs->count++;
 2161                                 mtx_unlock(&sfs->mtx);
 2162                         }
 2163                 }
 2164 
 2165                 /* Add the buffer chain to the socket buffer. */
 2166                 if (m != NULL) {
 2167                         int mlen, err;
 2168 
 2169                         mlen = m_length(m, NULL);
 2170                         SOCKBUF_LOCK(&so->so_snd);
 2171                         if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
 2172                                 error = EPIPE;
 2173                                 SOCKBUF_UNLOCK(&so->so_snd);
 2174                                 goto done;
 2175                         }
 2176                         SOCKBUF_UNLOCK(&so->so_snd);
 2177                         CURVNET_SET(so->so_vnet);
 2178                         /* Avoid error aliasing. */
 2179                         err = (*so->so_proto->pr_usrreqs->pru_send)
 2180                                     (so, 0, m, NULL, NULL, td);
 2181                         CURVNET_RESTORE();
 2182                         if (err == 0) {
 2183                                 /*
 2184                                  * We need two counters to get the
 2185                                  * file offset and nbytes to send
 2186                                  * right:
 2187                                  * - sbytes contains the total amount
 2188                                  *   of bytes sent, including headers.
 2189                                  * - fsbytes contains the total amount
 2190                                  *   of bytes sent from the file.
 2191                                  */
 2192                                 sbytes += mlen;
 2193                                 fsbytes += mlen;
 2194                                 if (hdrlen) {
 2195                                         fsbytes -= hdrlen;
 2196                                         hdrlen = 0;
 2197                                 }
 2198                         } else if (error == 0)
 2199                                 error = err;
 2200                         m = NULL;       /* pru_send always consumes */
 2201                 }
 2202 
 2203                 /* Quit outer loop on error or when we're done. */
 2204                 if (done) 
 2205                         break;
 2206                 if (error)
 2207                         goto done;
 2208         }
 2209 
 2210         /*
 2211          * Send trailers. Wimp out and use writev(2).
 2212          */
 2213         if (trl_uio != NULL) {
 2214                 sbunlock(&so->so_snd);
 2215                 error = kern_writev(td, uap->s, trl_uio);
 2216                 if (error == 0)
 2217                         sbytes += td->td_retval[0];
 2218                 goto out;
 2219         }
 2220 
 2221 done:
 2222         sbunlock(&so->so_snd);
 2223 out:
 2224         /*
 2225          * If there was no error we have to clear td->td_retval[0]
 2226          * because it may have been set by writev.
 2227          */
 2228         if (error == 0) {
 2229                 td->td_retval[0] = 0;
 2230         }
 2231         if (uap->sbytes != NULL) {
 2232                 copyout(&sbytes, uap->sbytes, sizeof(off_t));
 2233         }
 2234         if (obj != NULL)
 2235                 vm_object_deallocate(obj);
 2236         if (vp != NULL) {
 2237                 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 2238                 vrele(vp);
 2239                 VFS_UNLOCK_GIANT(vfslocked);
 2240         }
 2241         if (so)
 2242                 fdrop(sock_fp, td);
 2243         if (m)
 2244                 m_freem(m);
 2245 
 2246         if (sfs != NULL) {
 2247                 mtx_lock(&sfs->mtx);
 2248                 if (sfs->count != 0)
 2249                         cv_wait(&sfs->cv, &sfs->mtx);
 2250                 KASSERT(sfs->count == 0, ("sendfile sync still busy"));
 2251                 cv_destroy(&sfs->cv);
 2252                 mtx_destroy(&sfs->mtx);
 2253                 free(sfs, M_TEMP);
 2254         }
 2255 
 2256         if (error == ERESTART)
 2257                 error = EINTR;
 2258 
 2259         return (error);
 2260 }
 2261 
 2262 /*
 2263  * SCTP syscalls.
 2264  * Functionality only compiled in if SCTP is defined in the kernel Makefile,
 2265  * otherwise all return EOPNOTSUPP.
 2266  * XXX: We should make this loadable one day.
 2267  */
 2268 int
 2269 sctp_peeloff(td, uap)
 2270         struct thread *td;
 2271         struct sctp_peeloff_args /* {
 2272                 int     sd;
 2273                 caddr_t name;
 2274         } */ *uap;
 2275 {
 2276 #if (defined(INET) || defined(INET6)) && defined(SCTP)
 2277         struct filedesc *fdp;
 2278         struct file *nfp = NULL;
 2279         int error;
 2280         struct socket *head, *so;
 2281         int fd;
 2282         u_int fflag;
 2283 
 2284         fdp = td->td_proc->p_fd;
 2285         error = fgetsock(td, uap->sd, &head, &fflag);
 2286         if (error)
 2287                 goto done2;
 2288         error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name);
 2289         if (error)
 2290                 goto done2;
 2291         /*
 2292          * At this point we know we do have a assoc to pull
 2293          * we proceed to get the fd setup. This may block
 2294          * but that is ok.
 2295          */
 2296 
 2297         error = falloc(td, &nfp, &fd);
 2298         if (error)
 2299                 goto done;
 2300         td->td_retval[0] = fd;
 2301 
 2302         so = sonewconn(head, SS_ISCONNECTED);
 2303         if (so == NULL) 
 2304                 goto noconnection;
 2305         /*
 2306          * Before changing the flags on the socket, we have to bump the
 2307          * reference count.  Otherwise, if the protocol calls sofree(),
 2308          * the socket will be released due to a zero refcount.
 2309          */
 2310         SOCK_LOCK(so);
 2311         soref(so);                      /* file descriptor reference */
 2312         SOCK_UNLOCK(so);
 2313 
 2314         ACCEPT_LOCK();
 2315 
 2316         TAILQ_REMOVE(&head->so_comp, so, so_list);
 2317         head->so_qlen--;
 2318         so->so_state |= (head->so_state & SS_NBIO);
 2319         so->so_state &= ~SS_NOFDREF;
 2320         so->so_qstate &= ~SQ_COMP;
 2321         so->so_head = NULL;
 2322         ACCEPT_UNLOCK();
 2323         finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
 2324         error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name);
 2325         if (error)
 2326                 goto noconnection;
 2327         if (head->so_sigio != NULL)
 2328                 fsetown(fgetown(&head->so_sigio), &so->so_sigio);
 2329 
 2330 noconnection:
 2331         /*
 2332          * close the new descriptor, assuming someone hasn't ripped it
 2333          * out from under us.
 2334          */
 2335         if (error)
 2336                 fdclose(fdp, nfp, fd, td);
 2337 
 2338         /*
 2339          * Release explicitly held references before returning.
 2340          */
 2341 done:
 2342         if (nfp != NULL)
 2343                 fdrop(nfp, td);
 2344         fputsock(head);
 2345 done2:
 2346         return (error);
 2347 #else  /* SCTP */
 2348         return (EOPNOTSUPP);
 2349 #endif /* SCTP */
 2350 }
 2351 
 2352 int
 2353 sctp_generic_sendmsg (td, uap)
 2354         struct thread *td;
 2355         struct sctp_generic_sendmsg_args /* {
 2356                 int sd, 
 2357                 caddr_t msg, 
 2358                 int mlen, 
 2359                 caddr_t to, 
 2360                 __socklen_t tolen, 
 2361                 struct sctp_sndrcvinfo *sinfo, 
 2362                 int flags
 2363         } */ *uap;
 2364 {
 2365 #if (defined(INET) || defined(INET6)) && defined(SCTP)
 2366         struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL;
 2367         struct socket *so;
 2368         struct file *fp = NULL;
 2369         int use_rcvinfo = 1;
 2370         int error = 0, len;
 2371         struct sockaddr *to = NULL;
 2372 #ifdef KTRACE
 2373         struct uio *ktruio = NULL;
 2374 #endif
 2375         struct uio auio;
 2376         struct iovec iov[1];
 2377 
 2378         if (uap->sinfo) {
 2379                 error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
 2380                 if (error)
 2381                         return (error);
 2382                 u_sinfo = &sinfo;
 2383         }
 2384         if (uap->tolen) {
 2385                 error = getsockaddr(&to, uap->to, uap->tolen);
 2386                 if (error) {
 2387                         to = NULL;
 2388                         goto sctp_bad2;
 2389                 }
 2390         }
 2391 
 2392         error = getsock(td->td_proc->p_fd, uap->sd, &fp, NULL);
 2393         if (error)
 2394                 goto sctp_bad;
 2395 #ifdef KTRACE
 2396         if (KTRPOINT(td, KTR_STRUCT))
 2397                 ktrsockaddr(to);
 2398 #endif
 2399 
 2400         iov[0].iov_base = uap->msg;
 2401         iov[0].iov_len = uap->mlen;
 2402 
 2403         so = (struct socket *)fp->f_data;
 2404 #ifdef MAC
 2405         error = mac_socket_check_send(td->td_ucred, so);
 2406         if (error)
 2407                 goto sctp_bad;
 2408 #endif /* MAC */
 2409 
 2410         auio.uio_iov =  iov;
 2411         auio.uio_iovcnt = 1;
 2412         auio.uio_segflg = UIO_USERSPACE;
 2413         auio.uio_rw = UIO_WRITE;
 2414         auio.uio_td = td;
 2415         auio.uio_offset = 0;                    /* XXX */
 2416         auio.uio_resid = 0;
 2417         len = auio.uio_resid = uap->mlen;
 2418         error = sctp_lower_sosend(so, to, &auio,
 2419                     (struct mbuf *)NULL, (struct mbuf *)NULL,
 2420                     uap->flags, use_rcvinfo, u_sinfo, td);
 2421         if (error) {
 2422                 if (auio.uio_resid != len && (error == ERESTART ||
 2423                     error == EINTR || error == EWOULDBLOCK))
 2424                         error = 0;
 2425                 /* Generation of SIGPIPE can be controlled per socket. */
 2426                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
 2427                     !(uap->flags & MSG_NOSIGNAL)) {
 2428                         PROC_LOCK(td->td_proc);
 2429                         psignal(td->td_proc, SIGPIPE);
 2430                         PROC_UNLOCK(td->td_proc);
 2431                 }
 2432         }
 2433         if (error == 0)
 2434                 td->td_retval[0] = len - auio.uio_resid;
 2435 #ifdef KTRACE
 2436         if (ktruio != NULL) {
 2437                 ktruio->uio_resid = td->td_retval[0];
 2438                 ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
 2439         }
 2440 #endif /* KTRACE */
 2441 sctp_bad:
 2442         if (fp)
 2443                 fdrop(fp, td);
 2444 sctp_bad2:
 2445         if (to)
 2446                 free(to, M_SONAME);
 2447         return (error);
 2448 #else  /* SCTP */
 2449         return (EOPNOTSUPP);
 2450 #endif /* SCTP */
 2451 }
 2452 
 2453 int
 2454 sctp_generic_sendmsg_iov(td, uap)
 2455         struct thread *td;
 2456         struct sctp_generic_sendmsg_iov_args /* {
 2457                 int sd, 
 2458                 struct iovec *iov, 
 2459                 int iovlen, 
 2460                 caddr_t to, 
 2461                 __socklen_t tolen, 
 2462                 struct sctp_sndrcvinfo *sinfo, 
 2463                 int flags
 2464         } */ *uap;
 2465 {
 2466 #if (defined(INET) || defined(INET6)) && defined(SCTP)
 2467         struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL;
 2468         struct socket *so;
 2469         struct file *fp = NULL;
 2470         int use_rcvinfo = 1;
 2471         int error=0, len, i;
 2472         struct sockaddr *to = NULL;
 2473 #ifdef KTRACE
 2474         struct uio *ktruio = NULL;
 2475 #endif
 2476         struct uio auio;
 2477         struct iovec *iov, *tiov;
 2478 
 2479         if (uap->sinfo) {
 2480                 error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
 2481                 if (error)
 2482                         return (error);
 2483                 u_sinfo = &sinfo;
 2484         }
 2485         if (uap->tolen) {
 2486                 error = getsockaddr(&to, uap->to, uap->tolen);
 2487                 if (error) {
 2488                         to = NULL;
 2489                         goto sctp_bad2;
 2490                 }
 2491         }
 2492 
 2493         error = getsock(td->td_proc->p_fd, uap->sd, &fp, NULL);
 2494         if (error)
 2495                 goto sctp_bad1;
 2496 
 2497         error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
 2498         if (error)
 2499                 goto sctp_bad1;
 2500 #ifdef KTRACE
 2501         if (KTRPOINT(td, KTR_STRUCT))
 2502                 ktrsockaddr(to);
 2503 #endif
 2504 
 2505         so = (struct socket *)fp->f_data;
 2506 #ifdef MAC
 2507         error = mac_socket_check_send(td->td_ucred, so);
 2508         if (error)
 2509                 goto sctp_bad;
 2510 #endif /* MAC */
 2511 
 2512         auio.uio_iov =  iov;
 2513         auio.uio_iovcnt = uap->iovlen;
 2514         auio.uio_segflg = UIO_USERSPACE;
 2515         auio.uio_rw = UIO_WRITE;
 2516         auio.uio_td = td;
 2517         auio.uio_offset = 0;                    /* XXX */
 2518         auio.uio_resid = 0;
 2519         tiov = iov;
 2520         for (i = 0; i <uap->iovlen; i++, tiov++) {
 2521                 if ((auio.uio_resid += tiov->iov_len) < 0) {
 2522                         error = EINVAL;
 2523                         goto sctp_bad;
 2524                 }
 2525         }
 2526         len = auio.uio_resid;
 2527         error = sctp_lower_sosend(so, to, &auio,
 2528                     (struct mbuf *)NULL, (struct mbuf *)NULL,
 2529                     uap->flags, use_rcvinfo, u_sinfo, td);
 2530         if (error) {
 2531                 if (auio.uio_resid != len && (error == ERESTART ||
 2532                     error == EINTR || error == EWOULDBLOCK))
 2533                         error = 0;
 2534                 /* Generation of SIGPIPE can be controlled per socket */
 2535                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
 2536                     !(uap->flags & MSG_NOSIGNAL)) {
 2537                         PROC_LOCK(td->td_proc);
 2538                         psignal(td->td_proc, SIGPIPE);
 2539                         PROC_UNLOCK(td->td_proc);
 2540                 }
 2541         }
 2542         if (error == 0)
 2543                 td->td_retval[0] = len - auio.uio_resid;
 2544 #ifdef KTRACE
 2545         if (ktruio != NULL) {
 2546                 ktruio->uio_resid = td->td_retval[0];
 2547                 ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
 2548         }
 2549 #endif /* KTRACE */
 2550 sctp_bad:
 2551         free(iov, M_IOV);
 2552 sctp_bad1:
 2553         if (fp)
 2554                 fdrop(fp, td);
 2555 sctp_bad2:
 2556         if (to)
 2557                 free(to, M_SONAME);
 2558         return (error);
 2559 #else  /* SCTP */
 2560         return (EOPNOTSUPP);
 2561 #endif /* SCTP */
 2562 }
 2563 
 2564 int
 2565 sctp_generic_recvmsg(td, uap)
 2566         struct thread *td;
 2567         struct sctp_generic_recvmsg_args /* {
 2568                 int sd, 
 2569                 struct iovec *iov, 
 2570                 int iovlen,
 2571                 struct sockaddr *from, 
 2572                 __socklen_t *fromlenaddr,
 2573                 struct sctp_sndrcvinfo *sinfo, 
 2574                 int *msg_flags
 2575         } */ *uap;
 2576 {
 2577 #if (defined(INET) || defined(INET6)) && defined(SCTP)
 2578         u_int8_t sockbufstore[256];
 2579         struct uio auio;
 2580         struct iovec *iov, *tiov;
 2581         struct sctp_sndrcvinfo sinfo;
 2582         struct socket *so;
 2583         struct file *fp = NULL;
 2584         struct sockaddr *fromsa;
 2585         int fromlen;
 2586         int len, i, msg_flags;
 2587         int error = 0;
 2588 #ifdef KTRACE
 2589         struct uio *ktruio = NULL;
 2590 #endif
 2591         error = getsock(td->td_proc->p_fd, uap->sd, &fp, NULL);
 2592         if (error) {
 2593                 return (error);
 2594         }
 2595         error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
 2596         if (error) {
 2597                 goto out1;
 2598         }
 2599 
 2600         so = fp->f_data;
 2601 #ifdef MAC
 2602         error = mac_socket_check_receive(td->td_ucred, so);
 2603         if (error) {
 2604                 goto out;
 2605                 return (error);
 2606         }
 2607 #endif /* MAC */
 2608 
 2609         if (uap->fromlenaddr) {
 2610                 error = copyin(uap->fromlenaddr,
 2611                     &fromlen, sizeof (fromlen));
 2612                 if (error) {
 2613                         goto out;
 2614                 }
 2615         } else {
 2616                 fromlen = 0;
 2617         }
 2618         if(uap->msg_flags) {
 2619                 error = copyin(uap->msg_flags, &msg_flags, sizeof (int));
 2620                 if (error) {
 2621                         goto out;
 2622                 }
 2623         } else {
 2624                 msg_flags = 0;
 2625         }
 2626         auio.uio_iov = iov;
 2627         auio.uio_iovcnt = uap->iovlen;
 2628         auio.uio_segflg = UIO_USERSPACE;
 2629         auio.uio_rw = UIO_READ;
 2630         auio.uio_td = td;
 2631         auio.uio_offset = 0;                    /* XXX */
 2632         auio.uio_resid = 0;
 2633         tiov = iov;
 2634         for (i = 0; i <uap->iovlen; i++, tiov++) {
 2635                 if ((auio.uio_resid += tiov->iov_len) < 0) {
 2636                         error = EINVAL;
 2637                         goto out;
 2638                 }
 2639         }
 2640         len = auio.uio_resid;
 2641         fromsa = (struct sockaddr *)sockbufstore;
 2642 
 2643 #ifdef KTRACE
 2644         if (KTRPOINT(td, KTR_GENIO))
 2645                 ktruio = cloneuio(&auio);
 2646 #endif /* KTRACE */
 2647         error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
 2648                     fromsa, fromlen, &msg_flags,
 2649                     (struct sctp_sndrcvinfo *)&sinfo, 1);
 2650         if (error) {
 2651                 if (auio.uio_resid != (int)len && (error == ERESTART ||
 2652                     error == EINTR || error == EWOULDBLOCK))
 2653                         error = 0;
 2654         } else {
 2655                 if (uap->sinfo)
 2656                         error = copyout(&sinfo, uap->sinfo, sizeof (sinfo));
 2657         }
 2658 #ifdef KTRACE
 2659         if (ktruio != NULL) {
 2660                 ktruio->uio_resid = (int)len - auio.uio_resid;
 2661                 ktrgenio(uap->sd, UIO_READ, ktruio, error);
 2662         }
 2663 #endif /* KTRACE */
 2664         if (error)
 2665                 goto out;
 2666         td->td_retval[0] = (int)len - auio.uio_resid;
 2667 
 2668         if (fromlen && uap->from) {
 2669                 len = fromlen;
 2670                 if (len <= 0 || fromsa == 0)
 2671                         len = 0;
 2672                 else {
 2673                         len = MIN(len, fromsa->sa_len);
 2674                         error = copyout(fromsa, uap->from, (unsigned)len);
 2675                         if (error)
 2676                                 goto out;
 2677                 }
 2678                 error = copyout(&len, uap->fromlenaddr, sizeof (socklen_t));
 2679                 if (error) {
 2680                         goto out;
 2681                 }
 2682         }
 2683 #ifdef KTRACE
 2684         if (KTRPOINT(td, KTR_STRUCT))
 2685                 ktrsockaddr(fromsa);
 2686 #endif
 2687         if (uap->msg_flags) {
 2688                 error = copyout(&msg_flags, uap->msg_flags, sizeof (int));
 2689                 if (error) {
 2690                         goto out;
 2691                 }
 2692         }
 2693 out:
 2694         free(iov, M_IOV);
 2695 out1:
 2696         if (fp) 
 2697                 fdrop(fp, td);
 2698 
 2699         return (error);
 2700 #else  /* SCTP */
 2701         return (EOPNOTSUPP);
 2702 #endif /* SCTP */
 2703 }

Cache object: 467455ffd395a76be18e801f2a2275b6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.