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