Fixed the change user/group ability.
Log when tinyproxy is using default values rather than specific ones. Cleaned up the command line arguments since tinyproxy now uses a configuration file. Removed the USR1 signal and added the thread creation code.
This commit is contained in:
parent
1efe0265de
commit
9f080da488
532
src/tinyproxy.c
532
src/tinyproxy.c
@ -1,6 +1,6 @@
|
|||||||
/* $Id: tinyproxy.c,v 1.3 2000-03-31 20:08:19 rjkaes Exp $
|
/* $Id: tinyproxy.c,v 1.4 2000-09-12 00:03:53 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* The initialize routine. Basically sets up all the initial stuff (logfile,
|
* The initialise routine. Basically sets up all the initial stuff (logfile,
|
||||||
* listening socket, config options, etc.) and then sits there and loops
|
* listening socket, config options, etc.) and then sits there and loops
|
||||||
* over the new connections until the daemon is closed. Also has additional
|
* over the new connections until the daemon is closed. Also has additional
|
||||||
* functions to handle the "user friendly" aspects of a program (usage,
|
* functions to handle the "user friendly" aspects of a program (usage,
|
||||||
@ -22,148 +22,55 @@
|
|||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <defines.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
/* chris - need this for asynchronous DNS resolution */
|
|
||||||
#include <adns.h>
|
|
||||||
|
|
||||||
adns_state adns;
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "tinyproxy.h"
|
#include "tinyproxy.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "log.h"
|
#include <grp.h>
|
||||||
#include "sock.h"
|
#include <pwd.h>
|
||||||
#include "conns.h"
|
#include <signal.h>
|
||||||
#include "reqs.h"
|
#include <sysexits.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "anonymous.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "anonymous.h"
|
#include "log.h"
|
||||||
|
#include "reqs.h"
|
||||||
|
#include "sock.h"
|
||||||
|
#include "stats.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
void takesig(int sig);
|
void takesig(int sig);
|
||||||
|
|
||||||
|
extern int yyparse(void);
|
||||||
|
extern FILE *yyin;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global Structures
|
* Global Structures
|
||||||
*/
|
*/
|
||||||
struct config_s config = {
|
struct config_s config;
|
||||||
NULL, /* Log file handle */
|
|
||||||
DEFAULT_LOG, /* Logfile name */
|
|
||||||
FALSE, /* Use syslog instead? */
|
|
||||||
DEFAULT_CUTOFFLOAD, /* Cut off load */
|
|
||||||
DEFAULT_PORT, /* Listen on this port */
|
|
||||||
DEFAULT_STATHOST, /* URL of stats host */
|
|
||||||
FALSE, /* Quit? */
|
|
||||||
DEFAULT_USER, /* Name of user to change to */
|
|
||||||
FALSE, /* Run anonymous by default? */
|
|
||||||
NULL, /* String containing the subnet allowed */
|
|
||||||
NULL, /* IP address to listen on */
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
NULL, /* Location of filter file */
|
|
||||||
#endif /* FILTER_ENABLE */
|
|
||||||
FALSE, /* Restrict the log to only errors */
|
|
||||||
#ifdef XTINYPROXY
|
|
||||||
NULL, /* The name of this domain */
|
|
||||||
#endif
|
|
||||||
#ifdef UPSTREAM_PROXY
|
|
||||||
NULL, /* name of the upstream proxy */
|
|
||||||
0, /* port of the upstream proxy */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct stat_s stats;
|
|
||||||
float load = 0.00;
|
float load = 0.00;
|
||||||
|
|
||||||
/*
|
|
||||||
* Dump info to the logfile
|
|
||||||
*/
|
|
||||||
static void dumpdebug(void)
|
|
||||||
{
|
|
||||||
struct conn_s *connptr = connections;
|
|
||||||
long clients = 0, waiting = 0, relaying = 0, closing = 0, finished = 0;
|
|
||||||
|
|
||||||
log("SIGUSR1 received, debug dump follows.");
|
|
||||||
|
|
||||||
while (connptr) {
|
|
||||||
switch (connptr->type) {
|
|
||||||
case NEWCONN:
|
|
||||||
clients++;
|
|
||||||
break;
|
|
||||||
case WAITCONN:
|
|
||||||
waiting++;
|
|
||||||
break;
|
|
||||||
case RELAYCONN:
|
|
||||||
relaying++;
|
|
||||||
break;
|
|
||||||
case CLOSINGCONN:
|
|
||||||
closing++;
|
|
||||||
break;
|
|
||||||
case FINISHCONN:
|
|
||||||
finished++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
connptr = connptr->next;
|
|
||||||
}
|
|
||||||
log("clients: %d, waiting: %d, relaying: %d," \
|
|
||||||
"closing: %d, finished: %d",
|
|
||||||
clients, waiting, relaying, closing, finished);
|
|
||||||
log("total requests handled: %lu", stats.num_reqs);
|
|
||||||
log("total connections handled: %lu", stats.num_cons);
|
|
||||||
log("total sockets listened: %lu", stats.num_listens);
|
|
||||||
log("total sockets opened: %lu", stats.num_opens);
|
|
||||||
log("total bad opens: %lu", stats.num_badcons);
|
|
||||||
log("total bytes tx: %lu", stats.num_tx);
|
|
||||||
log("total bytes rx: %lu", stats.num_rx);
|
|
||||||
log("connections refused due to load: %lu", stats.num_refused);
|
|
||||||
log("garbage collections: %lu", stats.num_garbage);
|
|
||||||
log("idle connections killed: %lu", stats.num_idles);
|
|
||||||
log("end debug dump.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle a signal
|
* Handle a signal
|
||||||
*/
|
*/
|
||||||
void takesig(int sig)
|
void takesig(int sig)
|
||||||
{
|
{
|
||||||
switch (sig) {
|
switch (sig) {
|
||||||
case SIGUSR1:
|
|
||||||
dumpdebug();
|
|
||||||
break;
|
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
if (config.logf)
|
if (config.logf)
|
||||||
ftruncate(fileno(config.logf), 0);
|
ftruncate(fileno(config.logf), 0);
|
||||||
|
|
||||||
log("SIGHUP received, cleaning up...");
|
log(LOG_NOTICE, "SIGHUP received, cleaning up...");
|
||||||
conncoll();
|
|
||||||
garbcoll();
|
|
||||||
|
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
if (config.filter) {
|
if (config.filter) {
|
||||||
filter_destroy();
|
filter_destroy();
|
||||||
filter_init();
|
filter_init();
|
||||||
}
|
}
|
||||||
log("Re-reading filter file.");
|
log(LOG_NOTICE, "Re-reading filter file.");
|
||||||
#endif /* FILTER_ENABLE */
|
#endif /* FILTER_ENABLE */
|
||||||
log("Finished cleaning memory/connections.");
|
log(LOG_NOTICE, "Finished cleaning memory/connections.");
|
||||||
break;
|
break;
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
@ -171,10 +78,7 @@ void takesig(int sig)
|
|||||||
filter_destroy();
|
filter_destroy();
|
||||||
#endif /* FILTER_ENABLE */
|
#endif /* FILTER_ENABLE */
|
||||||
config.quit = TRUE;
|
config.quit = TRUE;
|
||||||
break;
|
log(LOG_INFO, "SIGTERM received.");
|
||||||
case SIGALRM:
|
|
||||||
calcload();
|
|
||||||
alarm(LOAD_RECALCTIMER);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sig != SIGTERM)
|
if (sig != SIGTERM)
|
||||||
@ -183,57 +87,44 @@ void takesig(int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display usage to the user on stderr.
|
* Display the version information for the user.
|
||||||
|
*/
|
||||||
|
static void versiondisp(void)
|
||||||
|
{
|
||||||
|
printf("tinyproxy " VERSION "\n");
|
||||||
|
printf("\
|
||||||
|
Copyright 1998 Steven Young (sdyoung@well.com)\n\
|
||||||
|
Copyright 1998-2000 Robert James Kaes (rjkaes@flarenet.com)\n\
|
||||||
|
Copyright 2000 Chris Lightfoot (chris@ex-parrot.com)\n\
|
||||||
|
\n\
|
||||||
|
This program is free software; you can redistribute it and/or modify it\n\
|
||||||
|
under the terms of the GNU General Public License as published by the Free\n\
|
||||||
|
Software Foundation; either version 2, or (at your option) any later\n\
|
||||||
|
version.\n\
|
||||||
|
\n\
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT\n\
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n\
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n\
|
||||||
|
more details.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display usage to the user.
|
||||||
*/
|
*/
|
||||||
static void usagedisp(void)
|
static void usagedisp(void)
|
||||||
{
|
{
|
||||||
printf("tinyproxy version " VERSION "\n");
|
printf("\
|
||||||
printf("Copyright 1998 Steven Young (sdyoung@well.com)\n");
|
Usage: tinyproxy [options]\n\
|
||||||
printf
|
Options:\n\
|
||||||
("Copyright 1998-1999 Robert James Kaes (rjkaes@flarenet.com)\n\n");
|
-d Operate in DEBUG mode.\n\
|
||||||
printf("Copyright 2000 Chris Lightfoot (chris@ex-parrot.com)\n");
|
-c FILE Use an alternate configuration file.\n\
|
||||||
|
-h Display this usage information.\n\
|
||||||
|
-v Display the version number.\n");
|
||||||
|
|
||||||
printf
|
|
||||||
("This software is licensed under the GNU General Public License (GPL).\n");
|
|
||||||
printf("See the file 'COPYING' included with tinyproxy source.\n\n");
|
|
||||||
|
|
||||||
printf("Compiled with Ian Jackson's adns:\n");
|
|
||||||
printf(" http://www.chiark.greenend.org.uk/~ian/adns/\n\n");
|
|
||||||
|
|
||||||
printf("Usage: tinyproxy [args]\n");
|
|
||||||
printf("Options:\n");
|
|
||||||
printf("\t-a header\tallow 'header' through the anon block\n");
|
|
||||||
printf("\t-d\t\tdo not daemonize\n");
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
printf("\t-f filterfile\tblock sites specified in filterfile\n");
|
|
||||||
#endif /* FILTER_ENABLE */
|
|
||||||
printf("\t-h\t\tdisplay usage\n");
|
|
||||||
printf("\t-i ip_address\tonly listen on this address\n");
|
|
||||||
printf("\t-l logfile\tlog to 'logfile'\n");
|
|
||||||
printf
|
|
||||||
("\t-n ip_address\tallow access from only this subnet. (i.e. 192.168.0.)\n");
|
|
||||||
printf("\t-p port\t\tlisten on 'port'\n");
|
|
||||||
printf("\t-r\t\trestrict the log to only errors\n");
|
|
||||||
printf("\t-s stathost\tset stathost to 'stathost'\n");
|
|
||||||
#ifdef HAVE_SYSLOG_H
|
|
||||||
printf("\t-S\t\tlog using the syslog instead\n");
|
|
||||||
#endif
|
|
||||||
#ifdef UPSTREAM_PROXY
|
|
||||||
printf("\t-t domain:port\tredirect connections to an upstream proxy\n");
|
|
||||||
#endif
|
|
||||||
printf("\t-u user\t\tchange to user after startup. \"\" disables\n");
|
|
||||||
printf("\t-v\t\tdisplay version number\n");
|
|
||||||
printf
|
|
||||||
("\t-w load\t\tstop accepting new connections at 'load'. 0 disables\n");
|
|
||||||
#ifdef XTINYPROXY
|
|
||||||
printf
|
|
||||||
("\t-x domain\tAdd a XTinyproxy header with the peer's IP address\n");
|
|
||||||
#endif
|
|
||||||
/* UPSTREAM_PROXY */
|
|
||||||
|
|
||||||
/* Display the modes compiled into tinyproxy */
|
/* Display the modes compiled into tinyproxy */
|
||||||
printf("\nFeatures Compiled In:\n");
|
printf("\nFeatures Compiled In:\n");
|
||||||
#ifdef XTINYPROXY
|
#ifdef XTINYPROXY_ENABLE
|
||||||
printf(" XTinyproxy Header\n");
|
printf(" XTinyproxy Header\n");
|
||||||
#endif /* XTINYPROXY */
|
#endif /* XTINYPROXY */
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
@ -243,157 +134,59 @@ static void usagedisp(void)
|
|||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
printf(" Debuggin code\n");
|
printf(" Debuggin code\n");
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
#ifdef UPSTREAM_PROXY
|
#ifdef TUNNEL_SUPPORT
|
||||||
printf(" Upstream proxy\n");
|
printf(" TCP Tunneling\n");
|
||||||
#endif /* UPSTREAM_PROXY */
|
#endif /* TUNNEL_SUPPORT */
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int optch;
|
int optch;
|
||||||
flag usage = FALSE, godaemon = TRUE, changeid = FALSE;
|
bool_t godaemon = TRUE;
|
||||||
struct passwd *thisuser = NULL;
|
struct passwd *thisuser = NULL;
|
||||||
|
struct group *thisgroup = NULL;
|
||||||
|
char *conf_file = DEFAULT_CONF_FILE;
|
||||||
|
|
||||||
#ifdef UPSTREAM_PROXY
|
while ((optch = getopt(argc, argv, "c:vdh")) !=
|
||||||
char *upstream_ptr;
|
|
||||||
#endif /* UPSTREAM_PROXY */
|
|
||||||
|
|
||||||
while ((optch = getopt(argc, argv, "vh?dp:l:Sa:w:s:u:n:i:rx:f:t:")) !=
|
|
||||||
EOF) {
|
EOF) {
|
||||||
switch (optch) {
|
switch (optch) {
|
||||||
case 'v':
|
case 'v':
|
||||||
fprintf(stderr, "tinyproxy version " VERSION "\n");
|
versiondisp();
|
||||||
exit(EX_OK);
|
exit(EX_OK);
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
if (!(config.port = atoi(optarg))) {
|
|
||||||
log
|
|
||||||
("bad port on commandline, defaulting to %d",
|
|
||||||
DEFAULT_PORT);
|
|
||||||
config.port = DEFAULT_PORT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
if (!(config.logf_name = xstrdup(optarg))) {
|
|
||||||
log("bad log file, defaulting to %s",
|
|
||||||
DEFAULT_LOG);
|
|
||||||
config.logf_name = DEFAULT_LOG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#ifdef HAVE_SYSLOG_H
|
|
||||||
case 'S': /* Use the syslog function to handle logging */
|
|
||||||
config.syslog = TRUE;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 'd':
|
case 'd':
|
||||||
godaemon = FALSE;
|
godaemon = FALSE;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'c':
|
||||||
sscanf(optarg, "%f", &config.cutoffload);
|
conf_file = strdup(optarg);
|
||||||
break;
|
if (!conf_file) {
|
||||||
case 's':
|
log(LOG_EMERG, "tinyproxy: could not allocate memory");
|
||||||
if (!(config.stathost = xstrdup(optarg))) {
|
|
||||||
log("bad stathost, defaulting to %s",
|
|
||||||
DEFAULT_STATHOST);
|
|
||||||
config.stathost = DEFAULT_STATHOST;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
if (!(config.changeuser = xstrdup(optarg))) {
|
|
||||||
log("bad user name, defaulting to %s",
|
|
||||||
DEFAULT_USER);
|
|
||||||
config.changeuser = DEFAULT_USER;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
config.anonymous = TRUE;
|
|
||||||
anon_insert(optarg);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
if (!(config.subnet = xstrdup(optarg))) {
|
|
||||||
log("tinyproxy: could not allocate memory");
|
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
|
||||||
if (!(config.ipAddr = xstrdup(optarg))) {
|
|
||||||
log("tinyproxy: could not allocate memory");
|
|
||||||
exit(EX_SOFTWARE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
case 'f':
|
|
||||||
if (!(config.filter = xstrdup(optarg))) {
|
|
||||||
log("tinyproxy: could not allocate memory");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif /* FILTER_ENABLE */
|
|
||||||
case 'r':
|
|
||||||
config.restricted = TRUE;
|
|
||||||
break;
|
|
||||||
#ifdef XTINYPROXY
|
|
||||||
case 'x':
|
|
||||||
if (!(config.my_domain = xstrdup(optarg))) {
|
|
||||||
log("tinyproxy: could not allocate memory");
|
|
||||||
exit(EX_SOFTWARE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UPSTREAM_PROXY
|
|
||||||
case 't':
|
|
||||||
if (!(upstream_ptr = strchr(optarg, ':'))) {
|
|
||||||
log("tinyproxy: invalid UPSTREAM declaration");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*upstream_ptr++ = '\0';
|
|
||||||
if (!(config.upstream_name = xstrdup(optarg))) {
|
|
||||||
log("tinyproxy: could not allocate memory");
|
|
||||||
exit(EX_SOFTWARE);
|
|
||||||
}
|
|
||||||
config.upstream_port = atoi(upstream_ptr);
|
|
||||||
#ifndef NDEBUG
|
|
||||||
log("upstream name: %s", config.upstream_name);
|
|
||||||
log("upstream port: %d", config.upstream_port);
|
|
||||||
#endif /* NDEBUG */
|
|
||||||
|
|
||||||
break;
|
|
||||||
#endif /* UPSTREAM_PROXY */
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
usage = TRUE;
|
usagedisp();
|
||||||
break;
|
exit(EX_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usage == TRUE) {
|
|
||||||
usagedisp();
|
|
||||||
exit(EX_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If ANONYMOUS is turned on, make sure that Content-Length is
|
* Read in the settings from the config file.
|
||||||
* in the list of allowed headers, since it is required in a
|
|
||||||
* HTTP/1.0 request. Also add the Content-Type header since it goes
|
|
||||||
* hand in hand with Content-Length.
|
|
||||||
* - rjkaes
|
|
||||||
*/
|
*/
|
||||||
if (config.anonymous) {
|
yyin = fopen(conf_file, "r");
|
||||||
anon_insert("Content-Length:");
|
if (!yyin) {
|
||||||
anon_insert("Content-Type:");
|
log(LOG_ERR, "Could not open %s file", conf_file);
|
||||||
}
|
|
||||||
|
|
||||||
/* chris - Initialise asynchronous DNS */
|
|
||||||
if (adns_init(&adns, 0, 0)) {
|
|
||||||
log("tinyproxy: could not initialise ADNS");
|
|
||||||
exit(EX_SOFTWARE);
|
exit(EX_SOFTWARE);
|
||||||
}
|
}
|
||||||
|
yyparse();
|
||||||
|
|
||||||
/* Open the log file if not using syslog */
|
/* Open the log file if not using syslog */
|
||||||
if (config.syslog == FALSE) {
|
if (config.syslog == FALSE) {
|
||||||
|
if (!config.logf_name) {
|
||||||
|
log(LOG_INFO, "Setting Logfile to \"%s\"", DEFAULT_LOG);
|
||||||
|
config.logf_name = DEFAULT_LOG;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(config.logf = fopen(config.logf_name, "a"))) {
|
if (!(config.logf = fopen(config.logf_name, "a"))) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Unable to open logfile %s for appending!\n",
|
"Unable to open logfile %s for appending!\n",
|
||||||
@ -407,72 +200,129 @@ int main(int argc, char **argv)
|
|||||||
openlog("tinyproxy", LOG_PID, LOG_USER);
|
openlog("tinyproxy", LOG_PID, LOG_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
log(PACKAGE " " VERSION " starting...");
|
log(LOG_INFO, PACKAGE " " VERSION " starting...");
|
||||||
|
|
||||||
if (strlen(config.changeuser)) {
|
/*
|
||||||
if ((getuid() != 0) && (geteuid() != 0)) {
|
* Set the default values if they were not set in the config file.
|
||||||
log
|
*/
|
||||||
("not running as root, therefore not changing uid/gid.");
|
if (config.port == 0) {
|
||||||
} else {
|
log(LOG_INFO, "Setting Port to %u", DEFAULT_PORT);
|
||||||
changeid = TRUE;
|
config.port = DEFAULT_PORT;
|
||||||
if (!(thisuser = getpwnam(config.changeuser))) {
|
|
||||||
log("unable to find user \"%s\"!",
|
|
||||||
config.changeuser);
|
|
||||||
exit(EX_NOUSER);
|
|
||||||
}
|
|
||||||
log("changing to user \"%s\" (%d/%d).",
|
|
||||||
config.changeuser, thisuser->pw_uid,
|
|
||||||
thisuser->pw_gid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef NDEBUG
|
if (!config.stathost) {
|
||||||
|
log(LOG_INFO, "Setting stathost to \"%s\"", DEFAULT_STATHOST);
|
||||||
|
config.stathost = DEFAULT_STATHOST;
|
||||||
|
}
|
||||||
|
if (!config.username) {
|
||||||
|
log(LOG_INFO, "Setting user to \"%s\"", DEFAULT_USER);
|
||||||
|
config.username = DEFAULT_USER;
|
||||||
|
}
|
||||||
|
if (config.idletimeout == 0) {
|
||||||
|
log(LOG_INFO, "Setting idle timeout to %u seconds", MAX_IDLE_TIME);
|
||||||
|
config.idletimeout = MAX_IDLE_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_stats();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If ANONYMOUS is turned on, make sure that Content-Length is
|
||||||
|
* in the list of allowed headers, since it is required in a
|
||||||
|
* HTTP/1.0 request. Also add the Content-Type header since it goes
|
||||||
|
* hand in hand with Content-Length.
|
||||||
|
* - rjkaes
|
||||||
|
*/
|
||||||
|
if (config.anonymous) {
|
||||||
|
anon_insert("Content-Length:");
|
||||||
|
anon_insert("Content-Type:");
|
||||||
|
}
|
||||||
|
|
||||||
if (godaemon == TRUE)
|
if (godaemon == TRUE)
|
||||||
makedaemon();
|
makedaemon();
|
||||||
#else
|
|
||||||
printf("Debugging is enabled, so you can not go daemon.\n");
|
if (config.pidpath) {
|
||||||
#endif
|
pidfile_create(config.pidpath);
|
||||||
|
}
|
||||||
|
|
||||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
|
||||||
fprintf(stderr, "Could not set SIGPIPE\n");
|
log(LOG_EMERG, "Could not set SIGPIPE\n");
|
||||||
exit(EX_OSERR);
|
exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
if (signal(SIGUSR1, takesig) == SIG_ERR) {
|
|
||||||
fprintf(stderr, "Could not set SIGUSR1\n");
|
|
||||||
exit(EX_OSERR);
|
|
||||||
}
|
|
||||||
if (signal(SIGTERM, takesig) == SIG_ERR) {
|
|
||||||
fprintf(stderr, "Could not set SIGTERM\n");
|
|
||||||
exit(EX_OSERR);
|
|
||||||
}
|
|
||||||
if (signal(SIGHUP, takesig) == SIG_ERR) {
|
|
||||||
fprintf(stderr, "Could not set SIGHUP\n");
|
|
||||||
exit(EX_OSERR);
|
|
||||||
}
|
|
||||||
if (signal(SIGALRM, takesig) == SIG_ERR) {
|
|
||||||
fprintf(stderr, "Could not set SIGALRM\n");
|
|
||||||
exit(EX_OSERR);
|
|
||||||
}
|
|
||||||
alarm(LOAD_RECALCTIMER);
|
|
||||||
calcload();
|
|
||||||
|
|
||||||
if (init_listen_sock(config.port) < 0) {
|
|
||||||
log("unable to bind port %d!", config.port);
|
|
||||||
exit(EX_UNAVAILABLE);
|
|
||||||
}
|
|
||||||
if (changeid == TRUE) {
|
|
||||||
setuid(thisuser->pw_uid);
|
|
||||||
setgid(thisuser->pw_gid);
|
|
||||||
}
|
|
||||||
log("now accepting connections.");
|
|
||||||
|
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
if (config.filter)
|
if (config.filter)
|
||||||
filter_init();
|
filter_init();
|
||||||
#endif /* FILTER_ENABLE */
|
#endif /* FILTER_ENABLE */
|
||||||
|
|
||||||
while (config.quit == FALSE) {
|
/*
|
||||||
if (getreqs() < 0)
|
* Start listening on the selected port.
|
||||||
break;
|
*/
|
||||||
|
if (thread_listening_sock(config.port) < 0) {
|
||||||
|
log(LOG_EMERG, "Problem creating listening socket");
|
||||||
|
exit(EX_OSERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch to a different user.
|
||||||
|
*/
|
||||||
|
if (geteuid() == 0) {
|
||||||
|
if (config.group && strlen(config.group) > 0) {
|
||||||
|
thisgroup = getgrnam(config.group);
|
||||||
|
if (!thisgroup) {
|
||||||
|
log(LOG_ERR, "Unable to find group '%s'!", config.group);
|
||||||
|
exit(EX_NOUSER);
|
||||||
|
}
|
||||||
|
if (setgid(thisgroup->gr_gid) < 0) {
|
||||||
|
log(LOG_ERR, "Unable to change to group '%s'", config.group);
|
||||||
|
exit(EX_CANTCREAT);
|
||||||
|
}
|
||||||
|
log(LOG_INFO, "Now running as group %s", config.group);
|
||||||
|
}
|
||||||
|
if (config.username && strlen(config.username) > 0) {
|
||||||
|
thisuser = getpwnam(config.username);
|
||||||
|
if (!thisuser) {
|
||||||
|
log(LOG_ERR, "Unable to find user '%s'!", config.username);
|
||||||
|
exit(EX_NOUSER);
|
||||||
|
}
|
||||||
|
if (setuid(thisuser->pw_uid) < 0) {
|
||||||
|
log(LOG_ERR, "Unable to change to user '%s'", config.username);
|
||||||
|
exit(EX_CANTCREAT);
|
||||||
|
}
|
||||||
|
log(LOG_INFO, "Now running as user %s", config.username);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log(LOG_WARNING, "Not running as root, so not changing UID/GID.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread_pool_create() < 0) {
|
||||||
|
log(LOG_ERR, "Could not create the pool of threads");
|
||||||
|
exit(EX_SOFTWARE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These signals are only for the main thread.
|
||||||
|
*/
|
||||||
|
log(LOG_INFO, "Setting the various signals.");
|
||||||
|
if (signal(SIGTERM, takesig) == SIG_ERR) {
|
||||||
|
log(LOG_EMERG, "Could not set SIGTERM\n");
|
||||||
|
exit(EX_OSERR);
|
||||||
|
}
|
||||||
|
if (signal(SIGHUP, takesig) == SIG_ERR) {
|
||||||
|
log(LOG_EMERG, "Could not set SIGHUP\n");
|
||||||
|
exit(EX_OSERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(LOG_INFO, "Starting main loop. Accepting connections.");
|
||||||
|
thread_main_loop();
|
||||||
|
|
||||||
|
log(LOG_INFO, "Shutting down.");
|
||||||
|
thread_close_sock();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove the PID file.
|
||||||
|
*/
|
||||||
|
if (unlink(config.pidpath) < 0) {
|
||||||
|
log(LOG_WARNING, "Could not remove PID file %s: %s",
|
||||||
|
config.pidpath, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
@ -480,16 +330,10 @@ int main(int argc, char **argv)
|
|||||||
filter_destroy();
|
filter_destroy();
|
||||||
#endif /* FILTER_ENABLE */
|
#endif /* FILTER_ENABLE */
|
||||||
|
|
||||||
log("shutting down.");
|
|
||||||
de_init_listen_sock();
|
|
||||||
|
|
||||||
if (config.syslog == FALSE)
|
if (config.syslog == FALSE)
|
||||||
fclose(config.logf);
|
fclose(config.logf);
|
||||||
else
|
else
|
||||||
closelog();
|
closelog();
|
||||||
|
|
||||||
/* finsih up ADNS */
|
|
||||||
adns_finish(adns);
|
|
||||||
|
|
||||||
exit(EX_OK);
|
exit(EX_OK);
|
||||||
}
|
}
|
||||||
|
104
src/tinyproxy.h
104
src/tinyproxy.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tinyproxy.h,v 1.3 2000-03-31 20:08:19 rjkaes Exp $
|
/* $Id: tinyproxy.h,v 1.4 2000-09-12 00:03:53 rjkaes Exp $
|
||||||
*
|
*
|
||||||
* See 'tinyproxy.c' for a detailed description.
|
* See 'tinyproxy.c' for a detailed description.
|
||||||
*
|
*
|
||||||
@ -16,70 +16,96 @@
|
|||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TINYPROXY_H_
|
#ifndef _TINYPROXY_TINYPROXY_H_
|
||||||
#define _TINYPROXY_H_ 1
|
#define _TINYPROXY_TINYPROXY_H_
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <defines.h>
|
# include "../config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
/*
|
||||||
#include <time.h>
|
* Include standard headers which are used through-out tinyproxy
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
# include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#ifdef HAVE_PTHREAD_H
|
||||||
|
# include <pthread.h>
|
||||||
|
#endif
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "config.h"
|
#ifndef SHUT_RD /* these three Posix.1g names are quite new */
|
||||||
|
# define SHUT_RD 0 /* shutdown for reading */
|
||||||
|
# define SHUT_WR 1 /* shutdown for writing */
|
||||||
|
# define SHUT_RDWR 2 /* shutdown for reading and writing */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Global variables for the main controls of the program */
|
/* Global variables for the main controls of the program */
|
||||||
#define BUFFER (1024 * 2) /* Size of buffer for reading */
|
#define MAXBUFFSIZE (1024 * 48) /* Max size of buffer */
|
||||||
#define MAXLISTEN 128 /* Max number of connections to listen for */
|
#define MAXLISTEN 1024 /* Max number of connections */
|
||||||
|
#define MAX_IDLE_TIME (60 * 10) /* 10 minutes of no activity */
|
||||||
|
|
||||||
/* Make a new type: flag */
|
/* Useful function macros */
|
||||||
typedef char flag;
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
/* Other stuff */
|
/* Make a new type: bool_t */
|
||||||
#define FALSE (0)
|
typedef enum {
|
||||||
#define TRUE (!FALSE)
|
FALSE = 0,
|
||||||
|
TRUE = (!FALSE)
|
||||||
|
} bool_t;
|
||||||
|
|
||||||
struct config_s {
|
struct config_s {
|
||||||
FILE *logf;
|
FILE *logf;
|
||||||
char *logf_name;
|
char *logf_name;
|
||||||
flag syslog;
|
bool_t syslog;
|
||||||
float cutoffload;
|
|
||||||
int port;
|
int port;
|
||||||
char *stathost;
|
char *stathost;
|
||||||
flag quit;
|
bool_t quit;
|
||||||
char *changeuser;
|
char *username;
|
||||||
flag anonymous;
|
char *group;
|
||||||
char *subnet;
|
bool_t anonymous;
|
||||||
char *ipAddr;
|
char *ipAddr;
|
||||||
#ifdef FILTER_ENABLE
|
#ifdef FILTER_ENABLE
|
||||||
char *filter;
|
char *filter;
|
||||||
#endif /* FILTER_ENABLE */
|
#endif /* FILTER_ENABLE */
|
||||||
flag restricted;
|
#ifdef XTINYPROXY_ENABLE
|
||||||
#ifdef XTINYPROXY
|
|
||||||
char *my_domain;
|
char *my_domain;
|
||||||
#endif
|
#endif
|
||||||
#ifdef UPSTREAM_PROXY
|
#ifdef TUNNEL_SUPPORT
|
||||||
char *upstream_name;
|
char *tunnel_name;
|
||||||
int upstream_port;
|
int tunnel_port;
|
||||||
#endif
|
#endif /* TUNNEL_SUPPORT */
|
||||||
|
char *pidpath;
|
||||||
|
unsigned int idletimeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stat_s {
|
struct conn_s {
|
||||||
unsigned long int num_reqs;
|
int client_fd, server_fd;
|
||||||
unsigned long int num_cons;
|
struct buffer_s *cbuffer, *sbuffer;
|
||||||
unsigned long int num_badcons;
|
bool_t simple_req;
|
||||||
unsigned long int num_opens;
|
char *output_message;
|
||||||
unsigned long int num_listens;
|
|
||||||
unsigned long int num_tx;
|
|
||||||
unsigned long int num_rx;
|
|
||||||
unsigned long int num_garbage;
|
|
||||||
unsigned long int num_idles;
|
|
||||||
unsigned long int num_refused;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Global Structures used in the program */
|
/* Global Structures used in the program */
|
||||||
extern struct config_s config;
|
extern struct config_s config;
|
||||||
extern struct stat_s stats;
|
|
||||||
extern float load;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user