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 |