Date: Mon, 29 Jul 2002 02:47:08 -0700 (PDT)
From: Don Lewis <dl-freebsd@catspoiler.org>
To: current@FreeBSD.org
Cc: hsu@FreeBSD.org, ume@FreeBSD.org, suz@kame.net
Subject: unbloating {tcp,tcp6,udp,udp6}_getcred()
Message-ID: <200207290947.g6T9l8wr065555@gw.catspoiler.org>
next in thread | raw e-mail | index | archive | help
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 <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/jail.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/ucred.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
#include <netinet/in_pcbgetcred.h>
#ifdef INET6
#include <netinet/ip6.h>
#include <netinet6/in6_pcb.h>
#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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207290947.g6T9l8wr065555>
