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