source: rtems-libbsd/freebsd/sys/kern/uipc_syscalls.c @ 6ffb9b9

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 6ffb9b9 was 6ffb9b9, checked in by Sebastian Huber <sebastian.huber@…>, on 10/11/13 at 12:48:13

Use shutdown() from FreeBSD

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