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