Subject: kern/2352: ident daemon is slow, it should not use /dev/kmem at all
To: None <gnats-bugs@NetBSD.ORG>
From: Tor Egge <tegge@idt.unit.no>
List: netbsd-bugs
Date: 04/29/1996 20:24:12
>Number: 2352
>Category: kern
>Synopsis: ident daemon is slow, it should not use /dev/kmem at all
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Apr 29 14:50:01 1996
>Last-Modified:
>Originator: tegge@idt.unit.no
>Organization:
Norwegian Instistute of Science and Technology
>Release: NetBSD-current
>Environment:
System: NetBSD ikke.idt.unit.no 1.1B NetBSD 1.1B (TEGGE) #13: Tue Apr 23 00:45:57 MET DST 1996 root@ikke.idt.unit.no:/usr/src/sys/arch/i386/compile/TEGGE i386
>Description:
Significant delays in
- WWW client browser contacting nearby servers
- Sendmail to a large mailing list
>How-To-Repeat:
>Fix:
This is just an example of how it can be done. The modified identd
has to run as root, thus the inetd.conf file has to be edited too.
identd should be statically linked, to reduce the startup overhead.
Defining a new ioctl, possible on a new device, may be a better solution.
*** /usr/src/libexec/identd/Makefile.orig Tue Apr 23 01:25:58 1996
--- usr/src/libexec/identd/Makefile Tue Apr 23 01:26:01 1996
***************
*** 4,10 ****
SRCS= config.c identd.c netbsd.c parse.c proxy.c version.c
MAN= identd.8
! LDADD= -lkvm
DPADD= ${LIBKVM}
.include <bsd.prog.mk>
--- 4,10 ----
SRCS= config.c identd.c netbsd.c parse.c proxy.c version.c
MAN= identd.8
! LDADD= -static
DPADD= ${LIBKVM}
.include <bsd.prog.mk>
*** /usr/src/libexec/identd/identd.c.orig Sat Oct 14 02:05:17 1995
--- usr/src/libexec/identd/identd.c Tue Apr 23 01:02:15 1996
***************
*** 177,186 ****
--- 177,188 ----
#else
int status;
#endif
+ int save_errno = errno;
while (wait3(&status, WNOHANG, NULL) > 0)
;
+ errno = save_errno;
#ifndef SIGRETURN_TYPE_IS_VOID
return 0;
#endif
***************
*** 457,462 ****
--- 459,474 ----
if (setuid(set_uid) == -1)
ERROR("main: setuid");
+ if (syslog_flag) {
+ #ifdef LOG_DAEMON
+ openlog("identd", LOG_PID, syslog_facility);
+ #else
+ openlog("identd", LOG_PID);
+ #endif
+ }
+ getpwnam("xyzzy");
+ gethostbyname("xyzzy");
+
/*
** Do some special handling if the "-b" or "-w" flags are used
*/
***************
*** 580,591 ****
*/
if (syslog_flag)
{
- #ifdef LOG_DAEMON
- openlog("identd", LOG_PID, syslog_facility);
- #else
- openlog("identd", LOG_PID);
- #endif
-
syslog(LOG_INFO, "Connection from %s", gethost(&faddr));
}
--- 592,597 ----
*** /usr/src/libexec/identd/netbsd.c.orig Sat Oct 14 02:05:18 1995
--- usr/src/libexec/identd/netbsd.c Tue Apr 23 00:52:16 1996
***************
*** 20,26 ****
#include <signal.h>
#include <syslog.h>
- #include "kvm.h"
#include <sys/types.h>
#include <sys/stat.h>
--- 20,25 ----
***************
*** 67,169 ****
extern void *malloc();
- struct nlist nl[] =
- {
- #define N_FILE 0
- #define N_NFILE 1
- #define N_TCBTABLE 2
-
- { "_filehead" },
- { "_nfiles" },
- { "_tcbtable" },
- { "" }
- };
-
- static kvm_t *kd;
-
- static struct file *xfile;
- static int nfile;
-
- static struct inpcbtable tcbtable;
-
-
int k_open()
{
- char errbuf[_POSIX2_LINE_MAX];
-
- /*
- ** Open the kernel memory device
- */
- if ((kd = kvm_openfiles(path_unix, path_kmem, NULL, O_RDONLY, errbuf)) ==
- NULL)
- ERROR1("main: kvm_open: %s", errbuf);
-
- /*
- ** Extract offsets to the needed variables in the kernel
- */
- if (kvm_nlist(kd, nl) < 0)
- ERROR("main: kvm_nlist");
-
return 0;
}
- /*
- ** Get a piece of kernel memory with error handling.
- ** Returns 1 if call succeeded, else 0 (zero).
- */
- static int getbuf(addr, buf, len, what)
- long addr;
- char *buf;
- int len;
- char *what;
- {
- if (kvm_read(kd, addr, buf, len) < 0)
- {
- if (syslog_flag)
- syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
- addr, len, what);
-
- return 0;
- }
-
- return 1;
- }
-
-
-
- /*
- ** Traverse the inpcb list until a match is found.
- ** Returns NULL if no match.
- */
- static struct socket *
- getlist(tcbtablep, ktcbtablep, faddr, fport, laddr, lport)
- struct inpcbtable *tcbtablep, *ktcbtablep;
- struct in_addr *faddr;
- int fport;
- struct in_addr *laddr;
- int lport;
- {
- struct inpcb *kpcbp, pcb;
-
- if (!tcbtablep)
- return NULL;
-
- for (kpcbp = tcbtablep->inpt_queue.cqh_first;
- kpcbp != (struct inpcb *)ktcbtablep;
- kpcbp = pcb.inp_queue.cqe_next) {
- if (!getbuf((long) kpcbp, &pcb, sizeof(struct inpcb), "tcb"))
- break;
- if (pcb.inp_faddr.s_addr == faddr->s_addr &&
- pcb.inp_laddr.s_addr == laddr->s_addr &&
- pcb.inp_fport == fport &&
- pcb.inp_lport == lport )
- return pcb.inp_socket;
- }
- return NULL;
- }
-
-
/*
** Return the user number for the connection owner
--- 66,77 ----
***************
*** 177,244 ****
{
long addr;
struct socket *sockp;
! int i, mib[2];
struct ucred ucb;
!
! /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
! if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
! return -1;
!
! if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
! return -1;
! {
! size_t siz;
! int rv;
!
! mib[0] = CTL_KERN;
! mib[1] = KERN_FILE;
! if ((rv = sysctl(mib, 2, NULL, &siz, NULL, 0)) == -1)
{
ERROR1("k_getuid: sysctl 1 (%d)", rv);
return -1;
}
! xfile = malloc(siz);
! if (!xfile)
! ERROR1("k_getuid: malloc(%d)", siz);
! if ((rv = sysctl(mib, 2, xfile, &siz, NULL, 0)) == -1)
! {
! ERROR1("k_getuid: sysctl 2 (%d)", rv);
! return -1;
! }
! xfile = (struct file *)((char *)xfile + sizeof(filehead));
! }
!
! /* -------------------- TCP PCB LIST -------------------- */
! if (!getbuf(nl[N_TCBTABLE].n_value, &tcbtable, sizeof(tcbtable), "tcbtable"))
! return -1;
!
! sockp = getlist(&tcbtable, nl[N_TCBTABLE].n_value, faddr, fport, laddr,
! lport);
!
! if (!sockp)
! return -1;
!
! /*
! ** Locate the file descriptor that has the socket in question
! ** open so that we can get the 'ucred' information
! */
! for (i = 0; i < nfile; i++)
! {
! if (xfile[i].f_count == 0)
! continue;
!
! if (xfile[i].f_type == DTYPE_SOCKET &&
! (struct socket *) xfile[i].f_data == sockp)
! {
! if (!getbuf(xfile[i].f_cred, &ucb, sizeof(ucb), "ucb"))
! return -1;
!
! *uid = ucb.cr_uid;
! return 0;
! }
! }
!
! return -1;
}
--- 85,116 ----
{
long addr;
struct socket *sockp;
! int i, mib[4];
struct ucred ucb;
! uid_t myuid = -1;
! size_t uidlen;
! struct sysctl_tcp_ident_args args;
! int rv;
!
! mib[0] = CTL_NET;
! mib[1] = PF_INET;
! mib[2] = IPPROTO_TCP;
! mib[3] = TCPCTL_IDENT;
!
! args.raddr = *faddr;
! args.rport = fport;
! args.laddr = *laddr;
! args.lport = lport;
! uidlen = sizeof(myuid);
!
! if ((rv = sysctl(mib, 4, &myuid, &uidlen, &args,sizeof(args)))== -1)
{
ERROR1("k_getuid: sysctl 1 (%d)", rv);
return -1;
}
!
! *uid = myuid;
! return 0;
}
*** /usr/src/sys/sys/socketvar.h.orig Sat Feb 10 13:34:35 1996
--- usr/src/sys/sys/socketvar.h Tue Apr 23 00:13:27 1996
***************
*** 96,101 ****
--- 96,102 ----
void *so_internal; /* Space for svr4 stream data */
void (*so_upcall) __P((struct socket *so, caddr_t arg, int waitf));
caddr_t so_upcallarg; /* Arg for above */
+ uid_t so_rfc931_uid; /* Answer for RFC931 ident queries */
};
/*
*** /usr/src/sys/netinet/tcp_usrreq.c.orig Wed Feb 14 13:37:03 1996
--- usr/src/sys/netinet/tcp_usrreq.c Tue Apr 23 00:45:50 1996
***************
*** 561,569 ****
case TCPCTL_RFC1323:
return (sysctl_int(oldp, oldlenp, newp, newlen,
&tcp_do_rfc1323));
!
default:
return (ENOPROTOOPT);
}
/* NOTREACHED */
}
--- 561,611 ----
case TCPCTL_RFC1323:
return (sysctl_int(oldp, oldlenp, newp, newlen,
&tcp_do_rfc1323));
! case TCPCTL_IDENT:
! return (tcp_sysctl_ident(oldp,oldlenp,newp,newlen));
default:
return (ENOPROTOOPT);
}
/* NOTREACHED */
+ }
+
+ int
+ tcp_sysctl_ident(oldp,oldlenp,newp,newlen)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ {
+ struct sysctl_tcp_ident_args args;
+ struct socket *sockp;
+ struct inpcb *inb;
+ uid_t uid = -1;
+ int error = 0;
+
+ if (newlen != sizeof(struct sysctl_tcp_ident_args))
+ return EINVAL;
+ if (!newp)
+ return EFAULT;
+ if (*oldlenp != sizeof(uid_t))
+ return ENOMEM;
+ if (!oldp || *oldlenp != sizeof(uid_t))
+ return ENOMEM;
+ if ((error = copyin(newp, &args,newlen)))
+ return error;
+
+ inb = in_pcbhashlookup(&tcbtable,
+ args.raddr,
+ args.rport,
+ args.laddr,
+ args.lport);
+ if (inb) {
+ sockp = inb->inp_socket;
+ if (sockp)
+ uid = sockp->so_rfc931_uid;
+ }
+
+ if ((error = copyout(&uid,oldp,sizeof(uid))))
+ return error;
+
+ return 0;
}
*** /usr/src/sys/netinet/tcp_var.h.orig Wed Feb 14 13:37:03 1996
--- usr/src/sys/netinet/tcp_var.h Tue Apr 23 00:26:44 1996
***************
*** 230,241 ****
*/
/* enable/disable RFC1323 timestamps/scaling */
#define TCPCTL_RFC1323 1
! #define TCPCTL_MAXID 2
#define TCPCTL_NAMES { \
{ 0, 0 }, \
{ "rfc1323", CTLTYPE_INT }, \
}
#ifdef _KERNEL
struct inpcbtable tcbtable; /* head of queue of active tcpcb's */
--- 230,250 ----
*/
/* enable/disable RFC1323 timestamps/scaling */
#define TCPCTL_RFC1323 1
! #define TCPCTL_IDENT 2
! #define TCPCTL_MAXID 3
#define TCPCTL_NAMES { \
{ 0, 0 }, \
{ "rfc1323", CTLTYPE_INT }, \
+ { "ident", CTLTYPE_STRUCT }, \
}
+
+ struct sysctl_tcp_ident_args {
+ struct in_addr raddr;
+ u_int rport;
+ struct in_addr laddr;
+ u_int lport;
+ };
#ifdef _KERNEL
struct inpcbtable tcbtable; /* head of queue of active tcpcb's */
*** /usr/src/sys/kern/uipc_socket.c.orig Sun Feb 4 14:09:47 1996
--- usr/src/sys/kern/uipc_socket.c Tue Apr 23 00:44:52 1996
***************
*** 82,87 ****
--- 82,88 ----
so->so_type = type;
if (p->p_ucred->cr_uid == 0)
so->so_state = SS_PRIV;
+ so->so_rfc931_uid = p->p_cred->p_ruid;
so->so_proto = prp;
error =
(*prp->pr_usrreq)(so, PRU_ATTACH, NULL, (struct mbuf *)(long)proto,
>Audit-Trail:
>Unformatted: