From owner-svn-src-all@freebsd.org Mon Oct 2 23:29:58 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DE8B6E29E6B; Mon, 2 Oct 2017 23:29:58 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A601B7F746; Mon, 2 Oct 2017 23:29:58 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v92NTvNK000180; Mon, 2 Oct 2017 23:29:57 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v92NTuLF000167; Mon, 2 Oct 2017 23:29:56 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201710022329.v92NTuLF000167@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Mon, 2 Oct 2017 23:29:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r324227 - in head: lib/libprocstat sys/kern sys/netinet6 sys/sys usr.bin/bluetooth/btsockstat usr.bin/netstat usr.bin/sockstat usr.bin/systat X-SVN-Group: head X-SVN-Commit-Author: glebius X-SVN-Commit-Paths: in head: lib/libprocstat sys/kern sys/netinet6 sys/sys usr.bin/bluetooth/btsockstat usr.bin/netstat usr.bin/sockstat usr.bin/systat X-SVN-Commit-Revision: 324227 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Oct 2017 23:29:59 -0000 Author: glebius Date: Mon Oct 2 23:29:56 2017 New Revision: 324227 URL: https://svnweb.freebsd.org/changeset/base/324227 Log: Hide struct socket and struct unpcb from the userland. Violators may define _WANT_SOCKET and _WANT_UNPCB respectively and are not guaranteed for stability of the structures. The violators list is the the usual one: libprocstat(3) and netstat(1) internally and lsof in ports. In struct xunpcb remove the inclusion of kernel structure and add a bunch of spare fields. The xsocket already has socket not included, but add there spares as well. Embed xsockbuf into xsocket. Sort declarations in sys/socketvar.h to separate kernel only from userland available ones. PR: 221820 (exp-run) Deleted: head/sys/sys/sockstate.h Modified: head/lib/libprocstat/libprocstat.c head/sys/kern/uipc_usrreq.c head/sys/netinet6/send.c head/sys/sys/param.h head/sys/sys/sockbuf.h head/sys/sys/socketvar.h head/sys/sys/unpcb.h head/usr.bin/bluetooth/btsockstat/btsockstat.c head/usr.bin/netstat/inet.c head/usr.bin/netstat/netgraph.c head/usr.bin/netstat/unix.c head/usr.bin/sockstat/sockstat.c head/usr.bin/systat/netstat.c Modified: head/lib/libprocstat/libprocstat.c ============================================================================== --- head/lib/libprocstat/libprocstat.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/lib/libprocstat/libprocstat.c Mon Oct 2 23:29:56 2017 (r324227) @@ -48,10 +48,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#define _WANT_SOCKET #include #include #include #include +#define _WANT_UNPCB #include #include #include Modified: head/sys/kern/uipc_usrreq.c ============================================================================== --- head/sys/kern/uipc_usrreq.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/sys/kern/uipc_usrreq.c Mon Oct 2 23:29:56 2017 (r324227) @@ -1646,12 +1646,20 @@ unp_pcblist(SYSCTL_HANDLER_ARGS) if (unp->unp_addr != NULL) bcopy(unp->unp_addr, &xu->xu_addr, unp->unp_addr->sun_len); + else + bzero(&xu->xu_addr, sizeof(xu->xu_addr)); if (unp->unp_conn != NULL && unp->unp_conn->unp_addr != NULL) bcopy(unp->unp_conn->unp_addr, &xu->xu_caddr, unp->unp_conn->unp_addr->sun_len); - bcopy(unp, &xu->xu_unp, sizeof *unp); + else + bzero(&xu->xu_caddr, sizeof(xu->xu_caddr)); + xu->unp_vnode = unp->unp_vnode; + xu->unp_conn = unp->unp_conn; + xu->xu_firstref = LIST_FIRST(&unp->unp_refs); + xu->xu_nextref = LIST_NEXT(unp, unp_reflink); + xu->unp_gencnt = unp->unp_gencnt; sotoxsocket(unp->unp_socket, &xu->xu_socket); UNP_PCB_UNLOCK(unp); error = SYSCTL_OUT(req, xu, sizeof *xu); Modified: head/sys/netinet6/send.c ============================================================================== --- head/sys/netinet6/send.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/sys/netinet6/send.c Mon Oct 2 23:29:56 2017 (r324227) @@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include Modified: head/sys/sys/param.h ============================================================================== --- head/sys/sys/param.h Mon Oct 2 23:23:12 2017 (r324226) +++ head/sys/sys/param.h Mon Oct 2 23:29:56 2017 (r324227) @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1200047 /* Master, propagated to newvers */ +#define __FreeBSD_version 1200048 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, Modified: head/sys/sys/sockbuf.h ============================================================================== --- head/sys/sys/sockbuf.h Mon Oct 2 23:23:12 2017 (r324226) +++ head/sys/sys/sockbuf.h Mon Oct 2 23:29:56 2017 (r324227) @@ -65,18 +65,6 @@ struct socket; struct thread; struct selinfo; -struct xsockbuf { - u_int sb_cc; - u_int sb_hiwat; - u_int sb_mbcnt; - u_int sb_mcnt; - u_int sb_ccnt; - u_int sb_mbmax; - int sb_lowat; - int sb_timeo; - short sb_flags; -}; - /* * Variables for socket buffering. * @@ -174,7 +162,6 @@ struct mbuf * sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff); struct mbuf * sbsndmbuf(struct sockbuf *sb, u_int off, u_int *moff); -void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb); int sbwait(struct sockbuf *sb); int sblock(struct sockbuf *sb, int flags); void sbunlock(struct sockbuf *sb); Modified: head/sys/sys/socketvar.h ============================================================================== --- head/sys/sys/socketvar.h Mon Oct 2 23:23:12 2017 (r324226) +++ head/sys/sys/socketvar.h Mon Oct 2 23:29:56 2017 (r324227) @@ -34,6 +34,12 @@ #ifndef _SYS_SOCKETVAR_H_ #define _SYS_SOCKETVAR_H_ +/* + * Socket generation count type. Also used in xinpcb, xtcpcb, xunpcb. + */ +typedef uint64_t so_gen_t; + +#if defined(_KERNEL) || defined(_WANT_SOCKET) #include /* for TAILQ macros */ #include /* for struct selinfo */ #include @@ -41,7 +47,6 @@ #include #include #include -#include #ifdef _KERNEL #include #include @@ -55,7 +60,6 @@ struct vnet; * handle on protocol and pointer to protocol * private data and error information. */ -typedef uint64_t so_gen_t; typedef int so_upcall_t(struct socket *, void *, int); struct socket; @@ -167,7 +171,40 @@ struct socket { }; }; }; +#endif /* defined(_KERNEL) || defined(_WANT_SOCKET) */ +/* + * Socket state bits. + * + * Historically, this bits were all kept in the so_state field. For + * locking reasons, they are now in multiple fields, as they are + * locked differently. so_state maintains basic socket state protected + * by the socket lock. so_qstate holds information about the socket + * accept queues. Each socket buffer also has a state field holding + * information relevant to that socket buffer (can't send, rcv). Many + * fields will be read without locks to improve performance and avoid + * lock order issues. However, this approach must be used with caution. + */ +#define SS_NOFDREF 0x0001 /* no file table ref any more */ +#define SS_ISCONNECTED 0x0002 /* socket connected to a peer */ +#define SS_ISCONNECTING 0x0004 /* in process of connecting to peer */ +#define SS_ISDISCONNECTING 0x0008 /* in process of disconnecting */ +#define SS_NBIO 0x0100 /* non-blocking ops */ +#define SS_ASYNC 0x0200 /* async i/o notify */ +#define SS_ISCONFIRMING 0x0400 /* deciding to accept connection req */ +#define SS_ISDISCONNECTED 0x2000 /* socket disconnected from peer */ + +/* + * Protocols can mark a socket as SS_PROTOREF to indicate that, following + * pru_detach, they still want the socket to persist, and will free it + * themselves when they are done. Protocols should only ever call sofree() + * following setting this flag in pru_detach(), and never otherwise, as + * sofree() bypasses socket reference counting. + */ +#define SS_PROTOREF 0x4000 /* strong protocol reference */ + +#ifdef _KERNEL + #define SOCK_MTX(so) &(so)->so_lock #define SOCK_LOCK(so) mtx_lock(&(so)->so_lock) #define SOCK_OWNED(so) mtx_owned(&(so)->so_lock) @@ -194,32 +231,6 @@ struct socket { } while (0) /* - * Externalized form of struct socket used by the sysctl(3) interface. - */ -struct xsocket { - size_t xso_len; /* length of this structure */ - struct socket *xso_so; /* makes a convenient handle sometimes */ - short so_type; - short so_options; - short so_linger; - short so_state; - caddr_t so_pcb; /* another convenient handle */ - int xso_protocol; - int xso_family; - u_int so_qlen; - u_int so_incqlen; - u_int so_qlimit; - short so_timeo; - u_short so_error; - pid_t so_pgid; - u_long so_oobmark; - struct xsockbuf so_rcv, so_snd; - uid_t so_uid; /* XXX */ -}; - -#ifdef _KERNEL - -/* * Macros for sockets and socket buffering. */ @@ -422,7 +433,6 @@ int sosend_generic(struct socket *so, struct sockaddr struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *td); int soshutdown(struct socket *so, int how); -void sotoxsocket(struct socket *so, struct xsocket *xso); void soupcall_clear(struct socket *, int); void soupcall_set(struct socket *, int, so_upcall_t, void *); void solisten_upcall_set(struct socket *, so_upcall_t, void *); @@ -431,6 +441,14 @@ void sowakeup_aio(struct socket *so, struct sockbuf *s void solisten_wakeup(struct socket *); int selsocket(struct socket *so, int events, struct timeval *tv, struct thread *td); +void soisconnected(struct socket *so); +void soisconnecting(struct socket *so); +void soisdisconnected(struct socket *so); +void soisdisconnecting(struct socket *so); +void socantrcvmore(struct socket *so); +void socantrcvmore_locked(struct socket *so); +void socantsendmore(struct socket *so); +void socantsendmore_locked(struct socket *so); /* * Accept filter functions (duh). @@ -446,5 +464,59 @@ int accept_filt_generic_mod_event(module_t mod, int ev #endif #endif /* _KERNEL */ + +/* + * Structure to export socket from kernel to utilities, via sysctl(3). + */ +struct xsocket { + size_t xso_len; /* length of this structure */ + union { + void *xso_so; /* kernel address of struct socket */ + int64_t ph_so; + }; + union { + void *so_pcb; /* kernel address of struct inpcb */ + int64_t ph_pcb; + }; + uint64_t so_oobmark; + int64_t so_spare64[8]; + int32_t xso_protocol; + int32_t xso_family; + uint32_t so_qlen; + uint32_t so_incqlen; + uint32_t so_qlimit; + pid_t so_pgid; + uid_t so_uid; + int32_t so_spare32[8]; + int16_t so_type; + int16_t so_options; + int16_t so_linger; + int16_t so_state; + int16_t so_timeo; + uint16_t so_error; + struct xsockbuf { + uint32_t sb_cc; + uint32_t sb_hiwat; + uint32_t sb_mbcnt; + uint32_t sb_mcnt; + uint32_t sb_ccnt; + uint32_t sb_mbmax; + int32_t sb_lowat; + int32_t sb_timeo; + int16_t sb_flags; + } so_rcv, so_snd; +}; + +#ifdef _KERNEL +void sotoxsocket(struct socket *so, struct xsocket *xso); +void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb); +#endif + +/* + * Socket buffer state bits. Exported via libprocstat(3). + */ +#define SBS_CANTSENDMORE 0x0010 /* can't send more data to peer */ +#define SBS_CANTRCVMORE 0x0020 /* can't receive more data from peer */ +#define SBS_RCVATMARK 0x0040 /* at mark on input */ #endif /* !_SYS_SOCKETVAR_H_ */ Modified: head/sys/sys/unpcb.h ============================================================================== --- head/sys/sys/unpcb.h Mon Oct 2 23:23:12 2017 (r324226) +++ head/sys/sys/unpcb.h Mon Oct 2 23:29:56 2017 (r324227) @@ -33,6 +33,9 @@ #ifndef _SYS_UNPCB_H_ #define _SYS_UNPCB_H_ +typedef uint64_t unp_gen_t; + +#if defined(_KERNEL) || defined(_WANT_UNPCB) #include #include @@ -61,7 +64,6 @@ * so that changes in the sockbuf may be computed to modify * back pressure on the sender accordingly. */ -typedef u_quad_t unp_gen_t; LIST_HEAD(unp_head, unpcb); struct unpcb { @@ -74,8 +76,6 @@ struct unpcb { struct unp_head unp_refs; /* referencing socket linked list */ LIST_ENTRY(unpcb) unp_reflink; /* link in unp_refs list */ struct sockaddr_un *unp_addr; /* bound address of socket */ - int reserved1; - int reserved2; unp_gen_t unp_gencnt; /* generation count of this instance */ short unp_flags; /* flags */ short unp_gcflag; /* Garbage collector flags. */ @@ -116,32 +116,50 @@ struct unpcb { #define sotounpcb(so) ((struct unpcb *)((so)->so_pcb)) -/* Hack alert -- this structure depends on . */ +#endif /* _KERNEL || _WANT_UNPCB */ + +/* + * UNPCB structure exported to user-land via sysctl(3). + * + * Fields prefixed with "xu_" are unique to the export structure, and fields + * with "unp_" or other prefixes match corresponding fields of 'struct unpcb'. + * + * Legend: + * (s) - used by userland utilities in src + * (p) - used by utilities in ports + * (3) - is known to be used by third party software not in ports + * (n) - no known usage + * + * Evil hack: declare only if sys/socketvar.h have been included. + */ #ifdef _SYS_SOCKETVAR_H_ struct xunpcb { - size_t xu_len; /* length of this structure */ - struct unpcb *xu_unpp; /* to help netstat, fstat */ - struct unpcb xu_unp; /* our information */ + size_t xu_len; /* length of this structure */ + void *xu_unpp; /* to help netstat, fstat */ + void *unp_vnode; /* (s) */ + void *unp_conn; /* (s) */ + void *xu_firstref; /* (s) */ + void *xu_nextref; /* (s) */ + unp_gen_t unp_gencnt; /* (s) */ + int64_t xu_spare64[8]; + int32_t xu_spare32[8]; union { - struct sockaddr_un xuu_addr; /* our bound address */ + struct sockaddr_un xu_addr; /* our bound address */ char xu_dummy1[256]; - } xu_au; -#define xu_addr xu_au.xuu_addr + }; union { - struct sockaddr_un xuu_caddr; /* their bound address */ + struct sockaddr_un xu_caddr; /* their bound address */ char xu_dummy2[256]; - } xu_cau; -#define xu_caddr xu_cau.xuu_caddr - struct xsocket xu_socket; - u_quad_t xu_alignment_hack; -}; + }; + struct xsocket xu_socket; +} __aligned(8); struct xunpgen { size_t xug_len; u_int xug_count; unp_gen_t xug_gen; so_gen_t xug_sogen; -}; +} __aligned(8);; #endif /* _SYS_SOCKETVAR_H_ */ #endif /* _SYS_UNPCB_H_ */ Modified: head/usr.bin/bluetooth/btsockstat/btsockstat.c ============================================================================== --- head/usr.bin/bluetooth/btsockstat/btsockstat.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/usr.bin/bluetooth/btsockstat/btsockstat.c Mon Oct 2 23:29:56 2017 (r324227) @@ -35,6 +35,7 @@ #include #include #include +#define _WANT_SOCKET #include #include Modified: head/usr.bin/netstat/inet.c ============================================================================== --- head/usr.bin/netstat/inet.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/usr.bin/netstat/inet.c Mon Oct 2 23:29:56 2017 (r324227) @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#define _WANT_SOCKET #include #include @@ -172,7 +173,7 @@ sotoxsocket(struct socket *so, struct xsocket *xso) xso->xso_family = domain.dom_family; xso->so_timeo = so->so_timeo; xso->so_error = so->so_error; - if (SOLISTENING(so)) { + if ((so->so_options & SO_ACCEPTCONN) != 0) { xso->so_qlen = so->sol_qlen; xso->so_incqlen = so->sol_incqlen; xso->so_qlimit = so->sol_qlimit; Modified: head/usr.bin/netstat/netgraph.c ============================================================================== --- head/usr.bin/netstat/netgraph.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/usr.bin/netstat/netgraph.c Mon Oct 2 23:29:56 2017 (r324227) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#define _WANT_SOCKET #include #include #include Modified: head/usr.bin/netstat/unix.c ============================================================================== --- head/usr.bin/netstat/unix.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/usr.bin/netstat/unix.c Mon Oct 2 23:29:56 2017 (r324227) @@ -43,10 +43,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#define _WANT_SOCKET #include #include #include #include +#define _WANT_UNPCB #include #include @@ -100,7 +102,7 @@ static int pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp) { struct unp_head head; - struct unpcb *unp, unp_conn; + struct unpcb *unp, unp0, unp_conn; u_char sun_len; struct socket so; struct xunpgen xug; @@ -150,8 +152,8 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_lon KREAD(head_off, &head, sizeof(head)); LIST_FOREACH(unp, &head, unp_link) { xu.xu_unpp = unp; - KREAD(unp, &xu.xu_unp, sizeof (*unp)); - unp = &xu.xu_unp; + KREAD(unp, &unp0, sizeof (*unp)); + unp = &unp0; if (unp->unp_gencnt > unp_gencnt) continue; @@ -236,7 +238,7 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhe so = &xunp->xu_socket; /* Ignore PCBs which were freed during copyout. */ - if (xunp->xu_unp.unp_gencnt > oxug->xug_gen) + if (xunp->unp_gencnt > oxug->xug_gen) continue; if (*first) { xo_open_list("socket"); @@ -268,7 +270,6 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhe static void unixdomainpr(struct xunpcb *xunp, struct xsocket *so) { - struct unpcb *unp; struct sockaddr_un *sa; static int first = 1; char buf1[33]; @@ -292,11 +293,7 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) }; int fmt = (sizeof(void *) == 8) ? 1 : 0; - unp = &xunp->xu_unp; - if (unp->unp_addr) - sa = &xunp->xu_addr; - else - sa = (struct sockaddr_un *)0; + sa = (xunp->xu_addr.sun_family == AF_UNIX) ? &xunp->xu_addr : NULL; if (first && !Lflag) { xo_emit("{T:Active UNIX domain sockets}\n"); @@ -318,10 +315,9 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) } else { xo_emit(format[fmt], (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc, - so->so_snd.sb_cc, (long)unp->unp_vnode, - (long)unp->unp_conn, - (long)LIST_FIRST(&unp->unp_refs), - (long)LIST_NEXT(unp, unp_reflink)); + so->so_snd.sb_cc, (long)xunp->unp_vnode, + (long)xunp->unp_conn, (long)xunp->xu_firstref, + (long)xunp->xu_nextref); } if (sa) xo_emit(" {:path/%.*s}", Modified: head/usr.bin/sockstat/sockstat.c ============================================================================== --- head/usr.bin/sockstat/sockstat.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/usr.bin/sockstat/sockstat.c Mon Oct 2 23:29:56 2017 (r324227) @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include +#define _WANT_UNPCB #include #include @@ -784,8 +785,8 @@ gather_unix(int proto) warnx("struct xunpcb size mismatch"); goto out; } - if ((xup->xu_unp.unp_conn == NULL && !opt_l) || - (xup->xu_unp.unp_conn != NULL && !opt_c)) + if ((xup->unp_conn == NULL && !opt_l) || + (xup->unp_conn != NULL && !opt_c)) continue; if ((sock = calloc(1, sizeof(*sock))) == NULL) err(1, "malloc()"); @@ -798,11 +799,11 @@ gather_unix(int proto) sock->proto = proto; sock->family = AF_UNIX; sock->protoname = protoname; - if (xup->xu_unp.unp_addr != NULL) + if (xup->xu_addr.sun_family == AF_UNIX) laddr->address = *(struct sockaddr_storage *)(void *)&xup->xu_addr; - else if (xup->xu_unp.unp_conn != NULL) - *(void **)&(faddr->address) = xup->xu_unp.unp_conn; + else if (xup->unp_conn != NULL) + *(void **)&(faddr->address) = xup->unp_conn; laddr->next = NULL; faddr->next = NULL; sock->laddr = laddr; Modified: head/usr.bin/systat/netstat.c ============================================================================== --- head/usr.bin/systat/netstat.c Mon Oct 2 23:23:12 2017 (r324226) +++ head/usr.bin/systat/netstat.c Mon Oct 2 23:29:56 2017 (r324227) @@ -41,6 +41,7 @@ static const char sccsid[] = "@(#)netstat.c 8.1 (Berke #include #include #include +#define _WANT_SOCKET #include #include