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