[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]

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

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD70  -  FREEBSD6  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  TRUSTEDBSD-SEDARWIN  -  TRUSTEDBSD-SEDARWIN7 
Ident_Mode: -  plain  -  excerpts  -  bigexcerpts 

  1 /*-
  2  * Copyright (c) 1982, 1986, 1989, 1990, 1993
  3  *      The Regents of the University of California.  All rights reserved.
  4  *
  5  * sendfile(2) and related extensions:
  6  * Copyright (c) 1998, David Greenman. All rights reserved.
  7  *
  8  * Redistribution and use in source and binary forms, with or without
  9  * modification, are permitted provided that the following conditions
 10  * are met:
 11  * 1. Redistributions of source code must retain the above copyright
 12  *    notice, this list of conditions and the following disclaimer.
 13  * 2. Redistributions in binary form must reproduce the above copyright
 14  *    notice, this list of conditions and the following disclaimer in the
 15  *    documentation and/or other materials provided with the distribution.
 16  * 4. Neither the name of the University nor the names of its contributors
 17  *    may be used to endorse or promote products derived from this software
 18  *    without specific prior written permission.
 19  *
 20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 30  * SUCH DAMAGE.
 31  *
 32  *      @(#)uipc_syscalls.c     8.4 (Berkeley) 2/21/94
 33  */
 34 
 35 #include <sys/cdefs.h>
 36 __FBSDID("$FreeBSD: src/sys/kern/uipc_syscalls.c,v 1.272 2008/05/22 07:18:54 rwatson Exp $");
 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_socket_check_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                 finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops);
184                 td->td_retval[0] = fd;
185         }
186         fdrop(fp, td);
187         return (error);
188 }
189 
190 /* ARGSUSED */
191 int
192 bind(td, uap)
193         struct thread *td;
194         struct bind_args /* {
195                 int     s;
196                 caddr_t name;
197                 int     namelen;
198         } */ *uap;
199 {
200         struct sockaddr *sa;
201         int error;
202 
203         if ((error = getsockaddr(&sa, uap->name, uap->namelen)) != 0)
204                 return (error);
205 
206         error = kern_bind(td, uap->s, sa);
207         free(sa, M_SONAME);
208         return (error);
209 }
210 
211 int
212 kern_bind(td, fd, sa)
213         struct thread *td;
214         int fd;
215         struct sockaddr *sa;
216 {
217         struct socket *so;
218         struct file *fp;
219         int error;
220 
221         error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
222         if (error)
223                 return (error);
224         so = fp->f_data;
225 #ifdef KTRACE
226         if (KTRPOINT(td, KTR_STRUCT))
227                 ktrsockaddr(sa);
228 #endif
229 #ifdef MAC
230         SOCK_LOCK(so);
231         error = mac_socket_check_bind(td->td_ucred, so, sa);
232         SOCK_UNLOCK(so);
233         if (error)
234                 goto done;
235 #endif
236         error = sobind(so, sa, td);
237 #ifdef MAC
238 done:
239 #endif
240         fdrop(fp, td);
241         return (error);
242 }
243 
244 /* ARGSUSED */
245 int
246 listen(td, uap)
247         struct thread *td;
248         struct listen_args /* {
249                 int     s;
250                 int     backlog;
251         } */ *uap;
252 {
253         struct socket *so;
254         struct file *fp;
255         int error;
256 
257         error = getsock(td->td_proc->p_fd, uap->s, &fp, NULL);
258         if (error == 0) {
259                 so = fp->f_data;
260 #ifdef MAC
261                 SOCK_LOCK(so);
262                 error = mac_socket_check_listen(td->td_ucred, so);
263                 SOCK_UNLOCK(so);
264                 if (error)
265                         goto done;
266 #endif
267                 error = solisten(so, uap->backlog, td);
268 #ifdef MAC
269 done:
270 #endif
271                 fdrop(fp, td);
272         }
273         return(error);
274 }
275 
276 /*
277  * accept1()
278  */
279 static int
280 accept1(td, uap, compat)
281         struct thread *td;
282         struct accept_args /* {
283                 int     s;
284                 struct sockaddr * __restrict name;
285                 socklen_t       * __restrict anamelen;
286         } */ *uap;
287         int compat;
288 {
289         struct sockaddr *name;
290         socklen_t namelen;
291         struct file *fp;
292         int error;
293 
294         if (uap->name == NULL)
295                 return (kern_accept(td, uap->s, NULL, NULL, NULL));
296 
297         error = copyin(uap->anamelen, &namelen, sizeof (namelen));
298         if (error)
299                 return (error);
300 
301         error = kern_accept(td, uap->s, &name, &namelen, &fp);
302 
303         /*
304          * return a namelen of zero for older code which might
305          * ignore the return value from accept.
306          */
307         if (error) {
308                 (void) copyout(&namelen,
309                     uap->anamelen, sizeof(*uap->anamelen));
310                 return (error);
311         }
312 
313         if (error == 0 && name != NULL) {
314 #ifdef COMPAT_OLDSOCK
315                 if (compat)
316                         ((struct osockaddr *)name)->sa_family =
317                             name->sa_family;
318 #endif
319                 error = copyout(name, uap->name, namelen);
320         }
321         if (error == 0)
322                 error = copyout(&namelen, uap->anamelen,
323                     sizeof(namelen));
324         if (error)
325                 fdclose(td->td_proc->p_fd, fp, td->td_retval[0], td);
326         fdrop(fp, td);
327         free(name, M_SONAME);
328         return (error);
329 }
330 
331 int
332 kern_accept(struct thread *td, int s, struct sockaddr **name,
333     socklen_t *namelen, struct file **fp)
334 {
335         struct filedesc *fdp;
336         struct file *headfp, *nfp = NULL;
337         struct sockaddr *sa = NULL;
338         int error;
339         struct socket *head, *so;
340         int fd;
341         u_int fflag;
342         pid_t pgid;
343         int tmp;
344 
345         if (name) {
346                 *name = NULL;
347                 if (*namelen < 0)
348                         return (EINVAL);
349         }
350 
351         fdp = td->td_proc->p_fd;
352         error = getsock(fdp, s, &headfp, &fflag);
353         if (error)
354                 return (error);
355         head = headfp->f_data;
356         if ((head->so_options & SO_ACCEPTCONN) == 0) {
357                 error = EINVAL;
358                 goto done;
359         }
360 #ifdef MAC
361         SOCK_LOCK(head);
362         error = mac_socket_check_accept(td->td_ucred, head);
363         SOCK_UNLOCK(head);
364         if (error != 0)
365                 goto done;
366 #endif
367         error = falloc(td, &nfp, &fd);
368         if (error)
369                 goto done;
370         ACCEPT_LOCK();
371         if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
372                 ACCEPT_UNLOCK();
373                 error = EWOULDBLOCK;
374                 goto noconnection;
375         }
376         while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
377                 if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
378                         head->so_error = ECONNABORTED;
379                         break;
380                 }
381                 error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH,
382                     "accept", 0);
383                 if (error) {
384                         ACCEPT_UNLOCK();
385                         goto noconnection;
386                 }
387         }
388         if (head->so_error) {
389                 error = head->so_error;
390                 head->so_error = 0;
391                 ACCEPT_UNLOCK();
392                 goto noconnection;
393         }
394         so = TAILQ_FIRST(&head->so_comp);
395         KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
396         KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
397 
398         /*
399          * Before changing the flags on the socket, we have to bump the
400          * reference count.  Otherwise, if the protocol calls sofree(),
401          * the socket will be released due to a zero refcount.
402          */
403         SOCK_LOCK(so);                  /* soref() and so_state update */
404         soref(so);                      /* file descriptor reference */
405 
406         TAILQ_REMOVE(&head->so_comp, so, so_list);
407         head->so_qlen--;
408         so->so_state |= (head->so_state & SS_NBIO);
409         so->so_qstate &= ~SQ_COMP;
410         so->so_head = NULL;
411 
412         SOCK_UNLOCK(so);
413         ACCEPT_UNLOCK();
414 
415         /* An extra reference on `nfp' has been held for us by falloc(). */
416         td->td_retval[0] = fd;
417 
418         /* connection has been removed from the listen queue */
419         KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0);
420 
421         pgid = fgetown(&head->so_sigio);
422         if (pgid != 0)
423                 fsetown(pgid, &so->so_sigio);
424 
425         finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
426         /* Sync socket nonblocking/async state with file flags */
427         tmp = fflag & FNONBLOCK;
428         (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
429         tmp = fflag & FASYNC;
430         (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
431         sa = 0;
432         error = soaccept(so, &sa);
433         if (error) {
434                 /*
435                  * return a namelen of zero for older code which might
436                  * ignore the return value from accept.
437                  */
438                 if (name)
439                         *namelen = 0;
440                 goto noconnection;
441         }
442         if (sa == NULL) {
443                 if (name)
444                         *namelen = 0;
445                 goto done;
446         }
447         if (name) {
448                 /* check sa_len before it is destroyed */
449                 if (*namelen > sa->sa_len)
450                         *namelen = sa->sa_len;
451 #ifdef KTRACE
452                 if (KTRPOINT(td, KTR_STRUCT))
453                         ktrsockaddr(sa);
454 #endif
455                 *name = sa;
456                 sa = NULL;
457         }
458 noconnection:
459         if (sa)
460                 FREE(sa, M_SONAME);
461 
462         /*
463          * close the new descriptor, assuming someone hasn't ripped it
464          * out from under us.
465          */
466         if (error)
467                 fdclose(fdp, nfp, fd, td);
468 
469         /*
470          * Release explicitly held references before returning.  We return
471          * a reference on nfp to the caller on success if they request it.
472          */
473 done:
474         if (fp != NULL) {
475                 if (error == 0) {
476                         *fp = nfp;
477                         nfp = NULL;
478                 } else
479                         *fp = NULL;
480         }
481         if (nfp != NULL)
482                 fdrop(nfp, td);
483         fdrop(headfp, td);
484         return (error);
485 }
486 
487 int
488 accept(td, uap)
489         struct thread *td;
490         struct accept_args *uap;
491 {
492 
493         return (accept1(td, uap, 0));
494 }
495 
496 #ifdef COMPAT_OLDSOCK
497 int
498 oaccept(td, uap)
499         struct thread *td;
500         struct accept_args *uap;
501 {
502 
503         return (accept1(td, uap, 1));
504 }
505 #endif /* COMPAT_OLDSOCK */
506 
507 /* ARGSUSED */
508 int
509 connect(td, uap)
510         struct thread *td;
511         struct connect_args /* {
512                 int     s;
513                 caddr_t name;
514                 int     namelen;
515         } */ *uap;
516 {
517         struct sockaddr *sa;
518         int error;
519 
520         error = getsockaddr(&sa, uap->name, uap->namelen);
521         if (error)
522                 return (error);
523 
524         error = kern_connect(td, uap->s, sa);
525         free(sa, M_SONAME);
526         return (error);
527 }
528 
529 
530 int
531 kern_connect(td, fd, sa)
532         struct thread *td;
533         int fd;
534         struct sockaddr *sa;
535 {
536         struct socket *so;
537         struct file *fp;
538         int error;
539         int interrupted = 0;
540 
541         error = getsock(td->td_proc->p_fd, fd, &fp, NULL);
542         if (error)
543                 return (error);
544         so = fp->f_data;
545         if (so->so_state & SS_ISCONNECTING) {
546                 error = EALREADY;
547                 goto done1;
548         }
549 #ifdef KTRACE
550         if (KTRPOINT(td, KTR_STRUCT))
551                 ktrsockaddr(sa);
552 #endif
553 #ifdef MAC
554         SOCK_LOCK(so);
555         error = mac_socket_check_connect(td->td_ucred, so, sa);
556         SOCK_UNLOCK(so);
557         if (error)
558                 goto bad;
559 #endif
560         error = soconnect(so, sa, td);
561         if (error)
562                 goto bad;
563         if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
564                 error = EINPROGRESS;
565                 goto done1;
566         }
567         SOCK_LOCK(so);
568         while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
569                 error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH,
570                     "connec", 0);
571                 if (error) {
572                         if (error == EINTR || error == ERESTART)
573                                 interrupted = 1;
574                         break;
575                 }
576         }
577         if (error == 0) {
578                 error = so->so_error;
579                 so->so_error = 0;
580         }
581         SOCK_UNLOCK(so);
582 bad:
583         if (!interrupted)
584                 so->so_state &= ~SS_ISCONNECTING;
585         if (error == ERESTART)
586                 error = EINTR;
587 done1:
588         fdrop(fp, td);
589         return (error);
590 }
591 
592 int
593 socketpair(td, uap)
594         struct thread *td;
595         struct socketpair_args /* {
596                 int     domain;
597                 int     type;
598                 int     protocol;
599                 int     *rsv;
600         } */ *uap;
601 {
602         struct filedesc *fdp = td->td_proc->p_fd;
603         struct file *fp1, *fp2;
604         struct socket *so1, *so2;
605         int fd, error, sv[2];
606 
607 #ifdef MAC
608         /* We might want to have a separate check for socket pairs. */
609         error = mac_socket_check_create(td->td_ucred, uap->domain, uap->type,
610             uap->protocol);
611         if (error)
612                 return (error);
613 #endif
614 
615         error = socreate(uap->domain, &so1, uap->type, uap->protocol,
616             td->td_ucred, td);
617         if (error)
618                 return (error);
619         error = socreate(uap->domain, &so2, uap->type, uap->protocol,
620             td->td_ucred, td);
621         if (error)
622                 goto free1;
623         /* On success extra reference to `fp1' and 'fp2' is set by falloc. */
624         error = falloc(td, &fp1, &fd);
625         if (error)
626                 goto free2;
627         sv[0] = fd;
628         fp1->f_data = so1;      /* so1 already has ref count */
629         error = falloc(td, &fp2, &fd);
630         if (error)
631                 goto free3;
632         fp2->f_data = so2;      /* so2 already has ref count */
633         sv[1] = fd;
634         error = soconnect2(so1, so2);
635         if (error)
636                 goto free4;
637         if (uap->type == SOCK_DGRAM) {
638                 /*
639                  * Datagram socket connection is asymmetric.
640                  */
641                  error = soconnect2(so2, so1);
642                  if (error)
643                         goto free4;
644         }
645         finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops);
646         finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops);
647         so1 = so2 = NULL;
648         error = copyout(sv, uap->rsv, 2 * sizeof (int));
649         if (error)
650                 goto free4;
651         fdrop(fp1, td);
652         fdrop(fp2, td);
653         return (0);
654 free4:
655         fdclose(fdp, fp2, sv[1], td);
656         fdrop(fp2, td);
657 free3:
658         fdclose(fdp, fp1, sv[0], td);
659         fdrop(fp1, td);
660 free2:
661         if (so2 != NULL)
662                 (void)soclose(so2);
663 free1:
664         if (so1 != NULL)
665                 (void)soclose(so1);
666         return (error);
667 }
668 
669 static int
670 sendit(td, s, mp, flags)
671         struct thread *td;
672         int s;
673         struct msghdr *mp;
674         int flags;
675 {
676         struct mbuf *control;
677         struct sockaddr *to;
678         int error;
679 
680         if (mp->msg_name != NULL) {
681                 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
682                 if (error) {
683                         to = NULL;
684                         goto bad;
685                 }
686                 mp->msg_name = to;
687         } else {
688                 to = NULL;
689         }
690 
691         if (mp->msg_control) {
692                 if (mp->msg_controllen < sizeof(struct cmsghdr)
693 #ifdef COMPAT_OLDSOCK
694                     && mp->msg_flags != MSG_COMPAT
695 #endif
696                 ) {
697                         error = EINVAL;
698                         goto bad;
699                 }
700                 error = sockargs(&control, mp->msg_control,
701                     mp->msg_controllen, MT_CONTROL);
702                 if (error)
703                         goto bad;
704 #ifdef COMPAT_OLDSOCK
705                 if (mp->msg_flags == MSG_COMPAT) {
706                         struct cmsghdr *cm;
707 
708                         M_PREPEND(control, sizeof(*cm), M_WAIT);
709                         cm = mtod(control, struct cmsghdr *);
710                         cm->cmsg_len = control->m_len;
711                         cm->cmsg_level = SOL_SOCKET;
712                         cm->cmsg_type = SCM_RIGHTS;
713                 }
714 #endif
715         } else {
716                 control = NULL;
717         }
718 
719         error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE);
720 
721 bad:
722         if (to)
723                 FREE(to, M_SONAME);
724         return (error);
725 }
726 
727 int
728 kern_sendit(td, s, mp, flags, control, segflg)
729         struct thread *td;
730         int s;
731         struct msghdr *mp;
732         int flags;
733         struct mbuf *control;
734         enum uio_seg segflg;
735 {
736         struct file *fp;
737         struct uio auio;
738         struct iovec *iov;
739         struct socket *so;
740         int i;
741         int len, error;
742 #ifdef KTRACE
743         struct uio *ktruio = NULL;
744 #endif
745 
746         error = getsock(td->td_proc->p_fd, s, &fp, NULL);
747         if (error)
748                 return (error);
749         so = (struct socket *)fp->f_data;
750 
751 #ifdef MAC
752         SOCK_LOCK(so);
753         if (mp->msg_name != NULL)
754                 error = mac_socket_check_connect(td->td_ucred, so,
755                     mp->msg_name);
756         if (error == 0)
757                 error = mac_socket_check_send(td->td_ucred, so);
758         SOCK_UNLOCK(so);
759         if (error)
760                 goto bad;
761 #endif
762 
763         auio.uio_iov = mp->msg_iov;
764         auio.uio_iovcnt = mp->msg_iovlen;
765         auio.uio_segflg = segflg;
766         auio.uio_rw = UIO_WRITE;
767         auio.uio_td = td;
768         auio.uio_offset = 0;                    /* XXX */
769         auio.uio_resid = 0;
770         iov = mp->msg_iov;
771         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
772                 if ((auio.uio_resid += iov->iov_len) < 0) {
773                         error = EINVAL;
774                         goto bad;
775                 }
776         }
777 #ifdef KTRACE
778         if (KTRPOINT(td, KTR_GENIO))
779                 ktruio = cloneuio(&auio);
780 #endif
781         len = auio.uio_resid;
782         error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
783         if (error) {
784                 if (auio.uio_resid != len && (error == ERESTART ||
785                     error == EINTR || error == EWOULDBLOCK))
786                         error = 0;
787                 /* Generation of SIGPIPE can be controlled per socket */
788                 if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
789                     !(flags & MSG_NOSIGNAL)) {
790                         PROC_LOCK(td->td_proc);
791                         psignal(td->td_proc, SIGPIPE);
792                         PROC_UNLOCK(td->td_proc);
793                 }
794         }
795         if (error == 0)
796                 td->td_retval[0] = len - auio.uio_resid;
797 #ifdef KTRACE
798         if (ktruio != NULL) {
799                 ktruio->uio_resid = td->td_retval[0];
800                 ktrgenio(s, UIO_WRITE, ktruio, error);
801         }
802 #endif
803 bad:
804         fdrop(fp, td);
805         return (error);
806 }
807 
808 int
809 sendto(td, uap)
810         struct thread *td;
811         struct sendto_args /* {
812                 int     s;
813                 caddr_t buf;
814                 size_t  len;
815                 int     flags;
816                 caddr_t to;
817                 int     tolen;
818         } */ *uap;
819 {
820         struct msghdr msg;
821         struct iovec aiov;
822         int error;
823 
824         msg.msg_name = uap->to;
825         msg.msg_namelen = uap->tolen;
826         msg.msg_iov = &aiov;
827         msg.msg_iovlen = 1;
828         msg.msg_control = 0;
829 #ifdef COMPAT_OLDSOCK
830         msg.msg_flags = 0;
831 #endif
832         aiov.iov_base = uap->buf;
833         aiov.iov_len = uap->len;
834         error = sendit(td, uap->s, &msg, uap->flags);
835         return (error);
836 }
837 
838 #ifdef COMPAT_OLDSOCK
839 int
840 osend(td, uap)
841         struct thread *td;
842         struct osend_args /* {
843                 int     s;
844                 caddr_t buf;
845                 int     len;
846                 int     flags;
847         } */ *uap;
848 {
849         struct msghdr msg;
850         struct iovec aiov;
851         int error;
852 
853         msg.msg_name = 0;
854         msg.msg_namelen = 0;
855         msg.msg_iov = &aiov;
856         msg.msg_iovlen = 1;
857         aiov.iov_base = uap->buf;
858         aiov.iov_len = uap->len;
859         msg.msg_control = 0;
860         msg.msg_flags = 0;
861         error = sendit(td, uap->s, &msg, uap->flags);
862         return (error);
863 }
864 
865 int
866 osendmsg(td, uap)
867         struct thread *td;
868         struct osendmsg_args /* {
869                 int     s;
870                 caddr_t msg;
871                 int     flags;
872         } */ *uap;
873 {
874         struct msghdr msg;
875         struct iovec *iov;
876         int error;
877 
878         error = copyin(uap->msg, &msg, sizeof (struct omsghdr));
879         if (error)
880                 return (error);
881         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
882         if (error)
883                 return (error);
884         msg.msg_iov = iov;
885         msg.msg_flags = MSG_COMPAT;
886         error = sendit(td, uap->s, &msg, uap->flags);
887         free(iov, M_IOV);
888         return (error);
889 }
890 #endif
891 
892 int
893 sendmsg(td, uap)
894         struct thread *td;
895         struct sendmsg_args /* {
896                 int     s;
897                 caddr_t msg;
898                 int     flags;
899         } */ *uap;
900 {
901         struct msghdr msg;
902         struct iovec *iov;
903         int error;
904 
905         error = copyin(uap->msg, &msg, sizeof (msg));
906         if (error)
907                 return (error);
908         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
909         if (error)
910                 return (error);
911         msg.msg_iov = iov;
912 #ifdef COMPAT_OLDSOCK
913         msg.msg_flags = 0;
914 #endif
915         error = sendit(td, uap->s, &msg, uap->flags);
916         free(iov, M_IOV);
917         return (error);
918 }
919 
920 int
921 kern_recvit(td, s, mp, fromseg, controlp)
922         struct thread *td;
923         int s;
924         struct msghdr *mp;
925         enum uio_seg fromseg;
926         struct mbuf **controlp;
927 {
928         struct uio auio;
929         struct iovec *iov;
930         int i;
931         socklen_t len;
932         int error;
933         struct mbuf *m, *control = 0;
934         caddr_t ctlbuf;
935         struct file *fp;
936         struct socket *so;
937         struct sockaddr *fromsa = 0;
938 #ifdef KTRACE
939         struct uio *ktruio = NULL;
940 #endif
941 
942         if(controlp != NULL)
943                 *controlp = 0;
944 
945         error = getsock(td->td_proc->p_fd, s, &fp, NULL);
946         if (error)
947                 return (error);
948         so = fp->f_data;
949 
950 #ifdef MAC
951         SOCK_LOCK(so);
952         error = mac_socket_check_receive(td->td_ucred, so);
953         SOCK_UNLOCK(so);
954         if (error) {
955                 fdrop(fp, td);
956                 return (error);
957         }
958 #endif
959 
960         auio.uio_iov = mp->msg_iov;
961         auio.uio_iovcnt = mp->msg_iovlen;
962         auio.uio_segflg = UIO_USERSPACE;
963         auio.uio_rw = UIO_READ;
964         auio.uio_td = td;
965         auio.uio_offset = 0;                    /* XXX */
966         auio.uio_resid = 0;
967         iov = mp->msg_iov;
968         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
969                 if ((auio.uio_resid += iov->iov_len) < 0) {
970                         fdrop(fp, td);
971                         return (EINVAL);
972                 }
973         }
974 #ifdef KTRACE
975         if (KTRPOINT(td, KTR_GENIO))
976                 ktruio = cloneuio(&auio);
977 #endif
978         len = auio.uio_resid;
979         error = soreceive(so, &fromsa, &auio, (struct mbuf **)0,
980             (