Improves and cleanups over inetd(8):
- Teach inetd(8) about kqueue, originally implemented by jmg@[1]. - Use new C99 style function prototypes instead of K&Rs. - Raise WARNS from 2 to 6 Glanced at by: ru MFC After: 2 weeks [1] http://people.freebsd.org/~jmg/inetd.kq.patch, http://people.freebsd.org/~jmg/inetd.kq.html
This commit is contained in:
parent
74bcd9d280
commit
4d115fef9e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=154503
@ -6,7 +6,7 @@ MAN= inetd.8
|
||||
MLINKS= inetd.8 inetd.conf.5
|
||||
SRCS= inetd.c builtins.c
|
||||
|
||||
WARNS?= 2
|
||||
WARNS?= 6
|
||||
CFLAGS+= -DLOGIN_CAP
|
||||
#CFLAGS+= -DSANITY_CHECK
|
||||
|
||||
|
@ -113,6 +113,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
@ -197,6 +199,7 @@ __FBSDID("$FreeBSD$");
|
||||
#ifndef TOOMANY
|
||||
#define TOOMANY 256 /* don't start more than TOOMANY */
|
||||
#endif
|
||||
|
||||
#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */
|
||||
#define RETRYTIME (60*10) /* retry after bind or server fail */
|
||||
#define MAX_MAXCHLD 32767 /* max allowable max children */
|
||||
@ -204,8 +207,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define SIGBLOCK (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM))
|
||||
|
||||
void close_sep(struct servtab *);
|
||||
void flag_signal(int);
|
||||
void flag_config(int);
|
||||
void config(void);
|
||||
int cpmip(const struct servtab *, int);
|
||||
void endconfig(void);
|
||||
@ -215,11 +216,8 @@ struct servtab *getconfigent(void);
|
||||
int matchservent(const char *, const char *, const char *);
|
||||
char *nextline(FILE *);
|
||||
void addchild(struct servtab *, int);
|
||||
void flag_reapchild(int);
|
||||
void reapchild(void);
|
||||
void enable(struct servtab *);
|
||||
void disable(struct servtab *);
|
||||
void flag_retry(int);
|
||||
void retry(void);
|
||||
int setconfig(void);
|
||||
void setup(struct servtab *);
|
||||
@ -230,7 +228,6 @@ void unregisterrpc(register struct servtab *sep);
|
||||
static struct conninfo *search_conn(struct servtab *sep, int ctrl);
|
||||
static int room_conn(struct servtab *sep, struct conninfo *conn);
|
||||
static void addchild_conn(struct conninfo *conn, pid_t pid);
|
||||
static void reapchild_conn(pid_t pid);
|
||||
static void free_conn(struct conninfo *conn);
|
||||
static void resize_conn(struct servtab *sep, int maxperip);
|
||||
static void free_connlist(struct servtab *sep);
|
||||
@ -245,7 +242,7 @@ int wrap_bi = 0;
|
||||
int debug = 0;
|
||||
int dolog = 0;
|
||||
int maxsock; /* highest-numbered descriptor */
|
||||
fd_set allsock;
|
||||
int kqsock;
|
||||
int options;
|
||||
int timingout;
|
||||
int toomany = TOOMANY;
|
||||
@ -261,7 +258,6 @@ int v4bind_ok = 0;
|
||||
struct sockaddr_in6 *bind_sa6;
|
||||
int v6bind_ok = 0;
|
||||
#endif
|
||||
int signalpipe[2];
|
||||
#ifdef SANITY_CHECK
|
||||
int nsock;
|
||||
#endif
|
||||
@ -313,6 +309,7 @@ whichaf(struct request_info *req)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct kevent kqevlist[16];
|
||||
struct servtab *sep;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
@ -336,7 +333,11 @@ main(int argc, char **argv)
|
||||
#define peer4 p_un.peer_un4
|
||||
#define peer6 p_un.peer_un6
|
||||
#define peermax p_un.peer_max
|
||||
int i;
|
||||
int i, j;
|
||||
#ifdef SANITY_CHECK
|
||||
int k;
|
||||
#endif
|
||||
int status;
|
||||
struct addrinfo hints, *res;
|
||||
const char *servname;
|
||||
int error;
|
||||
@ -519,19 +520,21 @@ main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
kqsock = kqueue();
|
||||
if (kqsock < 0)
|
||||
err(EX_OSERR, "ERROR: Cannot allocate kqueue");
|
||||
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaddset(&sa.sa_mask, SIGALRM);
|
||||
sigaddset(&sa.sa_mask, SIGCHLD);
|
||||
sigaddset(&sa.sa_mask, SIGHUP);
|
||||
sa.sa_handler = flag_retry;
|
||||
sigaction(SIGALRM, &sa, &saalrm);
|
||||
config();
|
||||
sa.sa_handler = flag_config;
|
||||
sigaction(SIGHUP, &sa, &sahup);
|
||||
sa.sa_handler = flag_reapchild;
|
||||
sigaction(SIGCHLD, &sa, &sachld);
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGALRM, &sa, &saalrm);
|
||||
WATCH_SIG(SIGALRM, retry);
|
||||
config();
|
||||
sigaction(SIGHUP, &sa, &sahup);
|
||||
WATCH_SIG(SIGHUP, config);
|
||||
sigaction(SIGPIPE, &sa, &sapipe);
|
||||
|
||||
{
|
||||
@ -544,27 +547,8 @@ main(int argc, char **argv)
|
||||
(void)setenv("inetd_dummy", dummy, 1);
|
||||
}
|
||||
|
||||
if (pipe(signalpipe) != 0) {
|
||||
syslog(LOG_ERR, "pipe: %m");
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
if (fcntl(signalpipe[0], F_SETFD, FD_CLOEXEC) < 0 ||
|
||||
fcntl(signalpipe[1], F_SETFD, FD_CLOEXEC) < 0) {
|
||||
syslog(LOG_ERR, "signalpipe: fcntl (F_SETFD, FD_CLOEXEC): %m");
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
FD_SET(signalpipe[0], &allsock);
|
||||
#ifdef SANITY_CHECK
|
||||
nsock++;
|
||||
#endif
|
||||
if (signalpipe[0] > maxsock)
|
||||
maxsock = signalpipe[0];
|
||||
if (signalpipe[1] > maxsock)
|
||||
maxsock = signalpipe[1];
|
||||
|
||||
for (;;) {
|
||||
int n, ctrl;
|
||||
fd_set readable;
|
||||
|
||||
#ifdef SANITY_CHECK
|
||||
if (nsock == 0) {
|
||||
@ -572,46 +556,60 @@ main(int argc, char **argv)
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
#endif
|
||||
readable = allsock;
|
||||
if ((n = select(maxsock + 1, &readable, (fd_set *)0,
|
||||
(fd_set *)0, (struct timeval *)0)) <= 0) {
|
||||
if (n < 0 && errno != EINTR) {
|
||||
syslog(LOG_WARNING, "select: %m");
|
||||
|
||||
if ((n = kevent(kqsock, NULL, 0, kqevlist,
|
||||
sizeof kqevlist / sizeof *kqevlist,
|
||||
(struct timespec *)0)) <= 0) {
|
||||
if (n == -1 && errno != EINTR) {
|
||||
syslog(LOG_WARNING, "kevent: %m");
|
||||
sleep(1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* handle any queued signal flags */
|
||||
if (FD_ISSET(signalpipe[0], &readable)) {
|
||||
int nsig;
|
||||
if (ioctl(signalpipe[0], FIONREAD, &nsig) != 0) {
|
||||
syslog(LOG_ERR, "ioctl: %m");
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
while (--nsig >= 0) {
|
||||
char c;
|
||||
if (read(signalpipe[0], &c, 1) != 1) {
|
||||
syslog(LOG_ERR, "read: %m");
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
if (kqevlist[j].filter == EVFILT_SIGNAL) {
|
||||
/* handle any queued signal flags */
|
||||
if (debug)
|
||||
warnx("handling signal flag %c", c);
|
||||
switch(c) {
|
||||
case 'A': /* sigalrm */
|
||||
retry();
|
||||
break;
|
||||
case 'C': /* sigchld */
|
||||
reapchild();
|
||||
break;
|
||||
case 'H': /* sighup */
|
||||
config();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (sep = servtab; n && sep; sep = sep->se_next)
|
||||
if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) {
|
||||
n--;
|
||||
warnx("calling signalhandler for sig %td",
|
||||
kqevlist[j].ident);
|
||||
((void (*)(void))kqevlist[j].udata)();
|
||||
} else if (kqevlist[j].filter == EVFILT_PROC) {
|
||||
sep = (struct servtab *)kqevlist[j].udata;
|
||||
pid = wait4(kqevlist[j].ident, &status, WNOHANG,
|
||||
(struct rusage *)0);
|
||||
if (debug)
|
||||
warnx("%d reaped, status %#x", pid, status);
|
||||
if (pid == 0) {
|
||||
/* XXX - this could leave a zombie */
|
||||
syslog(LOG_WARNING, "can't reap pid %td",
|
||||
kqevlist[j].ident);
|
||||
continue;
|
||||
}
|
||||
#ifdef SANITY_CHECK
|
||||
for (k = 0; k < sep->se_numchild; k++)
|
||||
if (sep->se_pids[k] == pid)
|
||||
break;
|
||||
if (k != sep->se_numchild)
|
||||
sep->se_pids[k] =
|
||||
sep->se_pids[sep->se_numchild - 1];
|
||||
#endif
|
||||
if (sep->se_maxchild &&
|
||||
sep->se_numchild == sep->se_maxchild)
|
||||
enable(sep);
|
||||
if (status)
|
||||
syslog(LOG_WARNING,
|
||||
"%s[%d]: exit status 0x%x",
|
||||
sep->se_server, pid, status);
|
||||
/* XXX - this should never happen */
|
||||
if (--sep->se_numchild < 0)
|
||||
sep->se_numchild = 0;
|
||||
if (sep->se_free && sep->se_numchild == 0) {
|
||||
freeconfig(sep);
|
||||
free((char *)sep);
|
||||
}
|
||||
} else {
|
||||
sep = (struct servtab *)kqevlist[j].udata;
|
||||
if (debug)
|
||||
warnx("someone wants %s", sep->se_service);
|
||||
dofork = !sep->se_bi || sep->se_bi->bi_fork || ISWRAP(sep);
|
||||
@ -882,21 +880,7 @@ main(int argc, char **argv)
|
||||
if (sep->se_accept && sep->se_socktype == SOCK_STREAM)
|
||||
close(ctrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a signal flag to the signal flag queue for later handling
|
||||
*/
|
||||
|
||||
void
|
||||
flag_signal(int c)
|
||||
{
|
||||
char ch = c;
|
||||
|
||||
if (write(signalpipe[1], &ch, 1) != 1) {
|
||||
syslog(LOG_ERR, "write: %m");
|
||||
_exit(EX_OSERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -908,72 +892,18 @@ flag_signal(int c)
|
||||
void
|
||||
addchild(struct servtab *sep, pid_t pid)
|
||||
{
|
||||
if (sep->se_maxchild <= 0)
|
||||
return;
|
||||
#ifdef SANITY_CHECK
|
||||
if (sep->se_numchild >= sep->se_maxchild) {
|
||||
if (sep->se_maxchild && sep->se_numchild >= sep->se_maxchild) {
|
||||
syslog(LOG_ERR, "%s: %d >= %d",
|
||||
__func__, sep->se_numchild, sep->se_maxchild);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
sep->se_pids[sep->se_numchild] = pid;
|
||||
#endif
|
||||
sep->se_pids[sep->se_numchild++] = pid;
|
||||
if (sep->se_numchild == sep->se_maxchild)
|
||||
sep->se_numchild++;
|
||||
if (sep->se_maxchild && sep->se_numchild == sep->se_maxchild)
|
||||
disable(sep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some child process has exited. See if it's on somebody's list.
|
||||
*/
|
||||
|
||||
void
|
||||
flag_reapchild(int signo __unused)
|
||||
{
|
||||
flag_signal('C');
|
||||
}
|
||||
|
||||
void
|
||||
reapchild(void)
|
||||
{
|
||||
int k, status;
|
||||
pid_t pid;
|
||||
struct servtab *sep;
|
||||
|
||||
for (;;) {
|
||||
pid = wait3(&status, WNOHANG, (struct rusage *)0);
|
||||
if (pid <= 0)
|
||||
break;
|
||||
if (debug)
|
||||
warnx("%d reaped, %s %u", pid,
|
||||
WIFEXITED(status) ? "status" : "signal",
|
||||
WIFEXITED(status) ? WEXITSTATUS(status)
|
||||
: WTERMSIG(status));
|
||||
for (sep = servtab; sep; sep = sep->se_next) {
|
||||
for (k = 0; k < sep->se_numchild; k++)
|
||||
if (sep->se_pids[k] == pid)
|
||||
break;
|
||||
if (k == sep->se_numchild)
|
||||
continue;
|
||||
if (sep->se_numchild == sep->se_maxchild)
|
||||
enable(sep);
|
||||
sep->se_pids[k] = sep->se_pids[--sep->se_numchild];
|
||||
if (WIFSIGNALED(status) || WEXITSTATUS(status))
|
||||
syslog(LOG_WARNING,
|
||||
"%s[%d]: exited, %s %u",
|
||||
sep->se_server, pid,
|
||||
WIFEXITED(status) ? "status" : "signal",
|
||||
WIFEXITED(status) ? WEXITSTATUS(status)
|
||||
: WTERMSIG(status));
|
||||
break;
|
||||
}
|
||||
reapchild_conn(pid);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flag_config(int signo __unused)
|
||||
{
|
||||
flag_signal('H');
|
||||
WATCH_PROC(pid, sep);
|
||||
}
|
||||
|
||||
void
|
||||
@ -990,8 +920,10 @@ config(void)
|
||||
syslog(LOG_ERR, "%s: %m", CONFIG);
|
||||
return;
|
||||
}
|
||||
for (sep = servtab; sep; sep = sep->se_next)
|
||||
|
||||
for (sep = servtab; sep != NULL; sep = sep->se_next)
|
||||
sep->se_checked = 0;
|
||||
|
||||
while ((new = getconfigent())) {
|
||||
if (getpwnam(new->se_user) == NULL) {
|
||||
syslog(LOG_ERR,
|
||||
@ -1037,12 +969,17 @@ config(void)
|
||||
/* copy over outstanding child pids */
|
||||
if (sep->se_maxchild > 0 && new->se_maxchild > 0) {
|
||||
new->se_numchild = sep->se_numchild;
|
||||
/* XXX - this can cause problems */
|
||||
if (new->se_numchild > new->se_maxchild)
|
||||
new->se_numchild = new->se_maxchild;
|
||||
#ifdef SANITY_CHECK
|
||||
memcpy(new->se_pids, sep->se_pids,
|
||||
new->se_numchild * sizeof(*new->se_pids));
|
||||
#endif
|
||||
}
|
||||
#ifdef SANITY_CHECK
|
||||
SWAP(pid_t *, sep->se_pids, new->se_pids);
|
||||
#endif
|
||||
sep->se_maxchild = new->se_maxchild;
|
||||
sep->se_numchild = new->se_numchild;
|
||||
sep->se_maxcpm = new->se_maxcpm;
|
||||
@ -1051,14 +988,11 @@ config(void)
|
||||
sep->se_bi = new->se_bi;
|
||||
/* might need to turn on or off service now */
|
||||
if (sep->se_fd >= 0) {
|
||||
if (sep->se_maxchild > 0
|
||||
&& sep->se_numchild == sep->se_maxchild) {
|
||||
if (FD_ISSET(sep->se_fd, &allsock))
|
||||
disable(sep);
|
||||
} else {
|
||||
if (!FD_ISSET(sep->se_fd, &allsock))
|
||||
enable(sep);
|
||||
}
|
||||
if (sep->se_maxchild
|
||||
&& sep->se_numchild == sep->se_maxchild)
|
||||
disable(sep);
|
||||
else
|
||||
enable(sep);
|
||||
}
|
||||
sep->se_accept = new->se_accept;
|
||||
SWAP(char *, sep->se_user, new->se_user);
|
||||
@ -1178,8 +1112,11 @@ config(void)
|
||||
print_service("FREE", sep);
|
||||
if (sep->se_rpc && sep->se_rpc_prog > 0)
|
||||
unregisterrpc(sep);
|
||||
freeconfig(sep);
|
||||
free(sep);
|
||||
if (sep->se_numchild == 0) {
|
||||
freeconfig(sep);
|
||||
free((char *)sep);
|
||||
} else
|
||||
sep->se_free = 1;
|
||||
}
|
||||
(void) sigsetmask(omask);
|
||||
}
|
||||
@ -1239,12 +1176,6 @@ unregisterrpc(struct servtab *sep)
|
||||
(void) sigsetmask(omask);
|
||||
}
|
||||
|
||||
void
|
||||
flag_retry(int signo __unused)
|
||||
{
|
||||
flag_signal('A');
|
||||
}
|
||||
|
||||
void
|
||||
retry(void)
|
||||
{
|
||||
@ -1279,12 +1210,12 @@ setup(struct servtab *sep)
|
||||
#define turnon(fd, opt) \
|
||||
setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
|
||||
if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
|
||||
turnon(sep->se_fd, SO_DEBUG) < 0)
|
||||
turnon(sep->se_fd, SO_DEBUG) == -1)
|
||||
syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
|
||||
if (turnon(sep->se_fd, SO_REUSEADDR) < 0)
|
||||
if (turnon(sep->se_fd, SO_REUSEADDR) == -1)
|
||||
syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");
|
||||
#ifdef SO_PRIVSTATE
|
||||
if (turnon(sep->se_fd, SO_PRIVSTATE) < 0)
|
||||
if (turnon(sep->se_fd, SO_PRIVSTATE) == -1)
|
||||
syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m");
|
||||
#endif
|
||||
/* tftpd opens a new connection then needs more infos */
|
||||
@ -1292,7 +1223,7 @@ setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
|
||||
(strcmp(sep->se_proto, "udp") == 0) &&
|
||||
(sep->se_accept == 0) &&
|
||||
(setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
|
||||
(char *)&on, sizeof (on)) < 0))
|
||||
(char *)&on, sizeof (on)) == -1))
|
||||
syslog(LOG_ERR, "setsockopt (IPV6_RECVPKTINFO): %m");
|
||||
if (sep->se_family == AF_INET6) {
|
||||
int flag = sep->se_nomapped ? 1 : 0;
|
||||
@ -1397,8 +1328,7 @@ setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
|
||||
|
||||
#ifdef IPSEC
|
||||
void
|
||||
ipsecsetup(sep)
|
||||
struct servtab *sep;
|
||||
ipsecsetup(struct servtab *sep)
|
||||
{
|
||||
char *buf;
|
||||
char *policy_in = NULL;
|
||||
@ -1475,8 +1405,7 @@ void
|
||||
close_sep(struct servtab *sep)
|
||||
{
|
||||
if (sep->se_fd >= 0) {
|
||||
if (FD_ISSET(sep->se_fd, &allsock))
|
||||
disable(sep);
|
||||
disable(sep);
|
||||
(void) close(sep->se_fd);
|
||||
sep->se_fd = -1;
|
||||
}
|
||||
@ -1515,7 +1444,7 @@ enter(struct servtab *cp)
|
||||
long omask;
|
||||
|
||||
sep = (struct servtab *)malloc(sizeof (*sep));
|
||||
if (sep == (struct servtab *)0) {
|
||||
if (sep == NULL) {
|
||||
syslog(LOG_ERR, "malloc: %m");
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
@ -1545,14 +1474,9 @@ enable(struct servtab *sep)
|
||||
"%s: %s: is mux", __func__, sep->se_service);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
if (FD_ISSET(sep->se_fd, &allsock)) {
|
||||
syslog(LOG_ERR,
|
||||
"%s: %s: not off", __func__, sep->se_service);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
nsock++;
|
||||
#endif
|
||||
FD_SET(sep->se_fd, &allsock);
|
||||
WATCH_SOCK(sep->se_fd, sep);
|
||||
if (sep->se_fd > maxsock)
|
||||
maxsock = sep->se_fd;
|
||||
}
|
||||
@ -1574,18 +1498,13 @@ disable(struct servtab *sep)
|
||||
"%s: %s: is mux", __func__, sep->se_service);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
if (!FD_ISSET(sep->se_fd, &allsock)) {
|
||||
syslog(LOG_ERR,
|
||||
"%s: %s: not on", __func__, sep->se_service);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
if (nsock == 0) {
|
||||
syslog(LOG_ERR, "%s: nsock=0", __func__);
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
nsock--;
|
||||
#endif
|
||||
FD_CLR(sep->se_fd, &allsock);
|
||||
UNWATCH_SOCK(sep->se_fd, sep);
|
||||
if (sep->se_fd == maxsock)
|
||||
maxsock--;
|
||||
}
|
||||
@ -1649,12 +1568,10 @@ getconfigent(void)
|
||||
for (p = cp + 2; p && *p && isspace(*p); p++)
|
||||
;
|
||||
if (*p == '\0') {
|
||||
if (policy)
|
||||
free(policy);
|
||||
free(policy);
|
||||
policy = NULL;
|
||||
} else if (ipsec_get_policylen(p) >= 0) {
|
||||
if (policy)
|
||||
free(policy);
|
||||
free(policy);
|
||||
policy = newstr(p);
|
||||
} else {
|
||||
syslog(LOG_ERR,
|
||||
@ -1970,6 +1887,7 @@ getconfigent(void)
|
||||
else
|
||||
sep->se_maxchild = 1;
|
||||
}
|
||||
#ifdef SANITY_CHECK
|
||||
if (sep->se_maxchild > 0) {
|
||||
sep->se_pids = malloc(sep->se_maxchild * sizeof(*sep->se_pids));
|
||||
if (sep->se_pids == NULL) {
|
||||
@ -1977,6 +1895,7 @@ getconfigent(void)
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
argc = 0;
|
||||
for (arg = skip(&cp); cp; arg = skip(&cp))
|
||||
if (argc < MAXARGV) {
|
||||
@ -2002,29 +1921,22 @@ freeconfig(struct servtab *cp)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cp->se_service)
|
||||
free(cp->se_service);
|
||||
if (cp->se_proto)
|
||||
free(cp->se_proto);
|
||||
if (cp->se_user)
|
||||
free(cp->se_user);
|
||||
if (cp->se_group)
|
||||
free(cp->se_group);
|
||||
free(cp->se_service);
|
||||
free(cp->se_proto);
|
||||
free(cp->se_user);
|
||||
free(cp->se_group);
|
||||
#ifdef LOGIN_CAP
|
||||
if (cp->se_class)
|
||||
free(cp->se_class);
|
||||
free(cp->se_class);
|
||||
#endif
|
||||
free(cp->se_server);
|
||||
#ifdef SANITY_CHECK
|
||||
free(cp->se_pids);
|
||||
#endif
|
||||
if (cp->se_server)
|
||||
free(cp->se_server);
|
||||
if (cp->se_pids)
|
||||
free(cp->se_pids);
|
||||
for (i = 0; i < MAXARGV; i++)
|
||||
if (cp->se_argv[i])
|
||||
free(cp->se_argv[i]);
|
||||
free(cp->se_argv[i]);
|
||||
free_connlist(cp);
|
||||
#ifdef IPSEC
|
||||
if (cp->se_policy)
|
||||
free(cp->se_policy);
|
||||
free(cp->se_policy);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2303,8 +2215,7 @@ cpmip(const struct servtab *sep, int ctrl)
|
||||
strcmp(sep->se_service, chBest->ch_Service) != 0) {
|
||||
chBest->ch_Family = sin4->sin_family;
|
||||
chBest->ch_Addr4 = sin4->sin_addr;
|
||||
if (chBest->ch_Service)
|
||||
free(chBest->ch_Service);
|
||||
free(chBest->ch_Service);
|
||||
chBest->ch_Service = strdup(sep->se_service);
|
||||
bzero(chBest->ch_Times, sizeof(chBest->ch_Times));
|
||||
}
|
||||
@ -2317,8 +2228,7 @@ cpmip(const struct servtab *sep, int ctrl)
|
||||
strcmp(sep->se_service, chBest->ch_Service) != 0) {
|
||||
chBest->ch_Family = sin6->sin6_family;
|
||||
chBest->ch_Addr6 = sin6->sin6_addr;
|
||||
if (chBest->ch_Service)
|
||||
free(chBest->ch_Service);
|
||||
free(chBest->ch_Service);
|
||||
chBest->ch_Service = strdup(sep->se_service);
|
||||
bzero(chBest->ch_Times, sizeof(chBest->ch_Times));
|
||||
}
|
||||
@ -2356,6 +2266,25 @@ cpmip(const struct servtab *sep, int ctrl)
|
||||
return(r);
|
||||
}
|
||||
|
||||
void
|
||||
watch(short filter, uintptr_t ident, void *data, u_int fflags, int addrm)
|
||||
{
|
||||
struct kevent kev;
|
||||
int i;
|
||||
|
||||
EV_SET(&kev, ident, filter, addrm? EV_ADD:EV_DELETE,
|
||||
fflags, 0, data);
|
||||
|
||||
i = kevent(kqsock, &kev, 1, NULL, 0, NULL);
|
||||
|
||||
if (i == -1)
|
||||
syslog(LOG_ERR, "kevent failed: %m");
|
||||
|
||||
if (debug) {
|
||||
warnx("kqueue, ident: %td, addrm: %d, ret: %d, data: %p, errno: %s", ident, addrm, i, data, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static struct conninfo *
|
||||
search_conn(struct servtab *sep, int ctrl)
|
||||
{
|
||||
@ -2466,26 +2395,6 @@ addchild_conn(struct conninfo *conn, pid_t pid)
|
||||
conn->co_proc[conn->co_numchild++] = proc;
|
||||
}
|
||||
|
||||
static void
|
||||
reapchild_conn(pid_t pid)
|
||||
{
|
||||
struct procinfo *proc;
|
||||
struct conninfo *conn;
|
||||
int i;
|
||||
|
||||
if ((proc = search_proc(pid, 0)) == NULL)
|
||||
return;
|
||||
if ((conn = proc->pr_conn) == NULL)
|
||||
return;
|
||||
for (i = 0; i < conn->co_numchild; ++i)
|
||||
if (conn->co_proc[i] == proc) {
|
||||
conn->co_proc[i] = conn->co_proc[--conn->co_numchild];
|
||||
break;
|
||||
}
|
||||
free_proc(proc);
|
||||
free_conn(conn);
|
||||
}
|
||||
|
||||
static void
|
||||
resize_conn(struct servtab *sep, int maxpip)
|
||||
{
|
||||
|
@ -74,7 +74,10 @@ struct servtab {
|
||||
int se_maxchild; /* max number of children */
|
||||
int se_maxcpm; /* max connects per IP per minute */
|
||||
int se_numchild; /* current number of children */
|
||||
int se_free; /* free when numchild == 0 */
|
||||
#ifdef SANITY_CHECK
|
||||
pid_t *se_pids; /* array of child pids */
|
||||
#endif
|
||||
char *se_user; /* user name to run as */
|
||||
char *se_group; /* group name to run as */
|
||||
#ifdef LOGIN_CAP
|
||||
@ -145,3 +148,14 @@ struct biltin {
|
||||
int bi_maxchild; /* max number of children, -1=default */
|
||||
bi_fn_t *bi_fn; /* function which performs it */
|
||||
};
|
||||
|
||||
void watch(short, uintptr_t, void *, u_int, int);
|
||||
#define WATCH_SOCK(fd, data) watch(EVFILT_READ, fd, data, 0, 1)
|
||||
#define UNWATCH_SOCK(fd, data) watch(EVFILT_READ, fd, data, 0, 0)
|
||||
#define WATCH_SIG(sig, data) watch(EVFILT_SIGNAL, sig, data, 0, 1)
|
||||
#define UNWATCH_SIG(sig, data) watch(EVFILT_SIGNAL, sig, data, 0, 0)
|
||||
#define WATCH_PROC(proc, data) watch(EVFILT_PROC, proc, data, NOTE_EXIT, 1)
|
||||
#define UNWATCH_PROC(proc, data) watch(EVFILT_PROC, proc, data, NOTE_EXIT, 0)
|
||||
#define WATCH_FD(fd, data) watch(EVFILT_VNODE, fd, data, NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_RENAME, 1)
|
||||
#define UNWATCH_FD(fd, data) watch(EVFILT_VNODE, fd, data, NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_RENAME, 0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user