The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ 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  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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


[ 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.