+++ /dev/null
-/* -*-c-*-
- *
- * $Id: bres.c,v 1.3 1999/07/26 23:27:22 mdw Exp $
- *
- * Background reverse name resolution
- *
- * (c) 1999 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of the `fw' port forwarder.
- *
- * `fw' is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * `fw' is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with `fw'; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: bres.c,v $
- * Revision 1.3 1999/07/26 23:27:22 mdw
- * Change copyright notice.
- *
- * Revision 1.2 1999/07/03 13:56:04 mdw
- * Perform a forward resolution to verify result of reverse lookup.
- *
- * Revision 1.1.1.1 1999/07/01 08:56:23 mdw
- * Initial revision.
- *
- */
-
-/*----- Header files ------------------------------------------------------*/
-
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/wait.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include <mLib/alloc.h>
-#include <mLib/report.h>
-#include <mLib/sel.h>
-#include <mLib/selbuf.h>
-
-#include "bres.h"
-
-/*----- Magic numbers -----------------------------------------------------*/
-
-#define BRES_MAX 5 /* Maximum number of resolvers */
-#define BRES_IDLE 60 /* Lifetime of an idle resolver */
-
-/*----- Static variables --------------------------------------------------*/
-
-static bres_server servers[BRES_MAX]; /* Statically allocated servers */
-
-#define FREE ((bres_server *)&freelist)
-static struct { bres_server *next, *prev; } freelist = { FREE, FREE };
-
-#define QUEUE ((bres_client *)&queue)
-static struct { bres_client *next, *prev; } queue = { QUEUE, QUEUE };
-
-static sel_state *sel;
-
-/*----- Main code ---------------------------------------------------------*/
-
-/* --- @zap@ --- *
- *
- * Arguments: @bres_server *rs@ = pointer to server block
- *
- * Returns: ---
- *
- * Use: Kills a server process, reaps the losing child and makes
- * things generally clean again.
- */
-
-static void zap(bres_server *rs)
-{
- /* --- Close the pipes, kill the child, and reap it --- */
-
- if (rs->kid != -1) {
- selbuf_disable(&rs->b);
- close(rs->fd);
- close(rs->b.reader.fd);
- kill(rs->kid, SIGTERM);
- waitpid(rs->kid, 0, 0);
- rs->kid = -1;
- }
-
- /* --- Move the server to the back of the list --- */
-
- rs->next->prev = rs->prev;
- rs->prev->next = rs->next;
- rs->next = FREE;
- rs->prev = FREE->prev;
- FREE->prev->next = rs;
- FREE->prev = rs;
-}
-
-/* --- @bres_abort@ --- *
- *
- * Arguments: @bres_client *rc@ = pointer to client block
- *
- * Returns: ---
- *
- * Use: Removes a queued job.
- */
-
-void bres_abort(bres_client *rc)
-{
- if (rc->rs) {
- zap(rc->rs);
- rc->rs = 0;
- } else {
- rc->next->prev = rc->prev;
- rc->prev->next = rc->next;
- }
-}
-
-/* --- @child@ --- *
- *
- * Arguments: @int rfd@ = output file descriptor for resolved hostnames
- * @int cfd@ = input file descriptor for raw addresses
- *
- * Returns: Never.
- *
- * Use: Asynchronous name resolving process.
- */
-
-static void child(int rfd, int cfd)
-{
- struct in_addr addr;
- FILE *fp = fdopen(rfd, "w");
-
- {
- int i;
- int maxfd = sysconf(_SC_OPEN_MAX);
-
- for (i = 0; i < maxfd; i++) {
- if (i != rfd && i != cfd)
- close(i);
- }
- }
-
- for (;;) {
- int r = read(cfd, &addr, sizeof(addr));
- struct hostent *h;
- char *p;
-
- if (r <= 0)
- break;
- else if (r != sizeof(addr))
- continue;
-
- h = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
- if (h) {
- char **pp;
-
- p = xstrdup(h->h_name);
- h = gethostbyname(p);
- free(p);
- p = 0;
- if (h) {
- for (pp = h->h_addr_list; *pp; pp++) {
- struct in_addr a;
- memcpy(&a, *pp, sizeof(a));
- if (a.s_addr == addr.s_addr) {
- p = h->h_name;
- break;
- }
- }
- }
- }
-
- if (!p)
- p = inet_ntoa(addr);
- fprintf(fp, "%s\n", p);
- fflush(fp);
- }
- _exit(0);
-}
-
-/* --- @idle@ --- *
- *
- * Arguments: @struct timeval *tv@ = pointer to the current time
- * @void *vp@ = pointer to a server block
- *
- * Returns: ---
- *
- * Use: Kills off a child which has been idle for too long.
- */
-
-static void idle(struct timeval *tv, void *vp)
-{
- bres_server *rs = vp;
- zap(rs);
-}
-
-/* --- @answer@ --- *
- *
- * Arguments: @char *p@ = pointer to string read
- * @void *vp@ = pointer to server block
- *
- * Returns: ---
- *
- * Use: Retrieves an answer from a name resolver process.
- */
-
-static void attach(bres_client */*rc*/);
-
-static void answer(char *p, void *vp)
-{
- bres_server *rs = vp;
- bres_client *rc = rs->rc;
-
- /* --- Report the result to my client --- */
-
- if (rc)
- rc->func(p, rc->p);
- if (!p)
- zap(rs);
- if (!rc)
- return;
-
- /* --- Wrap up the various structures --- */
-
- rs->rc = 0;
- rc->rs = 0;
- rs->next = FREE->next;
- rs->prev = FREE;
- FREE->next->prev = rs;
- FREE->next = rs;
-
- /* --- Tie a timer onto the server block --- */
-
- {
- struct timeval tv;
-
- gettimeofday(&tv, 0);
- tv.tv_sec += BRES_IDLE;
- sel_addtimer(sel, &rs->t, &tv, idle, rs);
- }
-
- /* --- If there are any clients waiting, attach one --- */
-
- if (QUEUE->next != QUEUE) {
- rc = QUEUE->next;
- QUEUE->next = rc->next;
- rc->next->prev = QUEUE;
- attach(rc);
- }
-}
-
-/* --- @start@ --- *
- *
- * Arguments: @bres_server *rs@ = pointer to a server block
- *
- * Returns: Zero if OK, nonzero if something failed.
- *
- * Use: Starts up a child resolver process.
- */
-
-static int start(bres_server *rs)
-{
- int rfd[2], cfd[2];
- pid_t kid;
-
- /* --- Make the pipes --- */
-
- if (pipe(rfd))
- goto fail_0;
- if (pipe(cfd))
- goto fail_1;
-
- /* --- Start up the child process --- */
-
- if ((kid = fork()) < 0)
- goto fail_2;
- if (kid == 0) {
- close(cfd[1]);
- close(rfd[0]);
- child(rfd[1], cfd[0]);
- _exit(1);
- }
-
- /* --- Fix up everything in the server block --- */
-
- close(cfd[0]);
- close(rfd[1]);
- rs->fd = cfd[1];
- selbuf_init(&rs->b, sel, rfd[0], answer, rs);
- rs->kid = kid;
- return (0);
-
- /* --- Fix up after errors --- */
-
-fail_2:
- close(cfd[0]);
- close(cfd[1]);
-fail_1:
- close(rfd[0]);
- close(rfd[1]);
-fail_0:
- return (-1);
-}
-
-/* --- @attach@ --- *
- *
- * Arguments: @bres_client *rc@ = pointer to a client block
- *
- * Returns: ---
- *
- * Use: Attaches a client to a spare server (which is assumed to
- * exist).
- */
-
-static void attach(bres_client *rc)
-{
- bres_server *rs;
- int lose = 0;
-
- /* --- Fix up the server ready for the job --- *
- *
- * If the server has a process, remove its timer. Otherwise, fork off a
- * new resolver process. This is also where I go if I find that the child
- * resolver process has lost while I wasn't looking. Only one attempt at
- * forking is performed.
- */
-
-again:
- rs = FREE->next;
- if (rs->kid != -1)
- sel_rmtimer(&rs->t);
- else {
- if (lose || start(rs))
- goto lost;
- lose = 1;
- }
-
- /* --- Submit the job to the resolver --- */
-
- {
- struct sigaction sa, osa;
- int e;
-
- /* --- Ignore @SIGPIPE@ for now --- *
- *
- * This way I can trap @EPIPE@ and reap a losing child, if there was one.
- */
-
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigaction(SIGPIPE, &sa, &osa);
-
- /* --- Write the new job to the child --- */
-
- e = 0;
- if (write(rs->fd, &rc->addr, sizeof(rc->addr)) < 0)
- e = errno;
- sigaction(SIGPIPE, &osa, 0);
-
- /* --- Sort out various errors --- */
-
- if (e == EPIPE) {
- zap(rs);
- goto again;
- } else if (e)
- goto lost;
- }
-
- /* --- Fiddle with lists so that everything's OK --- */
-
- rs->next->prev = FREE;
- FREE->next = rs->next;
- rs->next = rs->prev = rs;
- rs->rc = rc;
- rc->rs = rs;
- return;
-
-lost:
- rc->func(0, rc->p);
-}
-
-/* --- @bres_resolve@ --- *
- *
- * Arguments: @bres_client *rc@ = pointer to client block
- * @struct in_addr addr@ = address to resolve
- * @void (*func)(const char *host, void *p)@ = handler function
- * @void *p@ = argument for handler function
- *
- * Returns: ---
- *
- * Use: Adds a resolver job to the queue. The job will be processed
- * when there's a spare resolver process to deal with it.
- */
-
-void bres_resolve(bres_client *rc, struct in_addr addr,
- void (*func)(const char */*host*/, void */*p*/), void *p)
-{
- /* --- Fill in the structure --- */
-
- rc->addr = addr;
- rc->func = func;
- rc->p = p;
- rc->rs = 0;
-
- /* --- If there's a free server, plug it in --- */
-
- if (FREE->next == FREE) {
- rc->next = QUEUE;
- rc->prev = QUEUE->prev;
- QUEUE->prev->next = rc;
- QUEUE->prev = rc;
- } else
- attach(rc);
-}
-
-/* --- @bres_init@ --- *
- *
- * Arguments: @sel_state *s@ = pointer to select multiplexor
- *
- * Returns: ---
- *
- * Use: Initializes the background resolver for use.
- */
-
-void bres_init(sel_state *s)
-{
- int i;
-
- sel = s;
- for (i = 0; i < BRES_MAX; i++) {
- servers[i].next = FREE;
- servers[i].prev = FREE->prev;
- servers[i].kid = -1;
- servers[i].rc = 0;
- FREE->prev->next = &servers[i];
- FREE->prev = &servers[i];
- }
-}
-
-/*----- That's all, folks -------------------------------------------------*/
+++ /dev/null
-/* -*-c-*-
- *
- * $Id: bres.h,v 1.2 1999/07/26 23:27:22 mdw Exp $
- *
- * Background reverse name resolution
- *
- * (c) 1999 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of the `fw' port forwarder.
- *
- * `fw' is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * `fw' is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with `fw'; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: bres.h,v $
- * Revision 1.2 1999/07/26 23:27:22 mdw
- * Change copyright notice.
- *
- * Revision 1.1.1.1 1999/07/01 08:56:23 mdw
- * Initial revision.
- *
- */
-
-#ifndef RES_H
-#define RES_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*----- Header files ------------------------------------------------------*/
-
-#include <sys/types.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <mLib/sel.h>
-#include <mLib/selbuf.h>
-
-/*----- Data structures ---------------------------------------------------*/
-
-/* --- Client allocated request block --- */
-
-typedef struct bres_client {
- struct bres_client *next, *prev; /* Queue of waiting resolve jobs */
- struct bres_server *rs; /* Pointer to attached server */
- struct in_addr addr; /* Address to be resolved */
- void (*func)(const char */*host*/, void */*p*/); /* Handler function */
- void *p; /* Argument for handler function */
-} bres_client;
-
-/* --- Server maintained resolver blocks --- */
-
-typedef struct bres_server {
- struct bres_server *next, *prev; /* Doubly-linked list of servers */
- pid_t kid; /* Process id of server process */
- selbuf b; /* Input line-buffer selector */
- sel_timer t; /* Timeout for idle servers */
- int fd; /* File descriptor for writing */
- struct bres_client *rc; /* Pointer to attached client */
-} bres_server;
-
-/*----- Functions provided ------------------------------------------------*/
-
-/* --- @bres_abort@ --- *
- *
- * Arguments: @bres_client *rc@ = pointer to client block
- *
- * Returns: ---
- *
- * Use: Removes a queued job.
- */
-
-extern void bres_abort(bres_client */*rc*/);
-
-/* --- @bres_resolve@ --- *
- *
- * Arguments: @bres_client *rc@ = pointer to client block
- * @struct in_addr addr@ = address to resolve
- * @void (*func)(const char *host, void *p)@ = handler function
- * @void *p@ = argument for handler function
- *
- * Returns: ---
- *
- * Use: Adds a resolver job to the queue. The job will be processed
- * when there's a spare resolver process to deal with it.
- */
-
-extern void bres_resolve(bres_client */*rc*/, struct in_addr /*addr*/,
- void (*/*func*/)(const char */*host*/, void */*p*/),
- void */*p*/);
-
-/* --- @bres_init@ --- *
- *
- * Arguments: @sel_state *s@ = pointer to select multiplexor
- *
- * Returns: ---
- *
- * Use: Initializes the background resolver for use.
- */
-
-extern void bres_init(sel_state */*s*/);
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif
+++ /dev/null
-/* -*-c-*-
- *
- * $Id: ident.c,v 1.2 1999/07/26 23:26:44 mdw Exp $
- *
- * Parse replies from RFC931 servers
- *
- * (c) 1999 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of the `fw' port forwarder.
- *
- * `fw' is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * `fw' is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with `fw'; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: ident.c,v $
- * Revision 1.2 1999/07/26 23:26:44 mdw
- * Change copyright notice.
- *
- * Revision 1.1.1.1 1999/07/01 08:56:23 mdw
- * Initial revision.
- *
- * Revision 1.1.1.1 1999/05/21 22:22:27 mdw
- * Initial import. Code not really finished yet.
- *
- */
-
-/*----- Header files ------------------------------------------------------*/
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ident.h"
-
-/*----- Main code ---------------------------------------------------------*/
-
-/* --- @next@ --- *
- *
- * Arguments: @char **pp@ = address of string pointer
- *
- * Returns: Address of next token.
- *
- * Use: Reads the next token from the result string. Tokens are
- * terminated by whitespace, or `:' or `,' characters. The
- * result string has had `\' escapes removed; it's stored in
- * the same memory as the input string. The actual content
- * of the delimiter doesn't seem to be interesting, so it
- * gets thrown away.
- */
-
-static char *next(char **pp)
-{
- char *p, *q, *r;
-
- /* --- Deal with reads past the end of the string --- */
-
- if (!*pp)
- return ("");
-
- /* --- Initialize various pointers into the string --- */
-
- p = q = r = *pp;
-
- /* --- Skip past any leading whitespace --- */
-
- while (isspace((unsigned char)*p))
- p++;
-
- /* --- Now start work on the string itself --- */
-
- for (;;) {
- if (*p == 0 || *p == ':' || *p == ',' || isspace((unsigned char)*p))
- break;
- else if (*p == '\\') {
- p++;
- if (!*p) {
- *q++ = '\\';
- break;
- }
- }
- *q++ = *p++;
- }
-
- /* --- Tidy up afterwards --- */
-
- while (isspace((unsigned char)*p))
- p++;
- if (*p == 0)
- *pp = 0;
- else if (*p == ':' || *p == ',')
- *pp = p + 1;
- else
- *pp = p;
- *q = 0;
-
- return (r);
-}
-
-/* --- @ident_parse@ --- *
- *
- * Arguments: @char *p@ = pointer to input string from identd
- * @ident *i@ = pointer to output block
- *
- * Returns: ---
- *
- * Use: Parses a result string from an RFC931 (identd) server.
- */
-
-void ident_parse(char *p, ident *i)
-{
- char *q;
-
- /* --- Read the source and destination port numbers --- */
-
- i->sport = atoi(next(&p));
- i->dport = atoi(next(&p));
-
- /* --- Find out what sort of a reply this is --- */
-
- q = next(&p);
- if (strcmp(q, "USERID") == 0) {
- i->type = ident_userid;
- i->u.userid.os = next(&p);
- i->u.userid.user = next(&p);
- } else if (strcmp(q, "ERROR") == 0) {
- i->type = ident_error;
- i->u.error = next(&p);
- } else
- i->type = ident_bad;
-}
-
-/*----- That's all, folks -------------------------------------------------*/
+++ /dev/null
-/* -*-c-*-
- *
- * $Id: ident.h,v 1.2 1999/07/26 23:26:44 mdw Exp $
- *
- * Parse replies from RFC931 servers
- *
- * (c) 1999 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of the `fw' port forwarder.
- *
- * `fw' is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * `fw' is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with `fw'; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: ident.h,v $
- * Revision 1.2 1999/07/26 23:26:44 mdw
- * Change copyright notice.
- *
- * Revision 1.1.1.1 1999/07/01 08:56:23 mdw
- * Initial revision.
- *
- * Revision 1.1.1.1 1999/05/21 22:22:27 mdw
- * Initial import. Code not really finished yet.
- *
- */
-
-#ifndef IDENT_H
-#define IDENT_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*----- Data structures ---------------------------------------------------*/
-
-typedef struct ident {
- unsigned short sport, dport; /* Source and destination ports */
- unsigned type; /* Type of reply from server */
- union {
- struct {
- char *os; /* Operating system name */
- char *user; /* User name */
- } userid;
- char *error; /* Error message from server */
- } u;
-} ident;
-
-enum {
- ident_userid,
- ident_error,
- ident_bad
-};
-
-/*----- Functions provided ------------------------------------------------*/
-
-/* --- @ident_parse@ --- *
- *
- * Arguments: @char *p@ = pointer to input string from identd
- * @ident *i@ = pointer to output block
- *
- * Returns: ---
- *
- * Use: Parses a result string from an RFC931 (identd) server.
- */
-
-extern void ident_parse(char */*p*/, ident */*i*/);
-
-/*----- That's all, folks -------------------------------------------------*/
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif