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