1 /* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * from: @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94 34 * $Id: uipc_socket.c,v 1.15 1994/05/13 06:01:37 mycroft Exp $ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/proc.h> 40 #include <sys/file.h> 41 #include <sys/malloc.h> 42 #include <sys/mbuf.h> 43 #include <sys/domain.h> 44 #include <sys/kernel.h> 45 #include <sys/protosw.h> 46 #include <sys/socket.h> 47 #include <sys/socketvar.h> 48 #include <sys/resourcevar.h> 49 50 /* 51 * Socket operation routines. 52 * These routines are called by the routines in 53 * sys_socket.c or from a system process, and 54 * implement the semantics of socket operations by 55 * switching out to the protocol specific routines. 56 */ 57 /*ARGSUSED*/ 58 int 59 socreate(dom, aso, type, proto) 60 int dom; 61 struct socket **aso; 62 register int type; 63 int proto; 64 { 65 struct proc *p = curproc; /* XXX */ 66 register struct protosw *prp; 67 register struct socket *so; 68 register int error; 69 70 if (proto) 71 prp = pffindproto(dom, proto, type); 72 else 73 prp = pffindtype(dom, type); 74 if (prp == 0 || prp->pr_usrreq == 0) 75 return (EPROTONOSUPPORT); 76 if (prp->pr_type != type) 77 return (EPROTOTYPE); 78 MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT); 79 bzero((caddr_t)so, sizeof(*so)); 80 so->so_type = type; 81 if (p->p_ucred->cr_uid == 0) 82 so->so_state = SS_PRIV; 83 so->so_proto = prp; 84 error = 85 (*prp->pr_usrreq)(so, PRU_ATTACH, 86 (struct mbuf *)0, (struct mbuf *)proto, (struct mbuf *)0); 87 if (error) { 88 so->so_state |= SS_NOFDREF; 89 sofree(so); 90 return (error); 91 } 92 #ifdef COMPAT_SUNOS 93 if (p->p_emul == EMUL_SUNOS && type == SOCK_DGRAM) 94 so->so_options |= SO_BROADCAST; 95 #endif 96 *aso = so; 97 return (0); 98 } 99 100 int 101 sobind(so, nam) 102 struct socket *so; 103 struct mbuf *nam; 104 { 105 int s = splnet(); 106 int error; 107 108 error = 109 (*so->so_proto->pr_usrreq)(so, PRU_BIND, 110 (struct mbuf *)0, nam, (struct mbuf *)0); 111 splx(s); 112 return (error); 113 } 114 115 int 116 solisten(so, backlog) 117 register struct socket *so; 118 int backlog; 119 { 120 int s = splnet(), error; 121 122 error = 123 (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, 124 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0); 125 if (error) { 126 splx(s); 127 return (error); 128 } 129 if (so->so_q == 0) 130 so->so_options |= SO_ACCEPTCONN; 131 if (backlog < 0) 132 backlog = 0; 133 so->so_qlimit = min(backlog, SOMAXCONN); 134 splx(s); 135 return (0); 136 } 137 138 int 139 sofree(so) 140 register struct socket *so; 141 { 142 143 if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) 144 return; 145 if (so->so_head) { 146 if (!soqremque(so, 0) && !soqremque(so, 1)) 147 panic("sofree dq"); 148 so->so_head = 0; 149 } 150 sbrelease(&so->so_snd); 151 sorflush(so); 152 FREE(so, M_SOCKET); 153 } 154 155 /* 156 * Close a socket on last file table reference removal. 157 * Initiate disconnect if connected. 158 * Free socket when disconnect complete. 159 */ 160 int 161 soclose(so) 162 register struct socket *so; 163 { 164 int s = splnet(); /* conservative */ 165 int error = 0; 166 167 if (so->so_options & SO_ACCEPTCONN) { 168 while (so->so_q0) 169 (void) soabort(so->so_q0); 170 while (so->so_q) 171 (void) soabort(so->so_q); 172 } 173 if (so->so_pcb == 0) 174 goto discard; 175 if (so->so_state & SS_ISCONNECTED) { 176 if ((so->so_state & SS_ISDISCONNECTING) == 0) { 177 error = sodisconnect(so); 178 if (error) 179 goto drop; 180 } 181 if (so->so_options & SO_LINGER) { 182 if ((so->so_state & SS_ISDISCONNECTING) && 183 (so->so_state & SS_NBIO)) 184 goto drop; 185 while (so->so_state & SS_ISCONNECTED) 186 if (error = tsleep((caddr_t)&so->so_timeo, 187 PSOCK | PCATCH, netcls, so->so_linger)) 188 break; 189 } 190 } 191 drop: 192 if (so->so_pcb) { 193 int error2 = 194 (*so->so_proto->pr_usrreq)(so, PRU_DETACH, 195 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0); 196 if (error == 0) 197 error = error2; 198 } 199 discard: 200 if (so->so_state & SS_NOFDREF) 201 panic("soclose: NOFDREF"); 202 so->so_state |= SS_NOFDREF; 203 sofree(so); 204 splx(s); 205 return (error); 206 } 207 208 /* 209 * Must be called at splnet... 210 */ 211 int 212 soabort(so) 213 struct socket *so; 214 { 215 216 return ( 217 (*so->so_proto->pr_usrreq)(so, PRU_ABORT, 218 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)); 219 } 220 221 int 222 soaccept(so, nam) 223 register struct socket *so; 224 struct mbuf *nam; 225 { 226 int s = splnet(); 227 int error; 228 229 if ((so->so_state & SS_NOFDREF) == 0) 230 panic("soaccept: !NOFDREF"); 231 so->so_state &= ~SS_NOFDREF; 232 error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, 233 (struct mbuf *)0, nam, (struct mbuf *)0); 234 splx(s); 235 return (error); 236 } 237 238 int 239 soconnect(so, nam) 240 register struct socket *so; 241 struct mbuf *nam; 242 { 243 int s; 244 int error; 245 246 if (so->so_options & SO_ACCEPTCONN) 247 return (EOPNOTSUPP); 248 s = splnet(); 249 /* 250 * If protocol is connection-based, can only connect once. 251 * Otherwise, if connected, try to disconnect first. 252 * This allows user to disconnect by connecting to, e.g., 253 * a null address. 254 */ 255 if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) && 256 ((so->so_proto->pr_flags & PR_CONNREQUIRED) || 257 (error = sodisconnect(so)))) 258 error = EISCONN; 259 else 260 error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT, 261 (struct mbuf *)0, nam, (struct mbuf *)0); 262 splx(s); 263 return (error); 264 } 265 266 int 267 soconnect2(so1, so2) 268 register struct socket *so1; 269 struct socket *so2; 270 { 271 int s = splnet(); 272 int error; 273 274 error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, 275 (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0); 276 splx(s); 277 return (error); 278 } 279 280 int 281 sodisconnect(so) 282 register struct socket *so; 283 { 284 int s = splnet(); 285 int error; 286 287 if ((so->so_state & SS_ISCONNECTED) == 0) { 288 error = ENOTCONN; 289 goto bad; 290 } 291 if (so->so_state & SS_ISDISCONNECTING) { 292 error = EALREADY; 293 goto bad; 294 } 295 error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, 296 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0); 297 bad: 298 splx(s); 299 return (error); 300 } 301 302 #define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK) 303 /* 304 * Send on a socket. 305 * If send must go all at once and message is larger than 306 * send buffering, then hard error. 307 * Lock against other senders. 308 * If must go all at once and not enough room now, then 309 * inform user that this would block and do nothing. 310 * Otherwise, if nonblocking, send as much as possible. 311 * The data to be sent is described by "uio" if nonzero, 312 * otherwise by the mbuf chain "top" (which must be null 313 * if uio is not). Data provided in mbuf chain must be small 314 * enough to send all at once. 315 * 316 * Returns nonzero on error, timeout or signal; callers 317 * must check for short counts if EINTR/ERESTART are returned. 318 * Data and control buffers are freed on return. 319 */ 320 int 321 sosend(so, addr, uio, top, control, flags) 322 register struct socket *so; 323 struct mbuf *addr; 324 struct uio *uio; 325 struct mbuf *top; 326 struct mbuf *control; 327 int flags; 328 { 329 struct proc *p = curproc; /* XXX */ 330 struct mbuf **mp; 331 register struct mbuf *m; 332 register long space, len, resid; 333 int clen = 0, error, s, dontroute, mlen; 334 int atomic = sosendallatonce(so) || top; 335 336 if (uio) 337 resid = uio->uio_resid; 338 else 339 resid = top->m_pkthdr.len; 340 /* 341 * In theory resid should be unsigned. 342 * However, space must be signed, as it might be less than 0 343 * if we over-committed, and we must use a signed comparison 344 * of space and resid. On the other hand, a negative resid 345 * causes us to loop sending 0-length segments to the protocol. 346 */ 347 if (resid < 0) 348 return (EINVAL); 349 dontroute = 350 (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 && 351 (so->so_proto->pr_flags & PR_ATOMIC); 352 p->p_stats->p_ru.ru_msgsnd++; 353 if (control) 354 clen = control->m_len; 355 #define snderr(errno) { error = errno; splx(s); goto release; } 356 357 restart: 358 if (error = sblock(&so->so_snd, SBLOCKWAIT(flags))) 359 goto out; 360 do { 361 s = splnet(); 362 if (so->so_state & SS_CANTSENDMORE) 363 snderr(EPIPE); 364 if (so->so_error) 365 snderr(so->so_error); 366 if ((so->so_state & SS_ISCONNECTED) == 0) { 367 if (so->so_proto->pr_flags & PR_CONNREQUIRED) { 368 if ((so->so_state & SS_ISCONFIRMING) == 0 && 369 !(resid == 0 && clen != 0)) 370 snderr(ENOTCONN); 371 } else if (addr == 0) 372 snderr(EDESTADDRREQ); 373 } 374 space = sbspace(&so->so_snd); 375 if (flags & MSG_OOB) 376 space += 1024; 377 if (atomic && resid > so->so_snd.sb_hiwat || 378 clen > so->so_snd.sb_hiwat) 379 snderr(EMSGSIZE); 380 if (space < resid + clen && uio && 381 (atomic || space < so->so_snd.sb_lowat || space < clen)) { 382 if (so->so_state & SS_NBIO) 383 snderr(EWOULDBLOCK); 384 sbunlock(&so->so_snd); 385 error = sbwait(&so->so_snd); 386 splx(s); 387 if (error) 388 goto out; 389 goto restart; 390 } 391 splx(s); 392 mp = ⊤ 393 space -= clen; 394 do { 395 if (uio == NULL) { 396 /* 397 * Data is prepackaged in "top". 398 */ 399 resid = 0; 400 if (flags & MSG_EOR) 401 top->m_flags |= M_EOR; 402 } else do { 403 if (top == 0) { 404 MGETHDR(m, M_WAIT, MT_DATA); 405 mlen = MHLEN; 406 m->m_pkthdr.len = 0; 407 m->m_pkthdr.rcvif = (struct ifnet *)0; 408 } else { 409 MGET(m, M_WAIT, MT_DATA); 410 mlen = MLEN; 411 } 412 if (resid >= MINCLSIZE && space >= MCLBYTES) { 413 MCLGET(m, M_WAIT); 414 if ((m->m_flags & M_EXT) == 0) 415 goto nopages; 416 mlen = MCLBYTES; 417 #ifdef MAPPED_MBUFS 418 len = min(MCLBYTES, resid); 419 #else 420 if (atomic && top == 0) { 421 len = min(MCLBYTES - max_hdr, resid); 422 m->m_data += max_hdr; 423 } else 424 len = min(MCLBYTES, resid); 425 #endif 426 space -= MCLBYTES; 427 } else { 428 nopages: 429 len = min(min(mlen, resid), space); 430 space -= len; 431 /* 432 * For datagram protocols, leave room 433 * for protocol headers in first mbuf. 434 */ 435 if (atomic && top == 0 && len < mlen) 436 MH_ALIGN(m, len); 437 } 438 error = uiomove(mtod(m, caddr_t), (int)len, uio); 439 resid = uio->uio_resid; 440 m->m_len = len; 441 *mp = m; 442 top->m_pkthdr.len += len; 443 if (error) 444 goto release; 445 mp = &m->m_next; 446 if (resid <= 0) { 447 if (flags & MSG_EOR) 448 top->m_flags |= M_EOR; 449 break; 450 } 451 } while (space > 0 && atomic); 452 if (dontroute) 453 so->so_options |= SO_DONTROUTE; 454 s = splnet(); /* XXX */ 455 error = (*so->so_proto->pr_usrreq)(so, 456 (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND, 457 top, addr, control); 458 splx(s); 459 if (dontroute) 460 so->so_options &= ~SO_DONTROUTE; 461 clen = 0; 462 control = 0; 463 top = 0; 464 mp = ⊤ 465 if (error) 466 goto release; 467 } while (resid && space > 0); 468 } while (resid); 469 470 release: 471 sbunlock(&so->so_snd); 472 out: 473 if (top) 474 m_freem(top); 475 if (control) 476 m_freem(control); 477 return (error); 478 } 479 480 /* 481 * Implement receive operations on a socket. 482 * We depend on the way that records are added to the sockbuf 483 * by sbappend*. In particular, each record (mbufs linked through m_next) 484 * must begin with an address if the protocol so specifies, 485 * followed by an optional mbuf or mbufs containing ancillary data, 486 * and then zero or more mbufs of data. 487 * In order to avoid blocking network interrupts for the entire time here, 488 * we splx() while doing the actual copy to user space. 489 * Although the sockbuf is locked, new data may still be appended, 490 * and thus we must maintain consistency of the sockbuf during that time. 491 * 492 * The caller may receive the data as a single mbuf chain by supplying 493 * an mbuf **mp0 for use in returning the chain. The uio is then used 494 * only for the count in uio_resid. 495 */ 496 int 497 soreceive(so, paddr, uio, mp0, controlp, flagsp) 498 register struct socket *so; 499 struct mbuf **paddr; 500 struct uio *uio; 501 struct mbuf **mp0; 502 struct mbuf **controlp; 503 int *flagsp; 504 { 505 register struct mbuf *m, **mp; 506 register int flags, len, error, s, offset; 507 struct protosw *pr = so->so_proto; 508 struct mbuf *nextrecord; 509 int moff, type; 510 int orig_resid = uio->uio_resid; 511 512 mp = mp0; 513 if (paddr) 514 *paddr = 0; 515 if (controlp) 516 *controlp = 0; 517 if (flagsp) 518 flags = *flagsp &~ MSG_EOR; 519 else 520 flags = 0; 521 if (flags & MSG_OOB) { 522 m = m_get(M_WAIT, MT_DATA); 523 error = (*pr->pr_usrreq)(so, PRU_RCVOOB, 524 m, (struct mbuf *)(flags & MSG_PEEK), (struct mbuf *)0); 525 if (error) 526 goto bad; 527 do { 528 error = uiomove(mtod(m, caddr_t), 529 (int) min(uio->uio_resid, m->m_len), uio); 530 m = m_free(m); 531 } while (uio->uio_resid && error == 0 && m); 532 bad: 533 if (m) 534 m_freem(m); 535 return (error); 536 } 537 if (mp) 538 *mp = (struct mbuf *)0; 539 if (so->so_state & SS_ISCONFIRMING && uio->uio_resid) 540 (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0, 541 (struct mbuf *)0, (struct mbuf *)0); 542 543 restart: 544 if (error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) 545 return (error); 546 s = splnet(); 547 548 m = so->so_rcv.sb_mb; 549 /* 550 * If we have less data than requested, block awaiting more 551 * (subject to any timeout) if: 552 * 1. the current count is less than the low water mark, 553 * 2. MSG_WAITALL is set, and it is possible to do the entire 554 * receive operation at once if we block (resid <= hiwat), or 555 * 3. MSG_DONTWAIT is not set. 556 * If MSG_WAITALL is set but resid is larger than the receive buffer, 557 * we have to do the receive in sections, and thus risk returning 558 * a short count if a timeout or signal occurs after we start. 559 */ 560 if (m == 0 || ((flags & MSG_DONTWAIT) == 0 && 561 so->so_rcv.sb_cc < uio->uio_resid) && 562 (so->so_rcv.sb_cc < so->so_rcv.sb_lowat || 563 ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) && 564 m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0) { 565 #ifdef DIAGNOSTIC 566 if (m == 0 && so->so_rcv.sb_cc) 567 panic("receive 1"); 568 #endif 569 if (so->so_error) { 570 if (m) 571 goto dontblock; 572 error = so->so_error; 573 if ((flags & MSG_PEEK) == 0) 574 so->so_error = 0; 575 goto release; 576 } 577 if (so->so_state & SS_CANTRCVMORE) { 578 if (m) 579 goto dontblock; 580 else 581 goto release; 582 } 583 for (; m; m = m->m_next) 584 if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) { 585 m = so->so_rcv.sb_mb; 586 goto dontblock; 587 } 588 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 && 589 (so->so_proto->pr_flags & PR_CONNREQUIRED)) { 590 error = ENOTCONN; 591 goto release; 592 } 593 if (uio->uio_resid == 0) 594 goto release; 595 if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) { 596 error = EWOULDBLOCK; 597 goto release; 598 } 599 sbunlock(&so->so_rcv); 600 error = sbwait(&so->so_rcv); 601 splx(s); 602 if (error) 603 return (error); 604 goto restart; 605 } 606 dontblock: 607 #ifdef notyet /* XXXX */ 608 if (uio->uio_procp) 609 uio->uio_procp->p_stats->p_ru.ru_msgrcv++; 610 #endif 611 nextrecord = m->m_nextpkt; 612 if (pr->pr_flags & PR_ADDR) { 613 #ifdef DIAGNOSTIC 614 if (m->m_type != MT_SONAME) 615 panic("receive 1a"); 616 #endif 617 orig_resid = 0; 618 if (flags & MSG_PEEK) { 619 if (paddr) 620 *paddr = m_copy(m, 0, m->m_len); 621 m = m->m_next; 622 } else { 623 sbfree(&so->so_rcv, m); 624 if (paddr) { 625 *paddr = m; 626 so->so_rcv.sb_mb = m->m_next; 627 m->m_next = 0; 628 m = so->so_rcv.sb_mb; 629 } else { 630 MFREE(m, so->so_rcv.sb_mb); 631 m = so->so_rcv.sb_mb; 632 } 633 } 634 } 635 while (m && m->m_type == MT_CONTROL && error == 0) { 636 if (flags & MSG_PEEK) { 637 if (controlp) 638 *controlp = m_copy(m, 0, m->m_len); 639 m = m->m_next; 640 } else { 641 sbfree(&so->so_rcv, m); 642 if (controlp) { 643 if (pr->pr_domain->dom_externalize && 644 mtod(m, struct cmsghdr *)->cmsg_type == 645 SCM_RIGHTS) 646 error = (*pr->pr_domain->dom_externalize)(m); 647 *controlp = m; 648 so->so_rcv.sb_mb = m->m_next; 649 m->m_next = 0; 650 m = so->so_rcv.sb_mb; 651 } else { 652 MFREE(m, so->so_rcv.sb_mb); 653 m = so->so_rcv.sb_mb; 654 } 655 } 656 if (controlp) { 657 orig_resid = 0; 658 controlp = &(*controlp)->m_next; 659 } 660 } 661 if (m) { 662 if ((flags & MSG_PEEK) == 0) 663 m->m_nextpkt = nextrecord; 664 type = m->m_type; 665 if (type == MT_OOBDATA) 666 flags |= MSG_OOB; 667 } 668 moff = 0; 669 offset = 0; 670 while (m && uio->uio_resid > 0 && error == 0) { 671 if (m->m_type == MT_OOBDATA) { 672 if (type != MT_OOBDATA) 673 break; 674 } else if (type == MT_OOBDATA) 675 break; 676 #ifdef DIAGNOSTIC 677 else if (m->m_type != MT_DATA && m->m_type != MT_HEADER) 678 panic("receive 3"); 679 #endif 680 so->so_state &= ~SS_RCVATMARK; 681 len = uio->uio_resid; 682 if (so->so_oobmark && len > so->so_oobmark - offset) 683 len = so->so_oobmark - offset; 684 if (len > m->m_len - moff) 685 len = m->m_len - moff; 686 /* 687 * If mp is set, just pass back the mbufs. 688 * Otherwise copy them out via the uio, then free. 689 * Sockbuf must be consistent here (points to current mbuf, 690 * it points to next record) when we drop priority; 691 * we must note any additions to the sockbuf when we 692 * block interrupts again. 693 */ 694 if (mp == 0) { 695 splx(s); 696 error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio); 697 s = splnet(); 698 } else 699 uio->uio_resid -= len; 700 if (len == m->m_len - moff) { 701 if (m->m_flags & M_EOR) 702 flags |= MSG_EOR; 703 if (flags & MSG_PEEK) { 704 m = m->m_next; 705 moff = 0; 706 } else { 707 nextrecord = m->m_nextpkt; 708 sbfree(&so->so_rcv, m); 709 if (mp) { 710 *mp = m; 711 mp = &m->m_next; 712 so->so_rcv.sb_mb = m = m->m_next; 713 *mp = (struct mbuf *)0; 714 } else { 715 MFREE(m, so->so_rcv.sb_mb); 716 m = so->so_rcv.sb_mb; 717 } 718 if (m) 719 m->m_nextpkt = nextrecord; 720 } 721 } else { 722 if (flags & MSG_PEEK) 723 moff += len; 724 else { 725 if (mp) 726 *mp = m_copym(m, 0, len, M_WAIT); 727 m->m_data += len; 728 m->m_len -= len; 729 so->so_rcv.sb_cc -= len; 730 } 731 } 732 if (so->so_oobmark) { 733 if ((flags & MSG_PEEK) == 0) { 734 so->so_oobmark -= len; 735 if (so->so_oobmark == 0) { 736 so->so_state |= SS_RCVATMARK; 737 break; 738 } 739 } else { 740 offset += len; 741 if (offset == so->so_oobmark) 742 break; 743 } 744 } 745 if (flags & MSG_EOR) 746 break; 747 /* 748 * If the MSG_WAITALL flag is set (for non-atomic socket), 749 * we must not quit until "uio->uio_resid == 0" or an error 750 * termination. If a signal/timeout occurs, return 751 * with a short count but without error. 752 * Keep sockbuf locked against other readers. 753 */ 754 while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 && 755 !sosendallatonce(so) && !nextrecord) { 756 if (so->so_error || so->so_state & SS_CANTRCVMORE) 757 break; 758 error = sbwait(&so->so_rcv); 759 if (error) { 760 sbunlock(&so->so_rcv); 761 splx(s); 762 return (0); 763 } 764 if (m = so->so_rcv.sb_mb) 765 nextrecord = m->m_nextpkt; 766 } 767 } 768 769 if (m && pr->pr_flags & PR_ATOMIC) { 770 flags |= MSG_TRUNC; 771 if ((flags & MSG_PEEK) == 0) 772 (void) sbdroprecord(&so->so_rcv); 773 } 774 if ((flags & MSG_PEEK) == 0) { 775 if (m == 0) 776 so->so_rcv.sb_mb = nextrecord; 777 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb) 778 (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0, 779 (struct mbuf *)flags, (struct mbuf *)0, 780 (struct mbuf *)0); 781 } 782 if (orig_resid == uio->uio_resid && orig_resid && 783 (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) { 784 sbunlock(&so->so_rcv); 785 splx(s); 786 goto restart; 787 } 788 789 if (flagsp) 790 *flagsp |= flags; 791 release: 792 sbunlock(&so->so_rcv); 793 splx(s); 794 return (error); 795 } 796 797 int 798 soshutdown(so, how) 799 register struct socket *so; 800 register int how; 801 { 802 register struct protosw *pr = so->so_proto; 803 804 how++; 805 if (how & FREAD) 806 sorflush(so); 807 if (how & FWRITE) 808 return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN, 809 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)); 810 return (0); 811 } 812 813 void 814 sorflush(so) 815 register struct socket *so; 816 { 817 register struct sockbuf *sb = &so->so_rcv; 818 register struct protosw *pr = so->so_proto; 819 register int s; 820 struct sockbuf asb; 821 822 sb->sb_flags |= SB_NOINTR; 823 (void) sblock(sb, M_WAITOK); 824 s = splimp(); 825 socantrcvmore(so); 826 sbunlock(sb); 827 asb = *sb; 828 bzero((caddr_t)sb, sizeof (*sb)); 829 splx(s); 830 if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) 831 (*pr->pr_domain->dom_dispose)(asb.sb_mb); 832 sbrelease(&asb); 833 } 834 835 int 836 sosetopt(so, level, optname, m0) 837 register struct socket *so; 838 int level, optname; 839 struct mbuf *m0; 840 { 841 int error = 0; 842 register struct mbuf *m = m0; 843 844 if (level != SOL_SOCKET) { 845 if (so->so_proto && so->so_proto->pr_ctloutput) 846 return ((*so->so_proto->pr_ctloutput) 847 (PRCO_SETOPT, so, level, optname, &m0)); 848 error = ENOPROTOOPT; 849 } else { 850 switch (optname) { 851 852 case SO_LINGER: 853 if (m == NULL || m->m_len != sizeof (struct linger)) { 854 error = EINVAL; 855 goto bad; 856 } 857 so->so_linger = mtod(m, struct linger *)->l_linger; 858 /* fall thru... */ 859 860 case SO_DEBUG: 861 case SO_KEEPALIVE: 862 case SO_DONTROUTE: 863 case SO_USELOOPBACK: 864 case SO_BROADCAST: 865 case SO_REUSEADDR: 866 case SO_REUSEPORT: 867 case SO_OOBINLINE: 868 if (m == NULL || m->m_len < sizeof (int)) { 869 error = EINVAL; 870 goto bad; 871 } 872 if (*mtod(m, int *)) 873 so->so_options |= optname; 874 else 875 so->so_options &= ~optname; 876 break; 877 878 case SO_SNDBUF: 879 case SO_RCVBUF: 880 case SO_SNDLOWAT: 881 case SO_RCVLOWAT: 882 if (m == NULL || m->m_len < sizeof (int)) { 883 error = EINVAL; 884 goto bad; 885 } 886 switch (optname) { 887 888 case SO_SNDBUF: 889 case SO_RCVBUF: 890 if (sbreserve(optname == SO_SNDBUF ? 891 &so->so_snd : &so->so_rcv, 892 (u_long) *mtod(m, int *)) == 0) { 893 error = ENOBUFS; 894 goto bad; 895 } 896 break; 897 898 case SO_SNDLOWAT: 899 so->so_snd.sb_lowat = *mtod(m, int *); 900 break; 901 case SO_RCVLOWAT: 902 so->so_rcv.sb_lowat = *mtod(m, int *); 903 break; 904 } 905 break; 906 907 case SO_SNDTIMEO: 908 case SO_RCVTIMEO: 909 { 910 struct timeval *tv; 911 short val; 912 913 if (m == NULL || m->m_len < sizeof (*tv)) { 914 error = EINVAL; 915 goto bad; 916 } 917 tv = mtod(m, struct timeval *); 918 if (tv->tv_sec > SHRT_MAX / hz - hz) { 919 error = EDOM; 920 goto bad; 921 } 922 val = tv->tv_sec * hz + tv->tv_usec / tick; 923 924 switch (optname) { 925 926 case SO_SNDTIMEO: 927 so->so_snd.sb_timeo = val; 928 break; 929 case SO_RCVTIMEO: 930 so->so_rcv.sb_timeo = val; 931 break; 932 } 933 break; 934 } 935 936 default: 937 error = ENOPROTOOPT; 938 break; 939 } 940 if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) { 941 (void) ((*so->so_proto->pr_ctloutput) 942 (PRCO_SETOPT, so, level, optname, &m0)); 943 m = NULL; /* freed by protocol */ 944 } 945 } 946 bad: 947 if (m) 948 (void) m_free(m); 949 return (error); 950 } 951 952 int 953 sogetopt(so, level, optname, mp) 954 register struct socket *so; 955 int level, optname; 956 struct mbuf **mp; 957 { 958 register struct mbuf *m; 959 960 if (level != SOL_SOCKET) { 961 if (so->so_proto && so->so_proto->pr_ctloutput) { 962 return ((*so->so_proto->pr_ctloutput) 963 (PRCO_GETOPT, so, level, optname, mp)); 964 } else 965 return (ENOPROTOOPT); 966 } else { 967 m = m_get(M_WAIT, MT_SOOPTS); 968 m->m_len = sizeof (int); 969 970 switch (optname) { 971 972 case SO_LINGER: 973 m->m_len = sizeof (struct linger); 974 mtod(m, struct linger *)->l_onoff = 975 so->so_options & SO_LINGER; 976 mtod(m, struct linger *)->l_linger = so->so_linger; 977 break; 978 979 case SO_USELOOPBACK: 980 case SO_DONTROUTE: 981 case SO_DEBUG: 982 case SO_KEEPALIVE: 983 case SO_REUSEADDR: 984 case SO_REUSEPORT: 985 case SO_BROADCAST: 986 case SO_OOBINLINE: 987 *mtod(m, int *) = so->so_options & optname; 988 break; 989 990 case SO_TYPE: 991 *mtod(m, int *) = so->so_type; 992 break; 993 994 case SO_ERROR: 995 *mtod(m, int *) = so->so_error; 996 so->so_error = 0; 997 break; 998 999 case SO_SNDBUF: 1000 *mtod(m, int *) = so->so_snd.sb_hiwat; 1001 break; 1002 1003 case SO_RCVBUF: 1004 *mtod(m, int *) = so->so_rcv.sb_hiwat; 1005 break; 1006 1007 case SO_SNDLOWAT: 1008 *mtod(m, int *) = so->so_snd.sb_lowat; 1009 break; 1010 1011 case SO_RCVLOWAT: 1012 *mtod(m, int *) = so->so_rcv.sb_lowat; 1013 break; 1014 1015 case SO_SNDTIMEO: 1016 case SO_RCVTIMEO: 1017 { 1018 int val = (optname == SO_SNDTIMEO ? 1019 so->so_snd.sb_timeo : so->so_rcv.sb_timeo); 1020 1021 m->m_len = sizeof(struct timeval); 1022 mtod(m, struct timeval *)->tv_sec = val / hz; 1023 mtod(m, struct timeval *)->tv_usec = 1024 (val % hz) / tick; 1025 break; 1026 } 1027 1028 default: 1029 (void)m_free(m); 1030 return (ENOPROTOOPT); 1031 } 1032 *mp = m; 1033 return (0); 1034 } 1035 } 1036 1037 void 1038 sohasoutofband(so) 1039 register struct socket *so; 1040 { 1041 struct proc *p; 1042 1043 if (so->so_pgid < 0) 1044 gsignal(-so->so_pgid, SIGURG); 1045 else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) 1046 psignal(p, SIGURG); 1047 selwakeup(&so->so_rcv.sb_sel); 1048 } 1049