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