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