summaryrefslogtreecommitdiffhomepage
path: root/src/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf.c')
-rw-r--r--src/conf.c380
1 files changed, 222 insertions, 158 deletions
diff --git a/src/conf.c b/src/conf.c
index bf2458f..baacbbf 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -23,6 +23,8 @@
* add new directives to. Who knows if I'm right though.
*/
+#include "common.h"
+#include <regex.h>
#include "conf.h"
#include "acl.h"
@@ -36,6 +38,7 @@
#include "upstream.h"
#include "connect-ports.h"
#include "basicauth.h"
+#include "conf-tokens.h"
/*
* The configuration directives are defined in the structure below. Each
@@ -46,46 +49,35 @@
* can (and likely should) be used when building the regex for the
* given directive.
*/
-#define WS "[[:space:]]+"
+#define DIGIT "[0-9]"
+#define SPACE "[ \t]"
+#define WS SPACE "+"
#define STR "\"([^\"]+)\""
#define BOOL "(yes|on|no|off)"
-#define INT "((0x)?[[:digit:]]+)"
+#define INT "(()" DIGIT "+)"
#define ALNUM "([-a-z0-9._]+)"
#define USERNAME "([^:]*)"
#define PASSWORD "([^@]*)"
#define IP "((([0-9]{1,3})\\.){3}[0-9]{1,3})"
-#define IPMASK "(" IP "(/[[:digit:]]+)?)"
+#define IPMASK "(" IP "(/" DIGIT "+)?)"
#define IPV6 "(" \
- "(([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6})|" \
- "(([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5})|" \
- "(([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4})|" \
- "(([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3})|" \
- "(([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2})|" \
- "(([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1})|" \
- "((([0-9a-f]{1,4}:){1,7}|:):)|" \
- "(:(:[0-9a-f]{1,4}){1,7})|" \
- "([0-9a-f]{1,4}(:[0-9a-f]{1,4}){1,7})|" \
- "(((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}))|" \
- "((([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}))|" \
- "(([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
- "(([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
- "(([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
- "(([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
- "(([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
- "((([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
- "(:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})" \
+ "(([0-9a-f:]{2,39}))|" \
+ "(([0-9a-f:]{0,29}:" IP "))" \
")"
-#define IPV6MASK "(" IPV6 "(/[[:digit:]]+)?)"
-#define BEGIN "^[[:space:]]*"
-#define END "[[:space:]]*$"
+#define IPV6MASK "(" IPV6 "(/" DIGIT "+)?)"
+#define BEGIN "^" SPACE "*"
+#define END SPACE "*$"
/*
* 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 24
+
+#define CP_WARN(FMT, ...) \
+ log_message (LOG_WARNING, "line %lu: " FMT, lineno, __VA_ARGS__)
/*
* All configuration handling functions are REQUIRED to be defined
@@ -113,15 +105,20 @@ typedef int (*CONFFILE_HANDLER) (struct config_s *, const char *,
* List all the handling functions. These are defined later, but they need
* to be in-scope before the big structure below.
*/
-static HANDLE_FUNC (handle_nop)
+static HANDLE_FUNC (handle_disabled_feature)
{
- return 0;
-} /* do nothing function */
+ fprintf (stderr, "ERROR: accessing feature that was disabled at compiletime on line %lu\n",
+ lineno);
+
+ return -1;
+}
static HANDLE_FUNC (handle_allow);
static HANDLE_FUNC (handle_basicauth);
static HANDLE_FUNC (handle_anonymous);
static HANDLE_FUNC (handle_bind);
+static HANDLE_FUNC (handle_bindipv4mapped);
+static HANDLE_FUNC (handle_bindipv6mapped);
static HANDLE_FUNC (handle_bindsame);
static HANDLE_FUNC (handle_connectport);
static HANDLE_FUNC (handle_defaulterrorfile);
@@ -161,7 +158,6 @@ static HANDLE_FUNC (handle_xtinyproxy);
#ifdef UPSTREAM_SUPPORT
static HANDLE_FUNC (handle_upstream);
-static HANDLE_FUNC (handle_upstream_no);
#endif
static void config_free_regex (void);
@@ -177,7 +173,7 @@ static void config_free_regex (void);
* do not follow the pattern above. This macro is for convenience
* only.
*/
-#define STDCONF(d, re, func) { BEGIN "(" d ")" WS re END, func, NULL }
+#define STDCONF(d, re, func) [CD_ ## d] = { BEGIN "()" WS re END, func, NULL }
/*
* Holds the regular expression used to match the configuration directive,
@@ -190,109 +186,118 @@ struct {
CONFFILE_HANDLER handler;
regex_t *cre;
} directives[] = {
- /* comments */
- {
- BEGIN "#", handle_nop, NULL
- },
- /* blank lines */
- {
- "^[[:space:]]+$", handle_nop, NULL
- },
/* string arguments */
- STDCONF ("logfile", STR, handle_logfile),
- STDCONF ("pidfile", STR, handle_pidfile),
- STDCONF ("anonymous", STR, handle_anonymous),
- STDCONF ("viaproxyname", STR, handle_viaproxyname),
- STDCONF ("defaulterrorfile", STR, handle_defaulterrorfile),
- STDCONF ("statfile", STR, handle_statfile),
- STDCONF ("stathost", STR, handle_stathost),
- STDCONF ("xtinyproxy", BOOL, handle_xtinyproxy),
+ STDCONF (logfile, STR, handle_logfile),
+ STDCONF (pidfile, STR, handle_pidfile),
+ STDCONF (anonymous, STR, handle_anonymous),
+ STDCONF (viaproxyname, STR, handle_viaproxyname),
+ STDCONF (defaulterrorfile, STR, handle_defaulterrorfile),
+ STDCONF (statfile, STR, handle_statfile),
+ STDCONF (stathost, STR, handle_stathost),
+ STDCONF (xtinyproxy, BOOL, handle_xtinyproxy),
/* boolean arguments */
- STDCONF ("syslog", BOOL, handle_syslog),
- STDCONF ("bindsame", BOOL, handle_bindsame),
- STDCONF ("disableviaheader", BOOL, handle_disableviaheader),
+ STDCONF (syslog, BOOL, handle_syslog),
+ STDCONF (bindsame, BOOL, handle_bindsame),
+ STDCONF (disableviaheader, BOOL, handle_disableviaheader),
/* integer arguments */
- STDCONF ("port", INT, handle_port),
- STDCONF ("maxclients", INT, handle_maxclients),
- STDCONF ("maxspareservers", INT, handle_obsolete),
- STDCONF ("minspareservers", INT, handle_obsolete),
- STDCONF ("startservers", INT, handle_obsolete),
- STDCONF ("maxrequestsperchild", INT, handle_obsolete),
- STDCONF ("timeout", INT, handle_timeout),
- STDCONF ("connectport", INT, handle_connectport),
+ STDCONF (port, INT, handle_port),
+ STDCONF (maxclients, INT, handle_maxclients),
+ STDCONF (maxspareservers, INT, handle_obsolete),
+ STDCONF (minspareservers, INT, handle_obsolete),
+ STDCONF (startservers, INT, handle_obsolete),
+ STDCONF (maxrequestsperchild, INT, handle_obsolete),
+ STDCONF (timeout, INT, handle_timeout),
+ STDCONF (connectport, INT, handle_connectport),
/* alphanumeric arguments */
- STDCONF ("user", ALNUM, handle_user),
- STDCONF ("group", ALNUM, handle_group),
+ STDCONF (user, ALNUM, handle_user),
+ STDCONF (group, ALNUM, handle_group),
/* ip arguments */
- STDCONF ("listen", "(" IP "|" IPV6 ")", handle_listen),
- STDCONF ("allow", "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
+ STDCONF (listen, "(" IP "|" IPV6 ")", handle_listen),
+ STDCONF (allow, "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
handle_allow),
- STDCONF ("deny", "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
+ STDCONF (deny, "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
handle_deny),
- STDCONF ("bind", "(" IP "|" IPV6 ")", handle_bind),
+ STDCONF (bind, "(" IP "|" IPV6 ")", handle_bind),
+ STDCONF (bindipv4mapped, "(" IPV6 ")", handle_bindipv4mapped),
+ STDCONF (bindipv6mapped, "(" IP ")", handle_bindipv6mapped),
/* other */
- STDCONF ("basicauth", ALNUM WS ALNUM, handle_basicauth),
- STDCONF ("errorfile", INT WS STR, handle_errorfile),
- STDCONF ("addheader", STR WS STR, handle_addheader),
+ 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),
- STDCONF ("filterurls", BOOL, handle_filterurls),
- STDCONF ("filterextended", BOOL, handle_filterextended),
- STDCONF ("filterdefaultdeny", BOOL, handle_filterdefaultdeny),
- STDCONF ("filtercasesensitive", BOOL, handle_filtercasesensitive),
+ STDCONF (filter, STR, handle_filter),
+ STDCONF (filterurls, BOOL, handle_filterurls),
+ STDCONF (filterextended, BOOL, handle_filterextended),
+ STDCONF (filterdefaultdeny, BOOL, handle_filterdefaultdeny),
+ STDCONF (filtercasesensitive, BOOL, handle_filtercasesensitive),
#endif
#ifdef REVERSE_SUPPORT
/* Reverse proxy arguments */
- STDCONF ("reversebaseurl", STR, handle_reversebaseurl),
- STDCONF ("reverseonly", BOOL, handle_reverseonly),
- STDCONF ("reversemagic", BOOL, handle_reversemagic),
- STDCONF ("reversepath", STR "(" WS STR ")?", handle_reversepath),
+ STDCONF (reversebaseurl, STR, handle_reversebaseurl),
+ STDCONF (reverseonly, BOOL, handle_reverseonly),
+ STDCONF (reversemagic, BOOL, handle_reversemagic),
+ STDCONF (reversepath, STR "(" WS STR ")?", handle_reversepath),
#endif
#ifdef UPSTREAM_SUPPORT
- {
- 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
- },
+ STDCONF (upstream,
+ "(" "(none)" WS STR ")|" \
+ "(" "(http|socks4|socks5)" WS \
+ "(" USERNAME /*username*/ ":" PASSWORD /*password*/ "@" ")?"
+ "(" IP "|" ALNUM ")"
+ ":" INT "(" WS STR ")?" ")", handle_upstream),
#endif
/* loglevel */
- STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
+ STDCONF (loglevel, "(critical|error|warning|notice|connect|info)",
handle_loglevel)
};
const unsigned int ndirectives = sizeof (directives) / sizeof (directives[0]);
static void
-free_added_headers (vector_t add_headers)
+free_added_headers (sblist* add_headers)
{
- ssize_t i;
+ size_t i;
- for (i = 0; i < vector_length (add_headers); i++) {
- http_header_t *header = (http_header_t *)
- vector_getentry (add_headers, i, NULL);
+ if (!add_headers) return;
+
+ for (i = 0; i < sblist_getsize (add_headers); i++) {
+ http_header_t *header = sblist_get (add_headers, i);
safefree (header->name);
safefree (header->value);
}
- vector_delete (add_headers);
+ sblist_free (add_headers);
+}
+
+static void stringlist_free(sblist *sl) {
+ size_t i;
+ char **s;
+ if(sl) {
+ for(i = 0; i < sblist_getsize(sl); i++) {
+ s = sblist_get(sl, i);
+ if(s) safefree(*s);
+ }
+ sblist_free(sl);
+ }
}
-static void free_config (struct config_s *conf)
+void free_config (struct config_s *conf)
{
+ char *k;
+ htab_value *v;
+ size_t it;
safefree (conf->logf_name);
safefree (conf->stathost);
safefree (conf->user);
safefree (conf->group);
- vector_delete(conf->listen_addrs);
- vector_delete(conf->basicauth_list);
+ safefree (conf->bind_ipv4mapped);
+ safefree (conf->bind_ipv6mapped);
+ stringlist_free(conf->basicauth_list);
+ stringlist_free(conf->listen_addrs);
+ stringlist_free(conf->bind_addrs);
#ifdef FILTER_ENABLE
safefree (conf->filter);
#endif /* FILTER_ENABLE */
@@ -304,34 +309,50 @@ static void free_config (struct config_s *conf)
free_upstream_list (conf->upstream_list);
#endif /* UPSTREAM_SUPPORT */
safefree (conf->pidpath);
- safefree (conf->bind_address);
safefree (conf->via_proxy_name);
- hashmap_delete (conf->errorpages);
+ if (conf->errorpages) {
+ it = 0;
+ while((it = htab_next(conf->errorpages, it, &k, &v))) {
+ safefree(k);
+ safefree(v->p);
+ }
+ htab_destroy (conf->errorpages);
+ }
free_added_headers (conf->add_headers);
safefree (conf->errorpage_undef);
safefree (conf->statpage);
flush_access_list (conf->access_list);
free_connect_ports_list (conf->connect_ports);
- hashmap_delete (conf->anonymous_map);
+ if (conf->anonymous_map) {
+ it = 0;
+ while((it = htab_next(conf->anonymous_map, it, &k, &v)))
+ safefree(k);
+ htab_destroy (conf->anonymous_map);
+ }
memset (conf, 0, sizeof(*conf));
}
/*
+ * Initializes Config parser. Currently this means:
* Compiles the regular expressions used by the configuration file. This
* routine MUST be called before trying to parse the configuration file.
*
* Returns 0 on success; negative upon failure.
*/
int
-config_compile_regex (void)
+config_init (void)
{
unsigned int i, r;
for (i = 0; i != ndirectives; ++i) {
- assert (directives[i].handler);
assert (!directives[i].cre);
+ if (!directives[i].handler) {
+ directives[i].handler = handle_disabled_feature;
+ continue;
+ }
+
directives[i].cre = (regex_t *) safemalloc (sizeof (regex_t));
if (!directives[i].cre)
return -1;
@@ -375,20 +396,17 @@ config_free_regex (void)
* a negative number is returned.
*/
static int check_match (struct config_s *conf, const char *line,
- unsigned long lineno)
+ unsigned long lineno, enum config_directive cd)
{
regmatch_t match[RE_MAX_MATCHES];
- unsigned int i;
+ unsigned int i = cd;
- assert (ndirectives > 0);
-
- for (i = 0; i != ndirectives; ++i) {
- assert (directives[i].cre);
- if (!regexec
- (directives[i].cre, line, RE_MAX_MATCHES, match, 0))
- return (*directives[i].handler) (conf, line, lineno, match);
- }
+ if (!directives[i].cre)
+ return (*directives[i].handler) (conf, line, lineno, match);
+ if (!regexec
+ (directives[i].cre, line, RE_MAX_MATCHES, match, 0))
+ return (*directives[i].handler) (conf, line, lineno, match);
return -1;
}
@@ -397,15 +415,25 @@ static int check_match (struct config_s *conf, const char *line,
*/
static int config_parse (struct config_s *conf, FILE * f)
{
- char buffer[LINE_MAX];
+ char buffer[LINE_MAX], *p, *q, c;
+ const struct config_directive_entry *e;
unsigned long lineno = 1;
- while (fgets (buffer, sizeof (buffer), f)) {
- if (check_match (conf, buffer, lineno)) {
- printf ("Syntax error on line %ld\n", lineno);
+ for (;fgets (buffer, sizeof (buffer), f);++lineno) {
+ if(buffer[0] == '#') continue;
+ p = buffer;
+ while(isspace(*p))p++;
+ if(!*p) continue;
+ q = p;
+ while(!isspace(*q))q++;
+ c = *q;
+ *q = 0;
+ e = config_directive_find(p, strlen(p));
+ *q = c;
+ if (!e || e->value == CD_NIL || check_match (conf, q, lineno, e->value)) {
+ fprintf (stderr, "ERROR: Syntax error on line %lu\n", lineno);
return 1;
}
- ++lineno;
}
return 0;
}
@@ -464,10 +492,6 @@ int reload_config_file (const char *config_fname, struct config_s *conf)
{
int ret;
- log_message (LOG_NOTICE, "Reloading config file");
-
- free_config (conf);
-
initialize_config_defaults (conf);
ret = load_config_file (config_fname, conf);
@@ -624,8 +648,12 @@ static HANDLE_FUNC (handle_anonymous)
if (!arg)
return -1;
- anonymous_insert (conf, arg);
- safefree (arg);
+ if(anonymous_insert (conf, arg) < 0) {
+ CP_WARN ("anonymous_insert() failed: '%s'", arg);
+ safefree(arg);
+ return -1;
+ }
+
return 0;
}
@@ -748,11 +776,16 @@ static HANDLE_FUNC (handle_group)
return set_string_arg (&conf->group, line, &match[2]);
}
+static void warn_invalid_address(char *arg, unsigned long lineno) {
+ CP_WARN ("Invalid address %s", arg);
+}
+
static HANDLE_FUNC (handle_allow)
{
char *arg = get_string_arg (line, &match[2]);
- insert_acl (arg, ACL_ALLOW, &conf->access_list);
+ if(insert_acl (arg, ACL_ALLOW, &conf->access_list) < 0)
+ warn_invalid_address (arg, lineno);
safefree (arg);
return 0;
}
@@ -761,19 +794,35 @@ static HANDLE_FUNC (handle_deny)
{
char *arg = get_string_arg (line, &match[2]);
- insert_acl (arg, ACL_DENY, &conf->access_list);
+ if(insert_acl (arg, ACL_DENY, &conf->access_list) < 0)
+ warn_invalid_address (arg, lineno);
safefree (arg);
return 0;
}
static HANDLE_FUNC (handle_bind)
{
- int r = set_string_arg (&conf->bind_address, line, &match[2]);
+ char *arg = get_string_arg (line, &match[2]);
+
+ if (arg == NULL) {
+ return -1;
+ }
+
+ if (conf->bind_addrs == NULL) {
+ conf->bind_addrs = sblist_new(sizeof(char*), 16);
+ if (conf->bind_addrs == NULL) {
+ CP_WARN ("Could not create a list "
+ "of bind addresses.", "");
+ safefree(arg);
+ return -1;
+ }
+ }
+
+ sblist_add (conf->bind_addrs, &arg);
- if (r)
- return r;
log_message (LOG_INFO,
- "Outgoing connections bound to IP %s", conf->bind_address);
+ "Added bind address [%s] for outgoing connections.", arg);
+
return 0;
}
@@ -786,23 +835,32 @@ static HANDLE_FUNC (handle_listen)
}
if (conf->listen_addrs == NULL) {
- conf->listen_addrs = vector_create();
+ conf->listen_addrs = sblist_new(sizeof(char*), 16);
if (conf->listen_addrs == NULL) {
- log_message(LOG_WARNING, "Could not create a list "
- "of listen addresses.");
+ CP_WARN ("Could not create a list "
+ "of listen addresses.", "");
safefree(arg);
return -1;
}
}
- vector_append (conf->listen_addrs, arg, strlen(arg) + 1);
+ sblist_add (conf->listen_addrs, &arg);
log_message(LOG_INFO, "Added address [%s] to listen addresses.", arg);
- safefree (arg);
return 0;
}
+static HANDLE_FUNC (handle_bindipv4mapped)
+{
+ return set_string_arg(&conf->bind_ipv4mapped, line, &match[2]);
+}
+
+static HANDLE_FUNC (handle_bindipv6mapped)
+{
+ return set_string_arg(&conf->bind_ipv6mapped, line, &match[2]);
+}
+
static HANDLE_FUNC (handle_errorfile)
{
/*
@@ -815,8 +873,10 @@ static HANDLE_FUNC (handle_errorfile)
unsigned long int err = get_long_arg (line, &match[2]);
char *page = get_string_arg (line, &match[4]);
- add_new_errorpage (page, err);
- safefree (page);
+ if(add_new_errorpage (conf, page, err) < 0) {
+ CP_WARN ("add_new_errorpage() failed: '%s'", page);
+ safefree (page);
+ }
return 0;
}
@@ -824,19 +884,16 @@ static HANDLE_FUNC (handle_addheader)
{
char *name = get_string_arg (line, &match[2]);
char *value = get_string_arg (line, &match[3]);
- http_header_t *header;
+ http_header_t header;
if (!conf->add_headers) {
- conf->add_headers = vector_create ();
+ conf->add_headers = sblist_new (sizeof(http_header_t), 16);
}
- header = (http_header_t *) safemalloc (sizeof (http_header_t));
- header->name = name;
- header->value = value;
-
- vector_prepend (conf->add_headers, header, sizeof *header);
+ header.name = name;
+ header.value = value;
- safefree (header);
+ sblist_add (conf->add_headers, &header);
/* Don't free name or value here, as they are referenced in the
* struct inserted into the vector. */
@@ -893,7 +950,7 @@ static HANDLE_FUNC (handle_basicauth)
return -1;
}
if (!conf->basicauth_list) {
- conf->basicauth_list = vector_create ();
+ conf->basicauth_list = sblist_new (sizeof(char*), 16);
}
basicauth_add (conf->basicauth_list, user, pass);
@@ -997,9 +1054,26 @@ static enum proxy_type pt_from_string(const char *s)
static HANDLE_FUNC (handle_upstream)
{
char *ip;
- int port, mi = 2;
+ int port, mi;
char *domain = 0, *user = 0, *pass = 0, *tmp;
enum proxy_type pt;
+ enum upstream_build_error ube;
+
+ if (match[3].rm_so != -1) {
+ tmp = get_string_arg (line, &match[3]);
+ if(!strcmp(tmp, "none")) {
+ safefree(tmp);
+ if (match[4].rm_so == -1) return -1;
+ domain = get_string_arg (line, &match[4]);
+ if (!domain)
+ return -1;
+ ube = upstream_add (NULL, 0, domain, 0, 0, PT_NONE, &conf->upstream_list);
+ safefree (domain);
+ goto check_err;
+ }
+ }
+
+ mi = 6;
tmp = get_string_arg (line, &match[mi]);
pt = pt_from_string(tmp);
@@ -1025,27 +1099,17 @@ static HANDLE_FUNC (handle_upstream)
if (match[mi].rm_so != -1)
domain = get_string_arg (line, &match[mi]);
- upstream_add (ip, port, domain, user, pass, pt, &conf->upstream_list);
+ ube = upstream_add (ip, port, domain, user, pass, pt, &conf->upstream_list);
safefree (user);
safefree (pass);
safefree (domain);
safefree (ip);
+check_err:;
+ if(ube != UBE_SUCCESS)
+ CP_WARN("%s", upstream_build_error_string(ube));
return 0;
}
-static HANDLE_FUNC (handle_upstream_no)
-{
- char *domain;
-
- domain = get_string_arg (line, &match[3]);
- if (!domain)
- return -1;
-
- upstream_add (NULL, 0, domain, 0, 0, PT_NONE, &conf->upstream_list);
- safefree (domain);
-
- return 0;
-}
#endif