Deleted Added
full compact
uipc_socket.c (111741) uipc_socket.c (111742)
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
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 111741 2003-03-02 15:50:23Z des $
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
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);
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;
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 register int type;
170 int type;
171 int proto;
172 struct ucred *cred;
173 struct thread *td;
174{
171 int proto;
172 struct ucred *cred;
173 struct thread *td;
174{
175 register struct protosw *prp;
176 register struct socket *so;
177 register int error;
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)
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 register struct socket *so;
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)
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 register struct socket *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)
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 register struct socket *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)
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 register struct socket *so;
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)
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 register struct socket *so;
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)
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 register struct socket *so1;
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)
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 register struct socket *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)
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 register struct socket *so;
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;
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 register struct mbuf *m;
530 register long space, len, resid;
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) {
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
645#ifdef ZERO_COPY_SOCKETS
646 if (so_zero_copy_send &&
646 if (so_zero_copy_send &&
647 resid>=PAGE_SIZE &&
648 space>=PAGE_SIZE &&
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 }
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 }
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 }
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
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)
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 register struct socket *so;
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;
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 register int flags, len, error, s, offset;
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;
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
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)
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 register struct socket *so;
1106 register int how;
1105 struct socket *so;
1106 int how;
1107{
1107{
1108 register struct protosw *pr = so->so_proto;
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)
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 register struct socket *so;
1122 struct socket *so;
1123{
1123{
1124 register struct sockbuf *sb = &so->so_rcv;
1125 register struct protosw *pr = so->so_proto;
1126 register int s;
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)
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 register struct socket *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 ---
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 ---