1/* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. 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 --- 17 unchanged lines hidden (view full) --- 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 * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94 |
34 * $FreeBSD: head/sys/kern/uipc_socket.c 111742 2003-03-02 15:56:49Z des $ |
35 */ 36 37#include "opt_inet.h" 38#include "opt_mac.h" 39#include "opt_zero.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> --- 21 unchanged lines hidden (view full) --- 64#include <vm/uma.h> 65 66#include <machine/limits.h> 67 68#ifdef INET 69static int do_setopt_accept_filter(struct socket *so, struct sockopt *sopt); 70#endif 71 |
72static void filt_sordetach(struct knote *kn); 73static int filt_soread(struct knote *kn, long hint); 74static void filt_sowdetach(struct knote *kn); |
75static int filt_sowrite(struct knote *kn, long hint); 76static int filt_solisten(struct knote *kn, long hint); 77 78static struct filterops solisten_filtops = 79 { 1, NULL, filt_sordetach, filt_solisten }; 80static struct filterops soread_filtops = 81 { 1, NULL, filt_sordetach, filt_soread }; 82static struct filterops sowrite_filtops = --- 79 unchanged lines hidden (view full) --- 162/* 163 * socreate returns a socket with a ref count of 1. The socket should be 164 * closed with soclose(). 165 */ 166int 167socreate(dom, aso, type, proto, cred, td) 168 int dom; 169 struct socket **aso; |
170 int type; |
171 int proto; 172 struct ucred *cred; 173 struct thread *td; 174{ |
175 struct protosw *prp; 176 struct socket *so; 177 int error; |
178 179 if (proto) 180 prp = pffindproto(dom, proto, type); 181 else 182 prp = pffindtype(dom, type); 183 184 if (prp == 0 || prp->pr_usrreqs->pru_attach == 0) 185 return (EPROTONOSUPPORT); --- 67 unchanged lines hidden (view full) --- 253 crfree(so->so_cred); 254 /* sx_destroy(&so->so_sxlock); */ 255 uma_zfree(socket_zone, so); 256 --numopensockets; 257} 258 259int 260solisten(so, backlog, td) |
261 struct socket *so; |
262 int backlog; 263 struct thread *td; 264{ 265 int s, error; 266 267 s = splnet(); 268 if (so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING)) { 269 splx(s); --- 10 unchanged lines hidden (view full) --- 280 backlog = somaxconn; 281 so->so_qlimit = backlog; 282 splx(s); 283 return (0); 284} 285 286void 287sofree(so) |
288 struct socket *so; |
289{ 290 struct socket *head = so->so_head; 291 292 KASSERT(so->so_count == 0, ("socket %p so_count not 0", so)); 293 294 if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) 295 return; 296 if (head != NULL) { --- 25 unchanged lines hidden (view full) --- 322 * Free socket when disconnect complete. 323 * 324 * This function will sorele() the socket. Note that soclose() may be 325 * called prior to the ref count reaching zero. The actual socket 326 * structure will not be freed until the ref count reaches zero. 327 */ 328int 329soclose(so) |
330 struct socket *so; |
331{ 332 int s = splnet(); /* conservative */ 333 int error = 0; 334 335 funsetown(&so->so_sigio); 336 if (so->so_options & SO_ACCEPTCONN) { 337 struct socket *sp, *sonext; 338 --- 61 unchanged lines hidden (view full) --- 400 sotryfree(so); /* note: does not decrement the ref count */ 401 return error; 402 } 403 return (0); 404} 405 406int 407soaccept(so, nam) |
408 struct socket *so; |
409 struct sockaddr **nam; 410{ 411 int s = splnet(); 412 int error; 413 414 if ((so->so_state & SS_NOFDREF) == 0) 415 panic("soaccept: !NOFDREF"); 416 so->so_state &= ~SS_NOFDREF; 417 error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam); 418 splx(s); 419 return (error); 420} 421 422int 423soconnect(so, nam, td) |
424 struct socket *so; |
425 struct sockaddr *nam; 426 struct thread *td; 427{ 428 int s; 429 int error; 430 431 if (so->so_options & SO_ACCEPTCONN) 432 return (EOPNOTSUPP); --- 11 unchanged lines hidden (view full) --- 444 else 445 error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td); 446 splx(s); 447 return (error); 448} 449 450int 451soconnect2(so1, so2) |
452 struct socket *so1; |
453 struct socket *so2; 454{ 455 int s = splnet(); 456 int error; 457 458 error = (*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2); 459 splx(s); 460 return (error); 461} 462 463int 464sodisconnect(so) |
465 struct socket *so; |
466{ 467 int s = splnet(); 468 int error; 469 470 if ((so->so_state & SS_ISCONNECTED) == 0) { 471 error = ENOTCONN; 472 goto bad; 473 } --- 38 unchanged lines hidden (view full) --- 512#include <netinet/in_pcb.h> 513#include <vm/vm.h> 514#include <vm/vm_page.h> 515#include <vm/vm_object.h> 516#endif /*ZERO_COPY_SOCKETS*/ 517 518int 519sosend(so, addr, uio, top, control, flags, td) |
520 struct socket *so; |
521 struct sockaddr *addr; 522 struct uio *uio; 523 struct mbuf *top; 524 struct mbuf *control; 525 int flags; 526 struct thread *td; 527{ 528 struct mbuf **mp; |
529 struct mbuf *m; 530 long space, len, resid; |
531 int clen = 0, error, s, dontroute, mlen; 532 int atomic = sosendallatonce(so) || top; 533#ifdef ZERO_COPY_SOCKETS 534 int cow_send; 535#endif /* ZERO_COPY_SOCKETS */ 536 537 if (uio) 538 resid = uio->uio_resid; --- 98 unchanged lines hidden (view full) --- 637 MGET(m, M_TRYWAIT, MT_DATA); 638 if (m == NULL) { 639 error = ENOBUFS; 640 goto release; 641 } 642 mlen = MLEN; 643 } 644 if (resid >= MINCLSIZE) { |
645#ifdef ZERO_COPY_SOCKETS |
646 if (so_zero_copy_send && |
647 resid>=PAGE_SIZE && 648 space>=PAGE_SIZE && |
649 uio->uio_iov->iov_len>=PAGE_SIZE) { 650 so_zerocp_stats.size_ok++; 651 if (!((vm_offset_t) 652 uio->uio_iov->iov_base & PAGE_MASK)){ 653 so_zerocp_stats.align_ok++; 654 cow_send = socow_setup(m, uio); 655 } |
656 } |
657 if (!cow_send){ 658#endif /* ZERO_COPY_SOCKETS */ 659 MCLGET(m, M_TRYWAIT); 660 if ((m->m_flags & M_EXT) == 0) 661 goto nopages; 662 mlen = MCLBYTES; 663 len = min(min(mlen, resid), space); 664 } else { 665#ifdef ZERO_COPY_SOCKETS 666 len = PAGE_SIZE; 667 } |
668 |
669 } else { 670#endif /* ZERO_COPY_SOCKETS */ 671nopages: 672 len = min(min(mlen, resid), space); 673 /* 674 * For datagram protocols, leave room 675 * for protocol headers in first mbuf. 676 */ --- 81 unchanged lines hidden (view full) --- 758 * and thus we must maintain consistency of the sockbuf during that time. 759 * 760 * The caller may receive the data as a single mbuf chain by supplying 761 * an mbuf **mp0 for use in returning the chain. The uio is then used 762 * only for the count in uio_resid. 763 */ 764int 765soreceive(so, psa, uio, mp0, controlp, flagsp) |
766 struct socket *so; |
767 struct sockaddr **psa; 768 struct uio *uio; 769 struct mbuf **mp0; 770 struct mbuf **controlp; 771 int *flagsp; 772{ 773 struct mbuf *m, **mp; |
774 int flags, len, error, s, offset; |
775 struct protosw *pr = so->so_proto; 776 struct mbuf *nextrecord; 777 int moff, type = 0; 778 int orig_resid = uio->uio_resid; 779 780 mp = mp0; 781 if (psa) 782 *psa = 0; --- 192 unchanged lines hidden (view full) --- 975 vm_page_t pg; 976 int disposable; 977 978 if ((m->m_flags & M_EXT) 979 && (m->m_ext.ext_type == EXT_DISPOSABLE)) 980 disposable = 1; 981 else 982 disposable = 0; |
983 |
984 pg = PHYS_TO_VM_PAGE(vtophys(mtod(m, caddr_t) + 985 moff)); 986 987 if (uio->uio_offset == -1) 988 uio->uio_offset =IDX_TO_OFF(pg->pindex); 989 990 error = uiomoveco(mtod(m, char *) + moff, 991 (int)len, uio,pg->object, --- 105 unchanged lines hidden (view full) --- 1097release: 1098 sbunlock(&so->so_rcv); 1099 splx(s); 1100 return (error); 1101} 1102 1103int 1104soshutdown(so, how) |
1105 struct socket *so; 1106 int how; |
1107{ |
1108 struct protosw *pr = so->so_proto; |
1109 1110 if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR)) 1111 return (EINVAL); 1112 1113 if (how != SHUT_WR) 1114 sorflush(so); 1115 if (how != SHUT_RD) 1116 return ((*pr->pr_usrreqs->pru_shutdown)(so)); 1117 return (0); 1118} 1119 1120void 1121sorflush(so) |
1122 struct socket *so; |
1123{ |
1124 struct sockbuf *sb = &so->so_rcv; 1125 struct protosw *pr = so->so_proto; 1126 int s; |
1127 struct sockbuf asb; 1128 1129 sb->sb_flags |= SB_NOINTR; 1130 (void) sblock(sb, M_WAITOK); 1131 s = splimp(); 1132 socantrcvmore(so); 1133 sbunlock(sb); 1134 asb = *sb; --- 546 unchanged lines hidden (view full) --- 1681 return(EINVAL); 1682 } 1683 sopt->sopt_valsize = valsize; 1684 return 0; 1685} 1686 1687void 1688sohasoutofband(so) |
1689 struct socket *so; |
1690{ 1691 if (so->so_sigio != NULL) 1692 pgsigio(&so->so_sigio, SIGURG, 0); 1693 selwakeup(&so->so_rcv.sb_sel); 1694} 1695 1696int 1697sopoll(struct socket *so, int events, struct ucred *active_cred, --- 155 unchanged lines hidden --- |