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