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