Deleted Added
full compact
uipc_usrreq.c (262867) uipc_usrreq.c (262914)
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California.
4 * Copyright (c) 2004-2009 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 37 unchanged lines hidden (view full) ---

46 * The implementation is substantially complicated by the fact that
47 * "ancillary data", such as file descriptors or credentials, may be passed
48 * across UNIX domain sockets. The potential for passing UNIX domain sockets
49 * over other UNIX domain sockets requires the implementation of a simple
50 * garbage collector to find and tear down cycles of disconnected sockets.
51 *
52 * TODO:
53 * RDM
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California.
4 * Copyright (c) 2004-2009 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 37 unchanged lines hidden (view full) ---

46 * The implementation is substantially complicated by the fact that
47 * "ancillary data", such as file descriptors or credentials, may be passed
48 * across UNIX domain sockets. The potential for passing UNIX domain sockets
49 * over other UNIX domain sockets requires the implementation of a simple
50 * garbage collector to find and tear down cycles of disconnected sockets.
51 *
52 * TODO:
53 * RDM
54 * distinguish datagram size limits from flow control limits in SEQPACKET
55 * rethink name space problems
56 * need a proper out-of-band
57 */
58
59#include <sys/cdefs.h>
54 * rethink name space problems
55 * need a proper out-of-band
56 */
57
58#include <sys/cdefs.h>
60__FBSDID("$FreeBSD: head/sys/kern/uipc_usrreq.c 262867 2014-03-06 20:24:15Z asomers $");
59__FBSDID("$FreeBSD: head/sys/kern/uipc_usrreq.c 262914 2014-03-07 23:30:48Z asomers $");
61
62#include "opt_ddb.h"
63
64#include <sys/param.h>
65#include <sys/capability.h>
66#include <sys/domain.h>
67#include <sys/fcntl.h>
68#include <sys/malloc.h> /* XXX must be before <sys/file.h> */

--- 715 unchanged lines hidden (view full) ---

784}
785
786static int
787uipc_rcvd(struct socket *so, int flags)
788{
789 struct unpcb *unp, *unp2;
790 struct socket *so2;
791 u_int mbcnt, sbcc;
60
61#include "opt_ddb.h"
62
63#include <sys/param.h>
64#include <sys/capability.h>
65#include <sys/domain.h>
66#include <sys/fcntl.h>
67#include <sys/malloc.h> /* XXX must be before <sys/file.h> */

--- 715 unchanged lines hidden (view full) ---

783}
784
785static int
786uipc_rcvd(struct socket *so, int flags)
787{
788 struct unpcb *unp, *unp2;
789 struct socket *so2;
790 u_int mbcnt, sbcc;
792 u_long newhiwat;
793
794 unp = sotounpcb(so);
795 KASSERT(unp != NULL, ("uipc_rcvd: unp == NULL"));
796
797 if (so->so_type != SOCK_STREAM && so->so_type != SOCK_SEQPACKET)
798 panic("uipc_rcvd socktype %d", so->so_type);
799
800 /*

--- 5 unchanged lines hidden (view full) ---

806 * which is prevented by the lock on unp. We cache values from
807 * so_rcv to avoid holding the so_rcv lock over the entire
808 * transaction on the remote so_snd.
809 */
810 SOCKBUF_LOCK(&so->so_rcv);
811 mbcnt = so->so_rcv.sb_mbcnt;
812 sbcc = so->so_rcv.sb_cc;
813 SOCKBUF_UNLOCK(&so->so_rcv);
791
792 unp = sotounpcb(so);
793 KASSERT(unp != NULL, ("uipc_rcvd: unp == NULL"));
794
795 if (so->so_type != SOCK_STREAM && so->so_type != SOCK_SEQPACKET)
796 panic("uipc_rcvd socktype %d", so->so_type);
797
798 /*

--- 5 unchanged lines hidden (view full) ---

804 * which is prevented by the lock on unp. We cache values from
805 * so_rcv to avoid holding the so_rcv lock over the entire
806 * transaction on the remote so_snd.
807 */
808 SOCKBUF_LOCK(&so->so_rcv);
809 mbcnt = so->so_rcv.sb_mbcnt;
810 sbcc = so->so_rcv.sb_cc;
811 SOCKBUF_UNLOCK(&so->so_rcv);
812 /*
813 * There is a benign race condition at this point. If we're planning to
814 * clear SB_STOP, but uipc_send is called on the connected socket at
815 * this instant, it might add data to the sockbuf and set SB_STOP. Then
816 * we would erroneously clear SB_STOP below, even though the sockbuf is
817 * full. The race is benign because the only ill effect is to allow the
818 * sockbuf to exceed its size limit, and the size limits are not
819 * strictly guaranteed anyway.
820 */
814 UNP_PCB_LOCK(unp);
815 unp2 = unp->unp_conn;
816 if (unp2 == NULL) {
817 UNP_PCB_UNLOCK(unp);
818 return (0);
819 }
820 so2 = unp2->unp_socket;
821 SOCKBUF_LOCK(&so2->so_snd);
821 UNP_PCB_LOCK(unp);
822 unp2 = unp->unp_conn;
823 if (unp2 == NULL) {
824 UNP_PCB_UNLOCK(unp);
825 return (0);
826 }
827 so2 = unp2->unp_socket;
828 SOCKBUF_LOCK(&so2->so_snd);
822 so2->so_snd.sb_mbmax += unp->unp_mbcnt - mbcnt;
823 newhiwat = so2->so_snd.sb_hiwat + unp->unp_cc - sbcc;
824 (void)chgsbsize(so2->so_cred->cr_uidinfo, &so2->so_snd.sb_hiwat,
825 newhiwat, RLIM_INFINITY);
829 if (sbcc < so2->so_snd.sb_hiwat && mbcnt < so2->so_snd.sb_mbmax)
830 so2->so_snd.sb_flags &= ~SB_STOP;
826 sowwakeup_locked(so2);
831 sowwakeup_locked(so2);
827 unp->unp_mbcnt = mbcnt;
828 unp->unp_cc = sbcc;
829 UNP_PCB_UNLOCK(unp);
830 return (0);
831}
832
833static int
834uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
835 struct mbuf *control, struct thread *td)
836{
837 struct unpcb *unp, *unp2;
838 struct socket *so2;
832 UNP_PCB_UNLOCK(unp);
833 return (0);
834}
835
836static int
837uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
838 struct mbuf *control, struct thread *td)
839{
840 struct unpcb *unp, *unp2;
841 struct socket *so2;
839 u_int mbcnt_delta, sbcc;
840 u_int newhiwat;
842 u_int mbcnt, sbcc;
841 int error = 0;
842
843 unp = sotounpcb(so);
844 KASSERT(unp != NULL, ("uipc_send: unp == NULL"));
845
846 if (flags & PRUS_OOB) {
847 error = EOPNOTSUPP;
848 goto release;

--- 137 unchanged lines hidden (view full) ---

986 */
987 if (sbappendaddr_nospacecheck_locked(&so2->so_rcv,
988 from, m, control))
989 control = NULL;
990 break;
991 }
992 }
993
843 int error = 0;
844
845 unp = sotounpcb(so);
846 KASSERT(unp != NULL, ("uipc_send: unp == NULL"));
847
848 if (flags & PRUS_OOB) {
849 error = EOPNOTSUPP;
850 goto release;

--- 137 unchanged lines hidden (view full) ---

988 */
989 if (sbappendaddr_nospacecheck_locked(&so2->so_rcv,
990 from, m, control))
991 control = NULL;
992 break;
993 }
994 }
995
994 /*
995 * XXXRW: While fine for SOCK_STREAM, this conflates maximum
996 * datagram size and back-pressure for SOCK_SEQPACKET, which
997 * can lead to undesired return of EMSGSIZE on send instead
998 * of more desirable blocking.
999 */
1000 mbcnt_delta = so2->so_rcv.sb_mbcnt - unp2->unp_mbcnt;
1001 unp2->unp_mbcnt = so2->so_rcv.sb_mbcnt;
996 mbcnt = so2->so_rcv.sb_mbcnt;
1002 sbcc = so2->so_rcv.sb_cc;
1003 sorwakeup_locked(so2);
1004
997 sbcc = so2->so_rcv.sb_cc;
998 sorwakeup_locked(so2);
999
1000 /*
1001 * The PCB lock on unp2 protects the SB_STOP flag. Without it,
1002 * it would be possible for uipc_rcvd to be called at this
1003 * point, drain the receiving sockbuf, clear SB_STOP, and then
1004 * we would set SB_STOP below. That could lead to an empty
1005 * sockbuf having SB_STOP set
1006 */
1005 SOCKBUF_LOCK(&so->so_snd);
1007 SOCKBUF_LOCK(&so->so_snd);
1006 if ((int)so->so_snd.sb_hiwat >= (int)(sbcc - unp2->unp_cc))
1007 newhiwat = so->so_snd.sb_hiwat - (sbcc - unp2->unp_cc);
1008 else
1009 newhiwat = 0;
1010 (void)chgsbsize(so->so_cred->cr_uidinfo, &so->so_snd.sb_hiwat,
1011 newhiwat, RLIM_INFINITY);
1012 so->so_snd.sb_mbmax -= mbcnt_delta;
1008 if (sbcc >= so->so_snd.sb_hiwat || mbcnt >= so->so_snd.sb_mbmax)
1009 so->so_snd.sb_flags |= SB_STOP;
1013 SOCKBUF_UNLOCK(&so->so_snd);
1010 SOCKBUF_UNLOCK(&so->so_snd);
1014 unp2->unp_cc = sbcc;
1015 UNP_PCB_UNLOCK(unp2);
1016 m = NULL;
1017 break;
1018
1019 default:
1020 panic("uipc_send unknown socktype");
1021 }
1022

--- 21 unchanged lines hidden (view full) ---

1044 if (m != NULL)
1045 m_freem(m);
1046 return (error);
1047}
1048
1049static int
1050uipc_sense(struct socket *so, struct stat *sb)
1051{
1011 UNP_PCB_UNLOCK(unp2);
1012 m = NULL;
1013 break;
1014
1015 default:
1016 panic("uipc_send unknown socktype");
1017 }
1018

--- 21 unchanged lines hidden (view full) ---

1040 if (m != NULL)
1041 m_freem(m);
1042 return (error);
1043}
1044
1045static int
1046uipc_sense(struct socket *so, struct stat *sb)
1047{
1052 struct unpcb *unp, *unp2;
1053 struct socket *so2;
1048 struct unpcb *unp;
1054
1055 unp = sotounpcb(so);
1056 KASSERT(unp != NULL, ("uipc_sense: unp == NULL"));
1057
1058 sb->st_blksize = so->so_snd.sb_hiwat;
1049
1050 unp = sotounpcb(so);
1051 KASSERT(unp != NULL, ("uipc_sense: unp == NULL"));
1052
1053 sb->st_blksize = so->so_snd.sb_hiwat;
1059 UNP_LINK_RLOCK();
1060 UNP_PCB_LOCK(unp);
1054 UNP_PCB_LOCK(unp);
1061 unp2 = unp->unp_conn;
1062 if ((so->so_type == SOCK_STREAM || so->so_type == SOCK_SEQPACKET) &&
1063 unp2 != NULL) {
1064 so2 = unp2->unp_socket;
1065 sb->st_blksize += so2->so_rcv.sb_cc;
1066 }
1067 sb->st_dev = NODEV;
1068 if (unp->unp_ino == 0)
1069 unp->unp_ino = (++unp_ino == 0) ? ++unp_ino : unp_ino;
1070 sb->st_ino = unp->unp_ino;
1071 UNP_PCB_UNLOCK(unp);
1055 sb->st_dev = NODEV;
1056 if (unp->unp_ino == 0)
1057 unp->unp_ino = (++unp_ino == 0) ? ++unp_ino : unp_ino;
1058 sb->st_ino = unp->unp_ino;
1059 UNP_PCB_UNLOCK(unp);
1072 UNP_LINK_RUNLOCK();
1073 return (0);
1074}
1075
1076static int
1077uipc_shutdown(struct socket *so)
1078{
1079 struct unpcb *unp;
1080

--- 1411 unchanged lines hidden (view full) ---

2492 unp->unp_conn);
2493
2494 db_printf("unp_refs:\n");
2495 db_print_unprefs(2, &unp->unp_refs);
2496
2497 /* XXXRW: Would be nice to print the full address, if any. */
2498 db_printf("unp_addr: %p\n", unp->unp_addr);
2499
1060 return (0);
1061}
1062
1063static int
1064uipc_shutdown(struct socket *so)
1065{
1066 struct unpcb *unp;
1067

--- 1411 unchanged lines hidden (view full) ---

2479 unp->unp_conn);
2480
2481 db_printf("unp_refs:\n");
2482 db_print_unprefs(2, &unp->unp_refs);
2483
2484 /* XXXRW: Would be nice to print the full address, if any. */
2485 db_printf("unp_addr: %p\n", unp->unp_addr);
2486
2500 db_printf("unp_cc: %d unp_mbcnt: %d unp_gencnt: %llu\n",
2501 unp->unp_cc, unp->unp_mbcnt,
2487 db_printf("unp_gencnt: %llu\n",
2502 (unsigned long long)unp->unp_gencnt);
2503
2504 db_printf("unp_flags: %x (", unp->unp_flags);
2505 db_print_unpflags(unp->unp_flags);
2506 db_printf(")\n");
2507
2508 db_printf("unp_peercred:\n");
2509 db_print_xucred(2, &unp->unp_peercred);
2510
2511 db_printf("unp_refcount: %u\n", unp->unp_refcount);
2512}
2513#endif
2488 (unsigned long long)unp->unp_gencnt);
2489
2490 db_printf("unp_flags: %x (", unp->unp_flags);
2491 db_print_unpflags(unp->unp_flags);
2492 db_printf(")\n");
2493
2494 db_printf("unp_peercred:\n");
2495 db_print_xucred(2, &unp->unp_peercred);
2496
2497 db_printf("unp_refcount: %u\n", unp->unp_refcount);
2498}
2499#endif