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