Add proxy list
This commit is contained in:
parent
93e9c156e8
commit
d72ad621e5
@ -72,6 +72,11 @@ The possible keywords and their descriptions are as follows:
|
||||
The maximum number of seconds of inactivity a connection is
|
||||
allowed to have before it is closed by Tinyproxy.
|
||||
|
||||
*DeadTime*::
|
||||
|
||||
The maximum number of seconds of marking a proxy dead i.e. proxy
|
||||
won't be used for a new connections by Tinyproxy during the deadtime.
|
||||
|
||||
*ErrorFile*::
|
||||
|
||||
This parameter controls which HTML file Tinyproxy returns when a
|
||||
@ -153,12 +158,16 @@ The possible keywords and their descriptions are as follows:
|
||||
rules exist:
|
||||
|
||||
* 'upstream type host:port' turns proxy upstream support on generally.
|
||||
host:port can be a list seperated by | e.g. host1:port1|host2:port2.
|
||||
|
||||
* 'upstream type user:pass@host:port' does the same, but uses the
|
||||
supplied credentials for authentication.
|
||||
supplied credentials for authentication. host:port can be a list
|
||||
seperated by | e.g. host1:port1|host2:port2. Same user:pass will be
|
||||
used for the list.
|
||||
|
||||
* 'upstream type host:port "site_spec"' turns on the upstream proxy
|
||||
for the sites matching `site_spec`.
|
||||
for the sites matching `site_spec`. host:port can be a list
|
||||
seperated by | e.g. host1:port1|host2:port2.
|
||||
|
||||
`type` can be one of `http`, `socks4`, `socks5`, `none`.
|
||||
|
||||
@ -173,6 +182,11 @@ The possible keywords and their descriptions are as follows:
|
||||
* '.' matches any host with no domain (in 'empty' domain)
|
||||
* 'IP/bits' matches network/mask
|
||||
* 'IP/mask' matches network/mask
|
||||
* 'regex(<pat>)' matches against basic case senstive regular expression
|
||||
* 'regexe(<pat>)' matches against extended case senstive regular expression
|
||||
* 'regexi(<pat>)' matches against basic case insenstive regular expression
|
||||
* 'regexei(<pat>)' matches against extended case insenstive regular expression
|
||||
* 'regexie(<pat>)' matches against extended case insenstive regular expression
|
||||
|
||||
*MaxClients*::
|
||||
|
||||
|
@ -54,4 +54,3 @@ void base64enc(char *dst, const void* src, size_t count)
|
||||
}
|
||||
*d = 0;
|
||||
}
|
||||
|
||||
|
@ -26,4 +26,3 @@
|
||||
void base64enc (char *dst, const void *src, size_t count);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -37,10 +37,13 @@ ssize_t basicauth_string(const char *user, const char *pass,
|
||||
{
|
||||
char tmp[256 + 2];
|
||||
int l;
|
||||
if (!user || !pass) return -1;
|
||||
if (!user || !pass)
|
||||
return -1;
|
||||
l = snprintf (tmp, sizeof tmp, "%s:%s", user, pass);
|
||||
if (l < 0 || l >= (ssize_t) sizeof tmp) return 0;
|
||||
if (bufsize < (BASE64ENC_BYTES((unsigned)l) + 1)) return 0;
|
||||
if (l < 0 || l >= (ssize_t) sizeof tmp)
|
||||
return 0;
|
||||
if (bufsize < (BASE64ENC_BYTES ((unsigned) l) + 1))
|
||||
return 0;
|
||||
base64enc (buf, tmp, l);
|
||||
return BASE64ENC_BYTES (l);
|
||||
}
|
||||
@ -48,8 +51,7 @@ ssize_t basicauth_string(const char *user, const char *pass,
|
||||
/*
|
||||
* Add entry to the basicauth list
|
||||
*/
|
||||
void basicauth_add (vector_t authlist,
|
||||
const char *user, const char *pass)
|
||||
void basicauth_add (vector_t authlist, const char *user, const char *pass)
|
||||
{
|
||||
char b[BASE64ENC_BYTES ((256 + 2) - 1) + 1];
|
||||
ssize_t ret;
|
||||
@ -71,8 +73,7 @@ void basicauth_add (vector_t authlist,
|
||||
return;
|
||||
}
|
||||
|
||||
log_message (LOG_INFO,
|
||||
"Added basic auth user : %s", user);
|
||||
log_message (LOG_INFO, "Added basic auth user : %s", user);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -87,7 +88,8 @@ int basicauth_check (vector_t authlist, const char *authstring)
|
||||
const char *entry;
|
||||
|
||||
vl = vector_length (authlist);
|
||||
if (vl == -EINVAL) return 0;
|
||||
if (vl == -EINVAL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < vl; i++) {
|
||||
entry = vector_getentry (authlist, i, &el);
|
||||
|
@ -217,7 +217,8 @@ static void child_main (struct child_s *ptr)
|
||||
|
||||
ret = socket_nonblocking (*fd);
|
||||
if (ret != 0) {
|
||||
log_message(LOG_ERR, "Failed to set the listening "
|
||||
log_message (LOG_ERR,
|
||||
"Failed to set the listening "
|
||||
"socket %d to non-blocking: %s",
|
||||
fd, strerror (errno));
|
||||
exit (1);
|
||||
@ -539,7 +540,6 @@ void child_kill_children (int sig)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Listen on the various configured interfaces
|
||||
*/
|
||||
@ -559,9 +559,7 @@ int child_listening_sockets(vector_t listen_addrs, uint16_t port)
|
||||
}
|
||||
}
|
||||
|
||||
if ((listen_addrs == NULL) ||
|
||||
(vector_length(listen_addrs) == 0))
|
||||
{
|
||||
if ((listen_addrs == NULL) || (vector_length (listen_addrs) == 0)) {
|
||||
/*
|
||||
* no Listen directive:
|
||||
* listen on the wildcard address(es)
|
||||
|
130
src/conf.c
130
src/conf.c
@ -80,13 +80,14 @@
|
||||
#define IPV6MASK "(" IPV6 "(/[[:digit:]]+)?)"
|
||||
#define BEGIN "^[[:space:]]*"
|
||||
#define END "[[:space:]]*$"
|
||||
#define PIPE "\\|"
|
||||
|
||||
/*
|
||||
* Limit the maximum number of substring matches to a reasonably high
|
||||
* number. Given the usual structure of the configuration file, sixteen
|
||||
* substring matches should be plenty.
|
||||
*/
|
||||
#define RE_MAX_MATCHES 16
|
||||
#define RE_MAX_MATCHES 50
|
||||
|
||||
/*
|
||||
* All configuration handling functions are REQUIRED to be defined
|
||||
@ -163,6 +164,7 @@ static HANDLE_FUNC (handle_disableviaheader);
|
||||
static HANDLE_FUNC (handle_xtinyproxy);
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
static HANDLE_FUNC (handle_deadtime);
|
||||
static HANDLE_FUNC (handle_upstream);
|
||||
static HANDLE_FUNC (handle_upstream_no);
|
||||
#endif
|
||||
@ -195,12 +197,10 @@ struct {
|
||||
} directives[] = {
|
||||
/* comments */
|
||||
{
|
||||
BEGIN "#", handle_nop, NULL
|
||||
},
|
||||
BEGIN "#", handle_nop, NULL},
|
||||
/* blank lines */
|
||||
{
|
||||
"^[[:space:]]+$", handle_nop, NULL
|
||||
},
|
||||
"^[[:space:]]+$", handle_nop, NULL},
|
||||
/* string arguments */
|
||||
STDCONF ("logfile", STR, handle_logfile),
|
||||
STDCONF ("pidfile", STR, handle_pidfile),
|
||||
@ -222,6 +222,9 @@ struct {
|
||||
STDCONF ("startservers", INT, handle_startservers),
|
||||
STDCONF ("maxrequestsperchild", INT, handle_maxrequestsperchild),
|
||||
STDCONF ("timeout", INT, handle_timeout),
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
STDCONF ("deadtime", INT, handle_deadtime),
|
||||
#endif
|
||||
STDCONF ("connectport", INT, handle_connectport),
|
||||
/* alphanumeric arguments */
|
||||
STDCONF ("user", ALNUM, handle_user),
|
||||
@ -237,7 +240,6 @@ struct {
|
||||
STDCONF ("basicauth", ALNUM WS ALNUM, handle_basicauth),
|
||||
STDCONF ("errorfile", INT WS STR, handle_errorfile),
|
||||
STDCONF ("addheader", STR WS STR, handle_addheader),
|
||||
|
||||
#ifdef FILTER_ENABLE
|
||||
/* filtering */
|
||||
STDCONF ("filter", STR, handle_filter),
|
||||
@ -255,15 +257,14 @@ struct {
|
||||
#endif
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
{
|
||||
BEGIN "(upstream)" WS "(none)" WS STR END, handle_upstream_no, NULL
|
||||
},
|
||||
BEGIN "(upstream)" WS "(none)" WS STR END, handle_upstream_no, NULL},
|
||||
{
|
||||
BEGIN "(upstream)" WS "(http|socks4|socks5)" WS
|
||||
"(" USERNAME /*username*/ ":" PASSWORD /*password*/ "@" ")?"
|
||||
"(" IP "|" ALNUM ")"
|
||||
":" INT "(" WS STR ")?"
|
||||
END, handle_upstream, NULL
|
||||
},
|
||||
"(" USERNAME /*username */ ":" PASSWORD /*password */ "@"
|
||||
")?"
|
||||
"(" IP "|" ALNUM ")" ":" INT "(" "(" PIPE "(" IP
|
||||
"|" ALNUM ")" ":" INT ")+" ")?" "(" WS STR ")?"
|
||||
END, handle_upstream, NULL},
|
||||
#endif
|
||||
/* loglevel */
|
||||
STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
|
||||
@ -272,8 +273,7 @@ struct {
|
||||
|
||||
const unsigned int ndirectives = sizeof (directives) / sizeof (directives[0]);
|
||||
|
||||
static void
|
||||
free_added_headers (vector_t add_headers)
|
||||
static void free_added_headers (vector_t add_headers)
|
||||
{
|
||||
ssize_t i;
|
||||
|
||||
@ -288,7 +288,7 @@ free_added_headers (vector_t add_headers)
|
||||
vector_delete (add_headers);
|
||||
}
|
||||
|
||||
static void free_config (struct config_s *conf)
|
||||
void free_config (struct config_s *conf)
|
||||
{
|
||||
safefree (conf->config_file);
|
||||
safefree (conf->logf_name);
|
||||
@ -327,8 +327,7 @@ static void free_config (struct config_s *conf)
|
||||
*
|
||||
* Returns 0 on success; negative upon failure.
|
||||
*/
|
||||
int
|
||||
config_compile_regex (void)
|
||||
int config_compile_regex (void)
|
||||
{
|
||||
unsigned int i, r;
|
||||
|
||||
@ -356,8 +355,7 @@ config_compile_regex (void)
|
||||
* Frees pre-compiled regular expressions used by the configuration
|
||||
* file. This function is registered to be automatically called at exit.
|
||||
*/
|
||||
static void
|
||||
config_free_regex (void)
|
||||
static void config_free_regex (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -384,7 +382,6 @@ static int check_match (struct config_s *conf, const char *line)
|
||||
unsigned int i;
|
||||
|
||||
assert (ndirectives > 0);
|
||||
|
||||
for (i = 0; i != ndirectives; ++i) {
|
||||
assert (directives[i].cre);
|
||||
if (!regexec
|
||||
@ -486,7 +483,6 @@ static void initialize_with_defaults (struct config_s *conf,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef FILTER_ENABLE
|
||||
if (defaults->filter) {
|
||||
conf->filter = safestrdup (defaults->filter);
|
||||
@ -521,6 +517,10 @@ static void initialize_with_defaults (struct config_s *conf,
|
||||
|
||||
conf->idletimeout = defaults->idletimeout;
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
conf->deadtime = defaults->deadtime;
|
||||
#endif
|
||||
|
||||
if (defaults->bind_address) {
|
||||
conf->bind_address = safestrdup (defaults->bind_address);
|
||||
}
|
||||
@ -589,6 +589,15 @@ int reload_config_file (const char *config_fname, struct config_s *conf,
|
||||
MAX_IDLE_TIME);
|
||||
conf->idletimeout = MAX_IDLE_TIME;
|
||||
}
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
if (conf->deadtime == 0) {
|
||||
log_message (LOG_WARNING, "Invalid dead time setting. "
|
||||
"Only values greater than zero are allowed. "
|
||||
"Therefore setting idle timeout to %u seconds.",
|
||||
MAX_DEAD_TIME);
|
||||
conf->deadtime = MAX_DEAD_TIME;
|
||||
}
|
||||
#endif
|
||||
|
||||
done:
|
||||
return ret;
|
||||
@ -659,8 +668,7 @@ set_bool_arg (unsigned int *var, const char *line, regmatch_t * match)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
get_long_arg (const char *line, regmatch_t * match)
|
||||
static unsigned long get_long_arg (const char *line, regmatch_t * match)
|
||||
{
|
||||
assert (line);
|
||||
assert (match && match->rm_so != -1);
|
||||
@ -668,8 +676,7 @@ get_long_arg (const char *line, regmatch_t * match)
|
||||
return strtoul (line + match->rm_so, NULL, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
set_int_arg (unsigned int *var, const char *line, regmatch_t * match)
|
||||
static int set_int_arg (unsigned int *var, const char *line, regmatch_t * match)
|
||||
{
|
||||
assert (var);
|
||||
assert (line);
|
||||
@ -726,8 +733,7 @@ static HANDLE_FUNC (handle_viaproxyname)
|
||||
if (r)
|
||||
return r;
|
||||
log_message (LOG_INFO,
|
||||
"Setting \"Via\" header to '%s'",
|
||||
conf->via_proxy_name);
|
||||
"Setting \"Via\" header to '%s'", conf->via_proxy_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -739,8 +745,7 @@ static HANDLE_FUNC (handle_disableviaheader)
|
||||
return r;
|
||||
}
|
||||
|
||||
log_message (LOG_INFO,
|
||||
"Disabling transmission of the \"Via\" header.");
|
||||
log_message (LOG_INFO, "Disabling transmission of the \"Via\" header.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -811,15 +816,13 @@ static HANDLE_FUNC (handle_maxclients)
|
||||
|
||||
static HANDLE_FUNC (handle_maxspareservers)
|
||||
{
|
||||
child_configure (CHILD_MAXSPARESERVERS,
|
||||
get_long_arg (line, &match[2]));
|
||||
child_configure (CHILD_MAXSPARESERVERS, get_long_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HANDLE_FUNC (handle_minspareservers)
|
||||
{
|
||||
child_configure (CHILD_MINSPARESERVERS,
|
||||
get_long_arg (line, &match[2]));
|
||||
child_configure (CHILD_MINSPARESERVERS, get_long_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -841,6 +844,13 @@ static HANDLE_FUNC (handle_timeout)
|
||||
return set_int_arg (&conf->idletimeout, line, &match[2]);
|
||||
}
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
static HANDLE_FUNC (handle_deadtime)
|
||||
{
|
||||
return set_int_arg (&conf->deadtime, line, &match[2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static HANDLE_FUNC (handle_connectport)
|
||||
{
|
||||
add_connect_port_allowed (get_long_arg (line, &match[2]),
|
||||
@ -1106,11 +1116,13 @@ static enum proxy_type pt_from_string(const char *s)
|
||||
|
||||
static HANDLE_FUNC (handle_upstream)
|
||||
{
|
||||
char *ip;
|
||||
int port, mi = 2;
|
||||
struct upstream_proxy_list *pltr, *plist;
|
||||
int mi = 2;
|
||||
char *domain = 0, *user = 0, *pass = 0, *tmp;
|
||||
enum proxy_type pt;
|
||||
|
||||
pltr = plist = (upstream_proxy_list_t *)
|
||||
safemalloc (sizeof (upstream_proxy_list_t));
|
||||
tmp = get_string_arg (line, &match[mi]);
|
||||
pt = pt_from_string (tmp);
|
||||
safefree (tmp);
|
||||
@ -1123,24 +1135,54 @@ static HANDLE_FUNC (handle_upstream)
|
||||
if (match[mi].rm_so != -1)
|
||||
pass = get_string_arg (line, &match[mi]);
|
||||
mi++;
|
||||
|
||||
ip = get_string_arg (line, &match[mi]);
|
||||
if (!ip)
|
||||
plist->host = get_string_arg (line, &match[mi]);
|
||||
if (!plist->host)
|
||||
return -1;
|
||||
|
||||
mi += 5;
|
||||
plist->port = (int) get_long_arg (line, &match[mi]);
|
||||
plist->last_failed_connect = (time_t) 0;
|
||||
|
||||
port = (int) get_long_arg (line, &match[mi]);
|
||||
mi += 3;
|
||||
mi += 2;
|
||||
/* if != -1 we have a list of proxy hosts seperated by |. */
|
||||
if (match[mi].rm_so != -1) {
|
||||
/* loop over proxy host list */
|
||||
char *phl, *pptr;
|
||||
|
||||
phl = get_string_arg (line, &match[mi]);
|
||||
if (!phl)
|
||||
return -1;
|
||||
pptr = strtok (phl, "|");
|
||||
while (pptr) {
|
||||
char *cptr;
|
||||
plist->next = (upstream_proxy_list_t *)
|
||||
safemalloc (sizeof (upstream_proxy_list_t));
|
||||
plist = plist->next;
|
||||
cptr = strchr (pptr, ':');
|
||||
*cptr++ = '\0';
|
||||
plist->host = strdup (pptr);
|
||||
plist->port = strtoul (cptr, NULL, 0);
|
||||
plist->last_failed_connect = (time_t) 0;
|
||||
pptr = strtok (NULL, "|");
|
||||
}
|
||||
safefree (phl);
|
||||
}
|
||||
|
||||
mi += 10;
|
||||
if (match[mi].rm_so != -1)
|
||||
domain = get_string_arg (line, &match[mi]);
|
||||
|
||||
upstream_add (ip, port, domain, user, pass, pt, &conf->upstream_list);
|
||||
upstream_add (pltr, domain, user, pass, pt, &conf->upstream_list);
|
||||
|
||||
safefree (user);
|
||||
safefree (pass);
|
||||
safefree (domain);
|
||||
safefree (ip);
|
||||
while (pltr) {
|
||||
struct upstream_proxy_list *tmpp = pltr;
|
||||
pltr = pltr->next;
|
||||
safefree (tmpp->host);
|
||||
safefree (tmpp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1153,7 +1195,7 @@ static HANDLE_FUNC (handle_upstream_no)
|
||||
if (!domain)
|
||||
return -1;
|
||||
|
||||
upstream_add (NULL, 0, domain, 0, 0, PT_NONE, &conf->upstream_list);
|
||||
upstream_add (NULL, domain, 0, 0, PT_NONE, &conf->upstream_list);
|
||||
safefree (domain);
|
||||
|
||||
return 0;
|
||||
|
@ -68,6 +68,9 @@ struct config_s {
|
||||
#endif /* UPSTREAM_SUPPORT */
|
||||
char *pidpath;
|
||||
unsigned int idletimeout;
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
unsigned int deadtime;
|
||||
#endif /* UPSTREAM_SUPPORT */
|
||||
char *bind_address;
|
||||
unsigned int bindsame;
|
||||
|
||||
@ -116,6 +119,8 @@ struct config_s {
|
||||
extern int reload_config_file (const char *config_fname, struct config_s *conf,
|
||||
struct config_s *defaults);
|
||||
|
||||
extern void free_config (struct config_s *conf);
|
||||
|
||||
int config_compile_regex (void);
|
||||
|
||||
#endif
|
||||
|
@ -42,8 +42,7 @@ void makedaemon (void)
|
||||
exit (0);
|
||||
|
||||
if (chdir ("/") != 0) {
|
||||
log_message (LOG_WARNING,
|
||||
"Could not change directory to /");
|
||||
log_message (LOG_WARNING, "Could not change directory to /");
|
||||
}
|
||||
|
||||
umask (0177);
|
||||
|
@ -105,12 +105,10 @@ void filter_init (void)
|
||||
continue;
|
||||
|
||||
if (!p) /* head of list */
|
||||
fl = p =
|
||||
(struct filter_list *)
|
||||
fl = p = (struct filter_list *)
|
||||
safecalloc (1, sizeof (struct filter_list));
|
||||
else { /* next entry */
|
||||
p->next =
|
||||
(struct filter_list *)
|
||||
p->next = (struct filter_list *)
|
||||
safecalloc (1, sizeof (struct filter_list));
|
||||
p = p->next;
|
||||
}
|
||||
|
@ -508,8 +508,7 @@ char *lookup_variable (hashmap_t map, const char *varname)
|
||||
if (hashmap_is_end (map, result_iter))
|
||||
return (NULL);
|
||||
|
||||
if (hashmap_return_entry (map, result_iter,
|
||||
&key, (void **) &data) < 0)
|
||||
if (hashmap_return_entry (map, result_iter, &key, (void **) &data) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (data);
|
||||
|
@ -86,8 +86,7 @@ static char *get_html_file (unsigned int errornum)
|
||||
/*
|
||||
* Send an already-opened file to the client with variable substitution.
|
||||
*/
|
||||
int
|
||||
send_html_file (FILE *infile, struct conn_s *connptr)
|
||||
int send_html_file (FILE * infile, struct conn_s *connptr)
|
||||
{
|
||||
char *inbuf;
|
||||
char *varstart = NULL;
|
||||
@ -105,7 +104,8 @@ send_html_file (FILE *infile, struct conn_s *connptr)
|
||||
if (in_variable) {
|
||||
*p = '\0';
|
||||
varval = (const char *)
|
||||
lookup_variable (connptr->error_variables,
|
||||
lookup_variable
|
||||
(connptr->error_variables,
|
||||
varstart);
|
||||
if (!varval)
|
||||
varval = "(unknown)";
|
||||
@ -160,25 +160,21 @@ int send_http_headers (struct conn_s *connptr, int code, const char *message)
|
||||
const char headers[] =
|
||||
"HTTP/1.0 %d %s\r\n"
|
||||
"Server: %s/%s\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"%s"
|
||||
"Connection: close\r\n" "\r\n";
|
||||
"Content-Type: text/html\r\n" "%s" "Connection: close\r\n" "\r\n";
|
||||
|
||||
const char p_auth_str[] =
|
||||
"Proxy-Authenticate: Basic realm=\""
|
||||
PACKAGE_NAME "\"\r\n";
|
||||
"Proxy-Authenticate: Basic realm=\"" PACKAGE_NAME "\"\r\n";
|
||||
|
||||
const char w_auth_str[] =
|
||||
"WWW-Authenticate: Basic realm=\""
|
||||
PACKAGE_NAME "\"\r\n";
|
||||
"WWW-Authenticate: Basic realm=\"" PACKAGE_NAME "\"\r\n";
|
||||
|
||||
/* according to rfc7235, the 407 error must be accompanied by
|
||||
a Proxy-Authenticate header field. */
|
||||
const char *add = code == 407 ? p_auth_str : (code == 401 ? w_auth_str : "");
|
||||
* a Proxy-Authenticate header field. */
|
||||
const char *add =
|
||||
code == 407 ? p_auth_str : (code == 401 ? w_auth_str : "");
|
||||
|
||||
return (write_message (connptr->client_fd, headers,
|
||||
code, message, PACKAGE, VERSION,
|
||||
add));
|
||||
code, message, PACKAGE, VERSION, add));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -207,12 +203,12 @@ int send_http_error_message (struct conn_s *connptr)
|
||||
|
||||
error_file = get_html_file (connptr->error_number);
|
||||
if (!(infile = fopen (error_file, "r"))) {
|
||||
char *detail = lookup_variable (connptr->error_variables, "detail");
|
||||
return (write_message (connptr->client_fd, fallback_error,
|
||||
connptr->error_number,
|
||||
connptr->error_string,
|
||||
connptr->error_string,
|
||||
detail, PACKAGE, VERSION));
|
||||
char *detail =
|
||||
lookup_variable (connptr->error_variables, "detail");
|
||||
return (write_message
|
||||
(connptr->client_fd, fallback_error,
|
||||
connptr->error_number, connptr->error_string,
|
||||
connptr->error_string, detail, PACKAGE, VERSION));
|
||||
}
|
||||
|
||||
ret = send_html_file (infile, connptr);
|
||||
@ -274,8 +270,7 @@ int add_standard_vars (struct conn_s *connptr)
|
||||
gmtime (&global_time));
|
||||
add_error_variable (connptr, "date", timebuf);
|
||||
|
||||
add_error_variable (connptr, "website",
|
||||
"https://tinyproxy.github.io/");
|
||||
add_error_variable (connptr, "website", "https://tinyproxy.github.io/");
|
||||
add_error_variable (connptr, "version", VERSION);
|
||||
add_error_variable (connptr, "package", PACKAGE);
|
||||
|
||||
|
32
src/main.c
32
src/main.c
@ -54,8 +54,7 @@ unsigned int received_sighup = FALSE; /* boolean */
|
||||
/*
|
||||
* Handle a signal
|
||||
*/
|
||||
static void
|
||||
takesig (int sig)
|
||||
static void takesig (int sig)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
@ -80,8 +79,7 @@ takesig (int sig)
|
||||
/*
|
||||
* Display the version information for the user.
|
||||
*/
|
||||
static void
|
||||
display_version (void)
|
||||
static void display_version (void)
|
||||
{
|
||||
printf ("%s %s\n", PACKAGE, VERSION);
|
||||
}
|
||||
@ -89,8 +87,7 @@ display_version (void)
|
||||
/*
|
||||
* Display usage to the user.
|
||||
*/
|
||||
static void
|
||||
display_usage (void)
|
||||
static void display_usage (void)
|
||||
{
|
||||
int features = 0;
|
||||
|
||||
@ -143,8 +140,7 @@ display_usage (void)
|
||||
"<https://tinyproxy.github.io/>.\n");
|
||||
}
|
||||
|
||||
static int
|
||||
get_id (char *str)
|
||||
static int get_id (char *str)
|
||||
{
|
||||
char *tstr;
|
||||
|
||||
@ -168,8 +164,7 @@ get_id (char *str)
|
||||
*
|
||||
* This function parses command line arguments.
|
||||
**/
|
||||
static void
|
||||
process_cmdline (int argc, char **argv, struct config_s *conf)
|
||||
static void process_cmdline (int argc, char **argv, struct config_s *conf)
|
||||
{
|
||||
int opt;
|
||||
|
||||
@ -215,8 +210,7 @@ process_cmdline (int argc, char **argv, struct config_s *conf)
|
||||
* the config file. This function is typically called during
|
||||
* initialization when the effective user is root.
|
||||
**/
|
||||
static void
|
||||
change_user (const char *program)
|
||||
static void change_user (const char *program)
|
||||
{
|
||||
if (config.group && strlen (config.group) > 0) {
|
||||
int gid = get_id (config.group);
|
||||
@ -240,7 +234,6 @@ change_user (const char *program)
|
||||
program, config.group);
|
||||
exit (EX_NOPERM);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SETGROUPS
|
||||
/* Drop all supplementary groups, otherwise these are inherited from the calling process */
|
||||
if (setgroups (0, NULL) < 0) {
|
||||
@ -300,6 +293,9 @@ static void initialize_config_defaults (struct config_s *conf)
|
||||
conf->errorpages = NULL;
|
||||
conf->stathost = safestrdup (TINYPROXY_STATHOST);
|
||||
conf->idletimeout = MAX_IDLE_TIME;
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
conf->deadtime = MAX_DEAD_TIME;
|
||||
#endif
|
||||
conf->logf_name = NULL;
|
||||
conf->pidpath = NULL;
|
||||
}
|
||||
@ -326,8 +322,7 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* Only allow u+rw bits. This may be required for some versions
|
||||
* of glibc so that mkstemp() doesn't make us vulnerable.
|
||||
@ -344,8 +339,7 @@ main (int argc, char **argv)
|
||||
process_cmdline (argc, argv, &config_defaults);
|
||||
|
||||
if (reload_config_file (config_defaults.config_file,
|
||||
&config,
|
||||
&config_defaults)) {
|
||||
&config, &config_defaults)) {
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
|
||||
@ -373,7 +367,6 @@ main (int argc, char **argv)
|
||||
argv[0]);
|
||||
exit (EX_OSERR);
|
||||
}
|
||||
|
||||
#ifdef FILTER_ENABLE
|
||||
if (config.filter)
|
||||
filter_init ();
|
||||
@ -451,12 +444,13 @@ main (int argc, char **argv)
|
||||
"Could not remove PID file \"%s\": %s.",
|
||||
config.pidpath, strerror (errno));
|
||||
}
|
||||
|
||||
#ifdef FILTER_ENABLE
|
||||
if (config.filter)
|
||||
filter_destroy ();
|
||||
#endif /* FILTER_ENABLE */
|
||||
|
||||
free_config (&config);
|
||||
|
||||
shutdown_logging ();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
@ -27,6 +27,9 @@
|
||||
/* Global variables for the main controls of the program */
|
||||
#define MAXBUFFSIZE ((size_t)(1024 * 96)) /* Max size of buffer */
|
||||
#define MAX_IDLE_TIME (60 * 10) /* 10 minutes of no activity */
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
#define MAX_DEAD_TIME (60 * 10) /* 10 minutes of no activity */
|
||||
#endif
|
||||
|
||||
/* Global Structures used in the program */
|
||||
extern struct config_s config;
|
||||
|
@ -204,8 +204,7 @@ ssize_t readline (int fd, char **whole_buffer)
|
||||
break;
|
||||
}
|
||||
|
||||
line_ptr->next =
|
||||
(struct read_lines_s *)
|
||||
line_ptr->next = (struct read_lines_s *)
|
||||
safecalloc (sizeof (struct read_lines_s), 1);
|
||||
if (!line_ptr->next) {
|
||||
ret = -ENOMEM;
|
||||
|
35
src/reqs.c
35
src/reqs.c
@ -1417,12 +1417,13 @@ connect_to_upstream (struct conn_s *connptr, struct request_s *request)
|
||||
*/
|
||||
return -1;
|
||||
#else
|
||||
struct upstream_proxy_list *upp;
|
||||
char *combined_string;
|
||||
int len;
|
||||
|
||||
struct upstream *cur_upstream = connptr->upstream_proxy;
|
||||
|
||||
if (!cur_upstream) {
|
||||
if (!cur_upstream || !cur_upstream->plist) {
|
||||
log_message (LOG_WARNING,
|
||||
"No upstream proxy defined for %s.",
|
||||
request->host);
|
||||
@ -1431,11 +1432,39 @@ connect_to_upstream (struct conn_s *connptr, struct request_s *request)
|
||||
return -1;
|
||||
}
|
||||
|
||||
upp = cur_upstream->plist;
|
||||
while (upp) {
|
||||
double tdiff;
|
||||
if (upp->last_failed_connect > 0) {
|
||||
tdiff =
|
||||
difftime (time (NULL), upp->last_failed_connect);
|
||||
if (tdiff < config.deadtime) {
|
||||
log_message (LOG_INFO,
|
||||
"Won't try to connect to upstream "
|
||||
"proxy %s:%d during dead time.",
|
||||
upp->host, upp->port);
|
||||
upp = upp->next;
|
||||
continue;
|
||||
} else {
|
||||
upp->last_failed_connect = (time_t) 0;
|
||||
}
|
||||
}
|
||||
connptr->server_fd =
|
||||
opensock (cur_upstream->host, cur_upstream->port,
|
||||
connptr->server_ip_addr);
|
||||
opensock (upp->host, upp->port, connptr->server_ip_addr);
|
||||
|
||||
if (connptr->server_fd < 0) {
|
||||
log_message (LOG_WARNING,
|
||||
"Could not connect to upstream proxy. "
|
||||
"Try next in list if available.");
|
||||
upp->last_failed_connect = time (NULL);
|
||||
} else {
|
||||
cur_upstream->host = upp->host;
|
||||
cur_upstream->port = upp->port;
|
||||
break;
|
||||
}
|
||||
upp = upp->next;
|
||||
}
|
||||
if (!upp || connptr->server_fd < 0) {
|
||||
log_message (LOG_WARNING,
|
||||
"Could not connect to upstream proxy.");
|
||||
indicate_http_error (connptr, 404,
|
||||
|
@ -139,13 +139,10 @@ char *reverse_rewrite_url (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
&& (reverse =
|
||||
reversepath_get (cookieval +
|
||||
strlen (REVERSE_COOKIE) + 1,
|
||||
config.reversepath_list)))
|
||||
{
|
||||
config.reversepath_list))) {
|
||||
|
||||
rewrite_url = (char *) safemalloc
|
||||
(strlen (url) +
|
||||
strlen (reverse->url) +
|
||||
1);
|
||||
(strlen (url) + strlen (reverse->url) + 1);
|
||||
strcpy (rewrite_url, reverse->url);
|
||||
strcat (rewrite_url, url + 1);
|
||||
|
||||
|
23
src/sock.c
23
src/sock.c
@ -50,8 +50,7 @@ static const char * get_gai_error (int n)
|
||||
* returned if the bind succeeded. Otherwise, -1 is returned
|
||||
* to indicate an error.
|
||||
*/
|
||||
static int
|
||||
bind_socket (int sockfd, const char *addr, int family)
|
||||
static int bind_socket (int sockfd, const char *addr, int family)
|
||||
{
|
||||
struct addrinfo hints, *res, *ressave;
|
||||
int n;
|
||||
@ -67,7 +66,8 @@ bind_socket (int sockfd, const char *addr, int family)
|
||||
n = getaddrinfo (addr, NULL, &hints, &res);
|
||||
if (n != 0) {
|
||||
log_message (LOG_INFO,
|
||||
"bind_socket: getaddrinfo failed for %s: ", addr, get_gai_error (n));
|
||||
"bind_socket: getaddrinfo failed for %s: ", addr,
|
||||
get_gai_error (n));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -112,7 +112,8 @@ int opensock (const char *host, int port, const char *bind_to)
|
||||
n = getaddrinfo (host, portstr, &hints, &res);
|
||||
if (n != 0) {
|
||||
log_message (LOG_ERR,
|
||||
"opensock: Could not retrieve address info for %s:%d: %s", host, port, get_gai_error (n));
|
||||
"opensock: Could not retrieve address info for %s:%d: %s",
|
||||
host, port, get_gai_error (n));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -128,8 +129,7 @@ int opensock (const char *host, int port, const char *bind_to)
|
||||
|
||||
/* Bind to the specified address */
|
||||
if (bind_to) {
|
||||
if (bind_socket (sockfd, bind_to,
|
||||
res->ai_family) < 0) {
|
||||
if (bind_socket (sockfd, bind_to, res->ai_family) < 0) {
|
||||
close (sockfd);
|
||||
continue; /* can't bind, so try again */
|
||||
}
|
||||
@ -151,8 +151,7 @@ int opensock (const char *host, int port, const char *bind_to)
|
||||
if (res == NULL) {
|
||||
log_message (LOG_ERR,
|
||||
"opensock: Could not establish a connection to %s:%d",
|
||||
host,
|
||||
port);
|
||||
host, port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -185,7 +184,6 @@ int socket_blocking (int sock)
|
||||
return fcntl (sock, F_SETFL, flags & ~O_NONBLOCK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to listen on one socket based on the addrinfo
|
||||
* as returned from getaddrinfo.
|
||||
@ -203,7 +201,8 @@ static int listen_on_one_socket(struct addrinfo *ad)
|
||||
ret = getnameinfo (ad->ai_addr, ad->ai_addrlen,
|
||||
numerichost, NI_MAXHOST, NULL, 0, flags);
|
||||
if (ret != 0) {
|
||||
log_message(LOG_ERR, "getnameinfo failed: %s", get_gai_error (ret));
|
||||
log_message (LOG_ERR, "getnameinfo failed: %s",
|
||||
get_gai_error (ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -291,9 +290,7 @@ int listen_sock (const char *addr, uint16_t port, vector_t listen_fds)
|
||||
if (n != 0) {
|
||||
log_message (LOG_ERR,
|
||||
"Unable to getaddrinfo() for %s:%d because of %s",
|
||||
addr,
|
||||
port,
|
||||
get_gai_error (n));
|
||||
addr, port, get_gai_error (n));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,7 @@ void init_stats (void)
|
||||
/*
|
||||
* Display the statics of the tinyproxy server.
|
||||
*/
|
||||
int
|
||||
showstats (struct conn_s *connptr)
|
||||
int showstats (struct conn_s *connptr)
|
||||
{
|
||||
char *message_buffer;
|
||||
char opens[16], reqs[16], badconns[16], denied[16], refused[16];
|
||||
@ -102,8 +101,7 @@ showstats (struct conn_s *connptr)
|
||||
stats->num_badcons, stats->num_denied,
|
||||
stats->num_refused, PACKAGE, VERSION);
|
||||
|
||||
if (send_http_message (connptr, 200, "OK",
|
||||
message_buffer) < 0) {
|
||||
if (send_http_message (connptr, 200, "OK", message_buffer) < 0) {
|
||||
safefree (message_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
136
src/upstream.c
136
src/upstream.c
@ -31,6 +31,25 @@
|
||||
#include "basicauth.h"
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
static const char *proxy_list_name (struct upstream_proxy_list *plist)
|
||||
{
|
||||
#define MAXBUF ((size_t)(1024 * 96))
|
||||
static char hostport[MAXBUF];
|
||||
static char pbuffer[MAXBUF];
|
||||
struct upstream_proxy_list *upl = plist;
|
||||
|
||||
bzero (&pbuffer, MAXBUF);
|
||||
snprintf (pbuffer, MAXBUF, "%s:%d", upl->host, upl->port);
|
||||
upl = upl->next;
|
||||
while (upl) {
|
||||
bzero (&hostport, MAXBUF);
|
||||
snprintf (hostport, MAXBUF, "|%s:%d", upl->host, upl->port);
|
||||
strncat (pbuffer, hostport, MAXBUF - strlen (hostport));
|
||||
upl = upl->next;
|
||||
}
|
||||
return pbuffer;
|
||||
}
|
||||
|
||||
const char *proxy_type_name (proxy_type type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -47,15 +66,43 @@ const char *proxy_type_name (proxy_type type)
|
||||
}
|
||||
}
|
||||
|
||||
static struct upstream_proxy_list *uplcpy (const struct upstream_proxy_list
|
||||
*plist)
|
||||
{
|
||||
struct upstream_proxy_list *upr, *upp, *uptr;
|
||||
|
||||
if (!plist)
|
||||
return NULL;
|
||||
|
||||
upr = upp = (upstream_proxy_list_t *)
|
||||
safemalloc (sizeof (upstream_proxy_list_t));
|
||||
upp->host = safestrdup (plist->host);
|
||||
upp->port = plist->port;
|
||||
upp->last_failed_connect = plist->last_failed_connect;
|
||||
upp->next = NULL;
|
||||
uptr = plist->next;
|
||||
while (uptr) {
|
||||
upp->next = (upstream_proxy_list_t *)
|
||||
safemalloc (sizeof (upstream_proxy_list_t));
|
||||
upp = upp->next;
|
||||
upp->host = safestrdup (uptr->host);
|
||||
upp->port = uptr->port;
|
||||
upp->next = NULL;
|
||||
uptr = uptr->next;
|
||||
}
|
||||
return upr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an upstream struct from input data.
|
||||
*/
|
||||
static struct upstream *upstream_build (const char *host, int port,
|
||||
static struct upstream *upstream_build (const struct upstream_proxy_list *plist,
|
||||
const char *domain, const char *user,
|
||||
const char *pass, proxy_type type)
|
||||
{
|
||||
char *ptr;
|
||||
struct upstream *up;
|
||||
struct upstream_proxy_list *upp;
|
||||
#ifdef UPSTREAM_REGEX
|
||||
int cflags = REG_NEWLINE | REG_NOSUB;
|
||||
int rflag = 0;
|
||||
@ -70,7 +117,8 @@ static struct upstream *upstream_build (const char *host, int port,
|
||||
}
|
||||
|
||||
up->type = type;
|
||||
up->host = up->domain = up->ua.user = up->pass = NULL;
|
||||
up->domain = up->ua.user = up->pass = NULL;
|
||||
up->plist = NULL;
|
||||
#ifdef UPSTREAM_REGEX
|
||||
up->pat = NULL;
|
||||
up->cpat = NULL;
|
||||
@ -124,18 +172,18 @@ static struct upstream *upstream_build (const char *host, int port,
|
||||
}
|
||||
|
||||
if (domain == NULL) {
|
||||
if (!host || host[0] == '\0' || port < 1) {
|
||||
if (!plist || plist->host[0] == '\0' || plist->port < 1) {
|
||||
log_message (LOG_WARNING,
|
||||
"Nonsense upstream rule: invalid host or port");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
up->host = safestrdup (host);
|
||||
up->port = port;
|
||||
up->plist = uplcpy (plist);
|
||||
|
||||
log_message (LOG_INFO, "Added upstream %s %s:%d for [default]",
|
||||
proxy_type_name (type), host, port);
|
||||
} else if (host == NULL || type == PT_NONE) {
|
||||
log_message (LOG_INFO, "Added upstream %s %s for [default]",
|
||||
proxy_type_name (type),
|
||||
proxy_list_name (up->plist));
|
||||
} else if (plist == NULL || type == PT_NONE) {
|
||||
if (!domain || domain[0] == '\0') {
|
||||
log_message (LOG_WARNING,
|
||||
"Nonsense no-upstream rule: empty domain");
|
||||
@ -183,15 +231,14 @@ static struct upstream *upstream_build (const char *host, int port,
|
||||
|
||||
log_message (LOG_INFO, "Added no-upstream for %s", domain);
|
||||
} else {
|
||||
if (!host || host[0] == '\0' || port < 1 || !domain
|
||||
|| domain[0] == '\0') {
|
||||
if (!plist || plist->host[0] == '\0' || plist->port < 1
|
||||
|| !domain || domain[0] == '\0') {
|
||||
log_message (LOG_WARNING,
|
||||
"Nonsense upstream rule: invalid parameters");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
up->host = safestrdup (host);
|
||||
up->port = port;
|
||||
up->plist = uplcpy (plist);
|
||||
up->domain = safestrdup (domain);
|
||||
#ifdef UPSTREAM_REGEX
|
||||
if (rflag) {
|
||||
@ -205,19 +252,29 @@ static struct upstream *upstream_build (const char *host, int port,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
log_message (LOG_INFO, "Added upstream %s %s:%d for %s",
|
||||
proxy_type_name (type), host, port, domain);
|
||||
log_message (LOG_INFO, "Added upstream %s %s for %s",
|
||||
proxy_type_name (type),
|
||||
proxy_list_name (up->plist), domain);
|
||||
}
|
||||
|
||||
return up;
|
||||
|
||||
fail:
|
||||
safefree (up->ua.user);
|
||||
safefree (up->ua.authstr);
|
||||
safefree (up->pass);
|
||||
safefree (up->host);
|
||||
upp = up->plist;
|
||||
while (upp) {
|
||||
struct upstream_proxy_list *tmpp = upp;
|
||||
upp = upp->next;
|
||||
safefree (tmpp->host);
|
||||
safefree (tmpp);
|
||||
}
|
||||
safefree (up->domain);
|
||||
#ifdef UPSTREAM_REGEX
|
||||
safefree (up->pat);
|
||||
if (up->cpat)
|
||||
regfree (up->cpat);
|
||||
safefree (up->cpat);
|
||||
#endif
|
||||
safefree (up);
|
||||
@ -228,13 +285,14 @@ fail:
|
||||
/*
|
||||
* Add an entry to the upstream list
|
||||
*/
|
||||
void upstream_add (const char *host, int port, const char *domain,
|
||||
void upstream_add (const struct upstream_proxy_list *plist, const char *domain,
|
||||
const char *user, const char *pass,
|
||||
proxy_type type, struct upstream **upstream_list)
|
||||
{
|
||||
struct upstream *up;
|
||||
struct upstream_proxy_list *upp;
|
||||
|
||||
up = upstream_build (host, port, domain, user, pass, type);
|
||||
up = upstream_build (plist, domain, user, pass, type);
|
||||
if (up == NULL) {
|
||||
return;
|
||||
}
|
||||
@ -265,8 +323,23 @@ void upstream_add (const char *host, int port, const char *domain,
|
||||
return;
|
||||
|
||||
upstream_cleanup:
|
||||
safefree (up->host);
|
||||
upp = up->plist;
|
||||
while (upp) {
|
||||
struct upstream_proxy_list *tmpp = upp;
|
||||
upp = upp->next;
|
||||
safefree (tmpp->host);
|
||||
safefree (tmpp);
|
||||
}
|
||||
safefree (up->domain);
|
||||
safefree (up->ua.user);
|
||||
safefree (up->ua.authstr);
|
||||
safefree (up->pass);
|
||||
#ifdef UPSTREAM_REGEX
|
||||
safefree (up->pat);
|
||||
if (up->cpat)
|
||||
regfree (up->cpat);
|
||||
safefree (up->cpat);
|
||||
#endif
|
||||
safefree (up);
|
||||
|
||||
return;
|
||||
@ -323,14 +396,14 @@ struct upstream *upstream_get (struct request_s *request, struct upstream *up)
|
||||
|
||||
up = up->next;
|
||||
}
|
||||
|
||||
if (up && (!up->host || !up->port))
|
||||
if (up && !up->plist)
|
||||
up = NULL;
|
||||
|
||||
if (up)
|
||||
log_message (LOG_INFO, "Found upstream proxy %s %s:%d for %s",
|
||||
proxy_type_name (up->type), up->host, up->port,
|
||||
host);
|
||||
log_message (LOG_INFO,
|
||||
"Found upstream proxy/proxies %s %s for %s",
|
||||
proxy_type_name (up->type),
|
||||
proxy_list_name (up->plist), host);
|
||||
else
|
||||
log_message (LOG_INFO, "No upstream proxy for %s", host);
|
||||
|
||||
@ -341,9 +414,24 @@ void free_upstream_list (struct upstream *up)
|
||||
{
|
||||
while (up) {
|
||||
struct upstream *tmp = up;
|
||||
struct upstream_proxy_list *upp = up->plist;
|
||||
up = up->next;
|
||||
while (upp) {
|
||||
struct upstream_proxy_list *tmpp = upp;
|
||||
upp = upp->next;
|
||||
safefree (tmpp->host);
|
||||
safefree (tmpp);
|
||||
}
|
||||
safefree (tmp->domain);
|
||||
safefree (tmp->host);
|
||||
safefree (tmp->ua.user);
|
||||
safefree (tmp->ua.authstr);
|
||||
safefree (tmp->pass);
|
||||
#ifdef UPSTREAM_REGEX
|
||||
safefree (tmp->pat);
|
||||
if (tmp->cpat)
|
||||
regfree (tmp->cpat);
|
||||
safefree (tmp->cpat);
|
||||
#endif
|
||||
safefree (tmp);
|
||||
}
|
||||
}
|
||||
|
@ -39,16 +39,25 @@ typedef enum proxy_type {
|
||||
PT_SOCKS5
|
||||
} proxy_type;
|
||||
|
||||
typedef struct upstream_proxy_list {
|
||||
struct upstream_proxy_list *next;
|
||||
char *host;
|
||||
int port;
|
||||
time_t last_failed_connect;
|
||||
|
||||
} upstream_proxy_list_t;
|
||||
|
||||
struct upstream {
|
||||
struct upstream *next;
|
||||
char *domain; /* optional */
|
||||
struct upstream_proxy_list *plist;
|
||||
char *host;
|
||||
int port;
|
||||
union {
|
||||
char *user;
|
||||
char *authstr;
|
||||
} ua;
|
||||
char *pass;
|
||||
int port;
|
||||
in_addr_t ip, mask;
|
||||
proxy_type type;
|
||||
#if defined(UPSTREAM_SUPPORT) && defined(UPSTREAM_REGEX)
|
||||
@ -59,9 +68,10 @@ struct upstream {
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
const char *proxy_type_name (proxy_type type);
|
||||
extern void upstream_add (const char *host, int port, const char *domain,
|
||||
const char *user, const char *pass,
|
||||
proxy_type type, struct upstream **upstream_list);
|
||||
extern void upstream_add (const struct upstream_proxy_list *phost,
|
||||
const char *domain, const char *user,
|
||||
const char *pass, proxy_type type,
|
||||
struct upstream **upstream_list);
|
||||
extern struct upstream *upstream_get (struct request_s *request,
|
||||
struct upstream *up);
|
||||
extern void free_upstream_list (struct upstream *up);
|
||||
|
@ -185,8 +185,7 @@ int create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
*
|
||||
* Returns: %0 on success, non-zero values on errors.
|
||||
**/
|
||||
int
|
||||
pidfile_create (const char *filename)
|
||||
int pidfile_create (const char *filename)
|
||||
{
|
||||
int fildes;
|
||||
FILE *fd;
|
||||
|
@ -111,10 +111,7 @@ typedef enum {
|
||||
} vector_pos_t;
|
||||
|
||||
static int
|
||||
vector_insert (vector_t vector,
|
||||
void *data,
|
||||
size_t len,
|
||||
vector_pos_t pos)
|
||||
vector_insert (vector_t vector, void *data, size_t len, vector_pos_t pos)
|
||||
{
|
||||
struct vectorentry_s *entry;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user