From owner-freebsd-current Mon Jul 29 2:47:25 2002 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AAAC837B400; Mon, 29 Jul 2002 02:47:18 -0700 (PDT) Received: from gw.catspoiler.org (217-ip-163.nccn.net [209.79.217.163]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1681743E4A; Mon, 29 Jul 2002 02:47:18 -0700 (PDT) (envelope-from dl-freebsd@catspoiler.org) Received: from mousie.catspoiler.org (mousie.catspoiler.org [192.168.101.2]) by gw.catspoiler.org (8.12.5/8.12.5) with ESMTP id g6T9l8wr065555; Mon, 29 Jul 2002 02:47:12 -0700 (PDT) (envelope-from dl-freebsd@catspoiler.org) Message-Id: <200207290947.g6T9l8wr065555@gw.catspoiler.org> Date: Mon, 29 Jul 2002 02:47:08 -0700 (PDT) From: Don Lewis Subject: unbloating {tcp,tcp6,udp,udp6}_getcred() To: current@FreeBSD.org Cc: hsu@FreeBSD.org, ume@FreeBSD.org, suz@kame.net MIME-Version: 1.0 Content-Type: TEXT/plain; charset=us-ascii Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG The tcp_getcred(), tcp6_getcred(), udp_getcred(), udp6_getcred() look like a bad example of mostly duplicated code caused by cut and paste programming. By passing a pointer to the inpcbinfo structure as an argument to the sysctl hander it is possible to combine the use a common handler for the TCP and UDP cases, and the IPv4 and IPv6 handlers can use a common back end once the PCB has been looked up. To switch tcp_getcred() to use this new handler, you would make the following change: SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, - CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, - tcp_getcred, "S,xucred", "Get the xucred of a TCP connection"); + CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, &tcbinfo, 0, + in_pcbgetcred_handler, "S,xucred", "Get the xucred of a TCP connection"); The pcblist sysctl handlers look like another case of cut and paste programming ... =======================Cut Here=========================== #include "opt_inet6.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #include #endif /* INET6 */ /* * Convert the socket credential for inp to external format, unlock pcbinfo, * and return the credential info using SYSCTL_OUT(). */ static int in_getcred(struct sysctl_req *req, struct inpcbinfo *pcbinfo, struct inpcb *inp, int s) { struct xucred xuc; int error; if (inp == NULL) { error = ENOENT; goto out; } /* * XXX - It should not be necessary to lock the PCB or * test inp_socket, since inp_socket is static * for the life of the PCB. */ INP_LOCK(inp); if (inp->inp_socket == NULL) { error = ENOENT; goto outlocked; } error = cr_canseesocket(req->td->td_ucred, inp->inp_socket); if (error == 0) cru2x(inp->inp_socket->so_cred, &xuc); outlocked: INP_UNLOCK(inp); out: INP_INFO_RUNLOCK(pcbinfo); splx(s); if (error == 0) error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); return (error); } /* * Socket credential sysctl handler. * The pcbinfo pointer should be passed as arg1. */ int in_pcbgetcred_handler(SYSCTL_HANDLER_ARGS) { struct inpcbinfo *pcbinfo = arg1; struct sockaddr_in addrs[2]; struct inpcb *inp; int error, s; error = suser_cred(req->td->td_ucred, PRISON_ROOT); if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); if (error) return (error); s = splnet(); INP_INFO_RLOCK(pcbinfo); inp = in_pcblookup_hash(pcbinfo, addrs[1].sin_addr, addrs[1].sin_port, addrs[0].sin_addr, addrs[0].sin_port, 0, NULL); return (in_getcred(req, pcbinfo, inp, s)); } #ifdef INET6 int in6_pcbgetcred_handler(SYSCTL_HANDLER_ARGS) { struct inpcbinfo *pcbinfo = arg1; struct sockaddr_in6 addrs[2]; struct inpcb *inp; int error, s, mapped = 0; error = suser_cred(req->td->td_ucred, PRISON_ROOT); if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); if (error) return (error); if (IN6_IS_ADDR_V4MAPPED(&addrs[0].sin6_addr)) { if (IN6_IS_ADDR_V4MAPPED(&addrs[1].sin6_addr)) mapped = 1; else return (EINVAL); } s = splnet(); INP_INFO_RLOCK(pcbinfo); if (mapped == 1) inp = in_pcblookup_hash(pcbinfo, *(struct in_addr *)&addrs[1].sin6_addr.s6_addr[12], addrs[1].sin6_port, *(struct in_addr *)&addrs[0].sin6_addr.s6_addr[12], addrs[0].sin6_port, 0, NULL); else inp = in6_pcblookup_hash(pcbinfo, &addrs[1].sin6_addr, addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port, 0, NULL); return (in_getcred(req, pcbinfo, inp, s)); } #endif =======================Cut Here=========================== To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message