summaryrefslogtreecommitdiff
path: root/src/app/config/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/config/config.c')
-rw-r--r--src/app/config/config.c494
1 files changed, 105 insertions, 389 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 7ed60c4745..930986483d 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -182,7 +182,7 @@ static const char unix_q_socket_prefix[] = "unix:\"";
* *DowloadInitialDelay . */
#ifndef COCCI
#define DOWNLOAD_SCHEDULE(name) \
- { #name "DownloadSchedule", #name "DownloadInitialDelay", 0, 1 }
+ { (#name "DownloadSchedule"), (#name "DownloadInitialDelay"), 0, 1 }
#else
#define DOWNLOAD_SCHEDULE(name) { NULL, NULL, 0, 1 }
#endif /* !defined(COCCI) */
@@ -366,7 +366,7 @@ static const config_var_t option_vars_[] = {
#endif /* defined(HAVE_MODULE_RELAY) || defined(TOR_UNIT_TESTS) */
V(ClientPreferIPv6ORPort, AUTOBOOL, "auto"),
V(ClientPreferIPv6DirPort, AUTOBOOL, "auto"),
- V(ClientAutoIPv6ORPort, BOOL, "0"),
+ OBSOLETE("ClientAutoIPv6ORPort"),
V(ClientRejectInternalAddresses, BOOL, "1"),
V(ClientTransportPlugin, LINELIST, NULL),
V(ClientUseIPv6, BOOL, "0"),
@@ -510,6 +510,8 @@ static const config_var_t option_vars_[] = {
LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceEnableIntroDoSBurstPerSec",
LINELIST_S, RendConfigLines, NULL),
+ VAR("HiddenServiceOnionBalanceInstance",
+ LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceStatistics", BOOL, HiddenServiceStatistics_option, "1"),
V(HidServAuth, LINELIST, NULL),
V(ClientOnionAuthDir, FILENAME, NULL),
@@ -2496,6 +2498,9 @@ static const struct {
.command=CMD_IMMEDIATE },
{ .name="--nt-service" },
{ .name="-nt-service" },
+ { .name="--dbg-dump-subsystem-list",
+ .command=CMD_IMMEDIATE,
+ .quiet=QUIET_HUSH },
{ .name=NULL },
};
@@ -2717,23 +2722,6 @@ list_enabled_modules(void)
// test variants in test_parseconf.sh to no useful purpose.
}
-/** Last value actually set by resolve_my_address. */
-static uint32_t last_resolved_addr = 0;
-
-/** Accessor for last_resolved_addr from outside this file. */
-uint32_t
-get_last_resolved_addr(void)
-{
- return last_resolved_addr;
-}
-
-/** Reset last_resolved_addr from outside this file. */
-void
-reset_last_resolved_addr(void)
-{
- last_resolved_addr = 0;
-}
-
/* Return true if <b>options</b> is using the default authorities, and false
* if any authority-related option has been overridden. */
int
@@ -2742,277 +2730,6 @@ using_default_dir_authorities(const or_options_t *options)
return (!options->DirAuthorities && !options->AlternateDirAuthority);
}
-/**
- * Attempt getting our non-local (as judged by tor_addr_is_internal()
- * function) IP address using following techniques, listed in
- * order from best (most desirable, try first) to worst (least
- * desirable, try if everything else fails).
- *
- * First, attempt using <b>options-\>Address</b> to get our
- * non-local IP address.
- *
- * If <b>options-\>Address</b> represents a non-local IP address,
- * consider it ours.
- *
- * If <b>options-\>Address</b> is a DNS name that resolves to
- * a non-local IP address, consider this IP address ours.
- *
- * If <b>options-\>Address</b> is NULL, fall back to getting local
- * hostname and using it in above-described ways to try and
- * get our IP address.
- *
- * In case local hostname cannot be resolved to a non-local IP
- * address, try getting an IP address of network interface
- * in hopes it will be non-local one.
- *
- * Fail if one or more of the following is true:
- * - DNS name in <b>options-\>Address</b> cannot be resolved.
- * - <b>options-\>Address</b> is a local host address.
- * - Attempt at getting local hostname fails.
- * - Attempt at getting network interface address fails.
- *
- * Return 0 if all is well, or -1 if we can't find a suitable
- * public IP address.
- *
- * If we are returning 0:
- * - Put our public IP address (in host order) into *<b>addr_out</b>.
- * - If <b>method_out</b> is non-NULL, set *<b>method_out</b> to a static
- * string describing how we arrived at our answer.
- * - "CONFIGURED" - parsed from IP address string in
- * <b>options-\>Address</b>
- * - "RESOLVED" - resolved from DNS name in <b>options-\>Address</b>
- * - "GETHOSTNAME" - resolved from a local hostname.
- * - "INTERFACE" - retrieved from a network interface.
- * - If <b>hostname_out</b> is non-NULL, and we resolved a hostname to
- * get our address, set *<b>hostname_out</b> to a newly allocated string
- * holding that hostname. (If we didn't get our address by resolving a
- * hostname, set *<b>hostname_out</b> to NULL.)
- *
- * XXXX ipv6
- */
-int
-resolve_my_address(int warn_severity, const or_options_t *options,
- uint32_t *addr_out,
- const char **method_out, char **hostname_out)
-{
- struct in_addr in;
- uint32_t addr; /* host order */
- char hostname[256];
- const char *method_used;
- const char *hostname_used;
- int explicit_ip=1;
- int explicit_hostname=1;
- int from_interface=0;
- char *addr_string = NULL;
- const char *address = options->Address;
- int notice_severity = warn_severity <= LOG_NOTICE ?
- LOG_NOTICE : warn_severity;
-
- tor_addr_t myaddr;
- tor_assert(addr_out);
-
- /*
- * Step one: Fill in 'hostname' to be our best guess.
- */
-
- if (address && *address) {
- strlcpy(hostname, address, sizeof(hostname));
- } else { /* then we need to guess our address */
- explicit_ip = 0; /* it's implicit */
- explicit_hostname = 0; /* it's implicit */
-
- if (tor_gethostname(hostname, sizeof(hostname)) < 0) {
- log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
- return -1;
- }
- log_debug(LD_CONFIG, "Guessed local host name as '%s'", hostname);
- }
-
- /*
- * Step two: Now that we know 'hostname', parse it or resolve it. If
- * it doesn't parse or resolve, look at the interface address. Set 'addr'
- * to be our (host-order) 32-bit answer.
- */
-
- if (tor_inet_aton(hostname, &in) == 0) {
- /* then we have to resolve it */
- explicit_ip = 0;
- if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
- uint32_t interface_ip; /* host order */
-
- if (explicit_hostname) {
- log_fn(warn_severity, LD_CONFIG,
- "Could not resolve local Address '%s'. Failing.", hostname);
- return -1;
- }
- log_fn(notice_severity, LD_CONFIG,
- "Could not resolve guessed local hostname '%s'. "
- "Trying something else.", hostname);
- if (get_interface_address(warn_severity, &interface_ip)) {
- log_fn(warn_severity, LD_CONFIG,
- "Could not get local interface IP address. Failing.");
- return -1;
- }
- from_interface = 1;
- addr = interface_ip;
- log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
- "local interface. Using that.", fmt_addr32(addr));
- strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
- } else { /* resolved hostname into addr */
- tor_addr_from_ipv4h(&myaddr, addr);
-
- if (!explicit_hostname &&
- tor_addr_is_internal(&myaddr, 0)) {
- tor_addr_t interface_ip;
-
- log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
- "resolves to a private IP address (%s). Trying something "
- "else.", hostname, fmt_addr32(addr));
-
- if (get_interface_address6(warn_severity, AF_INET, &interface_ip)<0) {
- log_fn(warn_severity, LD_CONFIG,
- "Could not get local interface IP address. Too bad.");
- } else if (tor_addr_is_internal(&interface_ip, 0)) {
- log_fn(notice_severity, LD_CONFIG,
- "Interface IP address '%s' is a private address too. "
- "Ignoring.", fmt_addr(&interface_ip));
- } else {
- from_interface = 1;
- addr = tor_addr_to_ipv4h(&interface_ip);
- log_fn(notice_severity, LD_CONFIG,
- "Learned IP address '%s' for local interface."
- " Using that.", fmt_addr32(addr));
- strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
- }
- }
- }
- } else {
- addr = ntohl(in.s_addr); /* set addr so that addr_string is not
- * illformed */
- }
-
- /*
- * Step three: Check whether 'addr' is an internal IP address, and error
- * out if it is and we don't want that.
- */
-
- tor_addr_from_ipv4h(&myaddr,addr);
-
- addr_string = tor_dup_ip(addr);
- if (tor_addr_is_internal(&myaddr, 0)) {
- /* make sure we're ok with publishing an internal IP */
- if (using_default_dir_authorities(options)) {
- /* if they are using the default authorities, disallow internal IPs
- * always. */
- log_fn(warn_severity, LD_CONFIG,
- "Address '%s' resolves to private IP address '%s'. "
- "Tor servers that use the default DirAuthorities must have "
- "public IP addresses.", hostname, addr_string);
- tor_free(addr_string);
- return -1;
- }
- if (!explicit_ip) {
- /* even if they've set their own authorities, require an explicit IP if
- * they're using an internal address. */
- log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
- "IP address '%s'. Please set the Address config option to be "
- "the IP address you want to use.", hostname, addr_string);
- tor_free(addr_string);
- return -1;
- }
- }
-
- /*
- * Step four: We have a winner! 'addr' is our answer for sure, and
- * 'addr_string' is its string form. Fill out the various fields to
- * say how we decided it.
- */
-
- log_debug(LD_CONFIG, "Resolved Address to '%s'.", addr_string);
-
- if (explicit_ip) {
- method_used = "CONFIGURED";
- hostname_used = NULL;
- } else if (explicit_hostname) {
- method_used = "RESOLVED";
- hostname_used = hostname;
- } else if (from_interface) {
- method_used = "INTERFACE";
- hostname_used = NULL;
- } else {
- method_used = "GETHOSTNAME";
- hostname_used = hostname;
- }
-
- *addr_out = addr;
- if (method_out)
- *method_out = method_used;
- if (hostname_out)
- *hostname_out = hostname_used ? tor_strdup(hostname_used) : NULL;
-
- /*
- * Step five: Check if the answer has changed since last time (or if
- * there was no last time), and if so call various functions to keep
- * us up-to-date.
- */
-
- if (last_resolved_addr && last_resolved_addr != *addr_out) {
- /* Leave this as a notice, regardless of the requested severity,
- * at least until dynamic IP address support becomes bulletproof. */
- log_notice(LD_NET,
- "Your IP address seems to have changed to %s "
- "(METHOD=%s%s%s). Updating.",
- addr_string, method_used,
- hostname_used ? " HOSTNAME=" : "",
- hostname_used ? hostname_used : "");
- ip_address_changed(0);
- }
-
- if (last_resolved_addr != *addr_out) {
- control_event_server_status(LOG_NOTICE,
- "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s%s%s",
- addr_string, method_used,
- hostname_used ? " HOSTNAME=" : "",
- hostname_used ? hostname_used : "");
- }
- last_resolved_addr = *addr_out;
-
- /*
- * And finally, clean up and return success.
- */
-
- tor_free(addr_string);
- return 0;
-}
-
-/** Return true iff <b>addr</b> is judged to be on the same network as us, or
- * on a private network.
- */
-MOCK_IMPL(int,
-is_local_addr, (const tor_addr_t *addr))
-{
- if (tor_addr_is_internal(addr, 0))
- return 1;
- /* Check whether ip is on the same /24 as we are. */
- if (get_options()->EnforceDistinctSubnets == 0)
- return 0;
- if (tor_addr_family(addr) == AF_INET) {
- uint32_t ip = tor_addr_to_ipv4h(addr);
-
- /* It's possible that this next check will hit before the first time
- * resolve_my_address actually succeeds. (For clients, it is likely that
- * resolve_my_address will never be called at all). In those cases,
- * last_resolved_addr will be 0, and so checking to see whether ip is on
- * the same /24 as last_resolved_addr will be the same as checking whether
- * it was on net 0, which is already done by tor_addr_is_internal.
- */
- if ((last_resolved_addr & (uint32_t)0xffffff00ul)
- == (ip & (uint32_t)0xffffff00ul))
- return 1;
- }
- return 0;
-}
-
/** Return a new empty or_options_t. Used for testing. */
or_options_t *
options_new(void)
@@ -3719,7 +3436,7 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
"UseEntryGuards is disabled, but you have configured one or more "
"hidden services on this Tor instance. Your hidden services "
"will be very easy to locate using a well-known attack -- see "
- "http://freehaven.net/anonbib/#hs-attack06 for details.");
+ "https://freehaven.net/anonbib/#hs-attack06 for details.");
}
if (options->NumPrimaryGuards && options->NumEntryGuards &&
@@ -4601,6 +4318,10 @@ options_init_from_torrc(int argc, char **argv)
list_deprecated_options();
return 1;
}
+ if (config_line_find(cmdline_only_options, "--dbg-dump-subsystem-list")) {
+ subsystems_dump_list();
+ return 1;
+ }
if (config_line_find(cmdline_only_options, "--version")) {
printf("Tor version %s.\n",get_version());
@@ -5875,18 +5596,28 @@ parse_dir_fallback_line(const char *line,
return r;
}
-/** Allocate and return a new port_cfg_t with reasonable defaults. */
+/** Allocate and return a new port_cfg_t with reasonable defaults.
+ *
+ * <b>namelen</b> is the length of the unix socket name
+ * (typically the filesystem path), not including the trailing NUL.
+ * It should be 0 for ports that are not zunix sockets. */
port_cfg_t *
port_cfg_new(size_t namelen)
{
tor_assert(namelen <= SIZE_T_CEILING - sizeof(port_cfg_t) - 1);
port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t) + namelen + 1);
+
+ /* entry_cfg flags */
cfg->entry_cfg.ipv4_traffic = 1;
cfg->entry_cfg.ipv6_traffic = 1;
cfg->entry_cfg.prefer_ipv6 = 0;
cfg->entry_cfg.dns_request = 1;
cfg->entry_cfg.onion_traffic = 1;
cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
+ cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
+ cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
+
+ /* Other flags default to 0 due to tor_malloc_zero */
return cfg;
}
@@ -5995,7 +5726,7 @@ port_cfg_line_extract_addrport(const char *line,
size_t sz;
*is_unix_out = 1;
*addrport_out = NULL;
- line += strlen(unix_socket_prefix); /*No q: Keep the quote */
+ line += strlen(unix_socket_prefix); /* No 'unix:', but keep the quote */
*rest_out = unescape_string(line, addrport_out, &sz);
if (!*rest_out || (*addrport_out && sz != strlen(*addrport_out))) {
tor_free(*addrport_out);
@@ -6090,11 +5821,12 @@ port_parse_config(smartlist_t *out,
const unsigned is_unix_socket = flags & CL_PORT_IS_UNIXSOCKET;
int got_zero_port=0, got_nonzero_port=0;
char *unix_socket_path = NULL;
+ port_cfg_t *cfg = NULL;
/* If there's no FooPort, then maybe make a default one. */
if (! ports) {
if (defaultport && defaultaddr && out) {
- port_cfg_t *cfg = port_cfg_new(is_unix_socket ? strlen(defaultaddr) : 0);
+ cfg = port_cfg_new(is_unix_socket ? strlen(defaultaddr) : 0);
cfg->type = listener_type;
if (is_unix_socket) {
tor_addr_make_unspec(&cfg->addr);
@@ -6104,8 +5836,6 @@ port_parse_config(smartlist_t *out,
cfg->port = defaultport;
tor_addr_parse(&cfg->addr, defaultaddr);
}
- cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
- cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
smartlist_add(out, cfg);
}
return 0;
@@ -6119,28 +5849,12 @@ port_parse_config(smartlist_t *out,
for (; ports; ports = ports->next) {
tor_addr_t addr;
tor_addr_make_unspec(&addr);
-
- int port;
- int sessiongroup = SESSION_GROUP_UNSET;
- unsigned isolation = ISO_DEFAULT;
- int prefer_no_auth = 0;
- int socks_iso_keep_alive = 0;
-
+ int port, ok,
+ has_used_unix_socket_only_option = 0,
+ is_unix_tagged_addr = 0;
uint16_t ptmp=0;
- int ok;
- /* This must be kept in sync with port_cfg_new's defaults */
- int no_listen = 0, no_advertise = 0, all_addrs = 0,
- bind_ipv4_only = 0, bind_ipv6_only = 0,
- ipv4_traffic = 1, ipv6_traffic = 1, prefer_ipv6 = 0, dns_request = 1,
- onion_traffic = 1,
- cache_ipv4 = 0, use_cached_ipv4 = 0,
- cache_ipv6 = 0, use_cached_ipv6 = 0,
- prefer_ipv6_automap = 1, world_writable = 0, group_writable = 0,
- relax_dirmode_check = 0,
- has_used_unix_socket_only_option = 0, extended_errors = 0;
-
- int is_unix_tagged_addr = 0;
const char *rest_of_line = NULL;
+
if (port_cfg_line_extract_addrport(ports->value,
&addrport, &is_unix_tagged_addr, &rest_of_line)<0) {
log_warn(LD_CONFIG, "Invalid %sPort line with unparsable address",
@@ -6216,17 +5930,20 @@ port_parse_config(smartlist_t *out,
}
}
+ /* Default port_cfg_t object initialization */
+ cfg = port_cfg_new(unix_socket_path ? strlen(unix_socket_path) : 0);
+
if (unix_socket_path && default_to_group_writable)
- group_writable = 1;
+ cfg->is_group_writable = 1;
/* Now parse the rest of the options, if any. */
if (use_server_options) {
/* This is a server port; parse advertising options */
SMARTLIST_FOREACH_BEGIN(elts, char *, elt) {
if (!strcasecmp(elt, "NoAdvertise")) {
- no_advertise = 1;
+ cfg->server_cfg.no_advertise = 1;
} else if (!strcasecmp(elt, "NoListen")) {
- no_listen = 1;
+ cfg->server_cfg.no_listen = 1;
#if 0
/* not implemented yet. */
} else if (!strcasecmp(elt, "AllAddrs")) {
@@ -6234,33 +5951,36 @@ port_parse_config(smartlist_t *out,
all_addrs = 1;
#endif /* 0 */
} else if (!strcasecmp(elt, "IPv4Only")) {
- bind_ipv4_only = 1;
+ cfg->server_cfg.bind_ipv4_only = 1;
} else if (!strcasecmp(elt, "IPv6Only")) {
- bind_ipv6_only = 1;
+ cfg->server_cfg.bind_ipv6_only = 1;
} else {
log_warn(LD_CONFIG, "Unrecognized %sPort option '%s'",
portname, escaped(elt));
}
} SMARTLIST_FOREACH_END(elt);
- if (no_advertise && no_listen) {
+ if (cfg->server_cfg.no_advertise && cfg->server_cfg.no_listen) {
log_warn(LD_CONFIG, "Tried to set both NoListen and NoAdvertise "
"on %sPort line '%s'",
portname, escaped(ports->value));
goto err;
}
- if (bind_ipv4_only && bind_ipv6_only) {
+ if (cfg->server_cfg.bind_ipv4_only &&
+ cfg->server_cfg.bind_ipv6_only) {
log_warn(LD_CONFIG, "Tried to set both IPv4Only and IPv6Only "
"on %sPort line '%s'",
portname, escaped(ports->value));
goto err;
}
- if (bind_ipv4_only && tor_addr_family(&addr) != AF_INET) {
+ if (cfg->server_cfg.bind_ipv4_only &&
+ tor_addr_family(&addr) != AF_INET) {
log_warn(LD_CONFIG, "Could not interpret %sPort address as IPv4",
portname);
goto err;
}
- if (bind_ipv6_only && tor_addr_family(&addr) != AF_INET6) {
+ if (cfg->server_cfg.bind_ipv6_only &&
+ tor_addr_family(&addr) != AF_INET6) {
log_warn(LD_CONFIG, "Could not interpret %sPort address as IPv6",
portname);
goto err;
@@ -6279,12 +5999,12 @@ port_parse_config(smartlist_t *out,
portname, escaped(elt));
goto err;
}
- if (sessiongroup >= 0) {
+ if (cfg->entry_cfg.session_group >= 0) {
log_warn(LD_CONFIG, "Multiple SessionGroup options on %sPort",
portname);
goto err;
}
- sessiongroup = group;
+ cfg->entry_cfg.session_group = group;
continue;
}
@@ -6294,15 +6014,15 @@ port_parse_config(smartlist_t *out,
}
if (!strcasecmp(elt, "GroupWritable")) {
- group_writable = !no;
+ cfg->is_group_writable = !no;
has_used_unix_socket_only_option = 1;
continue;
} else if (!strcasecmp(elt, "WorldWritable")) {
- world_writable = !no;
+ cfg->is_world_writable = !no;
has_used_unix_socket_only_option = 1;
continue;
} else if (!strcasecmp(elt, "RelaxDirModeCheck")) {
- relax_dirmode_check = !no;
+ cfg->relax_dirmode_check = !no;
has_used_unix_socket_only_option = 1;
continue;
}
@@ -6315,19 +6035,19 @@ port_parse_config(smartlist_t *out,
if (takes_hostnames) {
if (!strcasecmp(elt, "IPv4Traffic")) {
- ipv4_traffic = ! no;
+ cfg->entry_cfg.ipv4_traffic = ! no;
continue;
} else if (!strcasecmp(elt, "IPv6Traffic")) {
- ipv6_traffic = ! no;
+ cfg->entry_cfg.ipv6_traffic = ! no;
continue;
} else if (!strcasecmp(elt, "PreferIPv6")) {
- prefer_ipv6 = ! no;
+ cfg->entry_cfg.prefer_ipv6 = ! no;
continue;
} else if (!strcasecmp(elt, "DNSRequest")) {
- dns_request = ! no;
+ cfg->entry_cfg.dns_request = ! no;
continue;
} else if (!strcasecmp(elt, "OnionTraffic")) {
- onion_traffic = ! no;
+ cfg->entry_cfg.onion_traffic = ! no;
continue;
} else if (!strcasecmp(elt, "OnionTrafficOnly")) {
/* Only connect to .onion addresses. Equivalent to
@@ -6338,46 +6058,50 @@ port_parse_config(smartlist_t *out,
"DNSRequest, IPv4Traffic, and/or IPv6Traffic instead.",
portname, escaped(elt));
} else {
- ipv4_traffic = ipv6_traffic = dns_request = 0;
+ cfg->entry_cfg.ipv4_traffic = 0;
+ cfg->entry_cfg.ipv6_traffic = 0;
+ cfg->entry_cfg.dns_request = 0;
}
continue;
}
}
if (!strcasecmp(elt, "CacheIPv4DNS")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- cache_ipv4 = ! no;
+ cfg->entry_cfg.cache_ipv4_answers = ! no;
continue;
} else if (!strcasecmp(elt, "CacheIPv6DNS")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- cache_ipv6 = ! no;
+ cfg->entry_cfg.cache_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "CacheDNS")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- cache_ipv4 = cache_ipv6 = ! no;
+ cfg->entry_cfg.cache_ipv4_answers = ! no;
+ cfg->entry_cfg.cache_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "UseIPv4Cache")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- use_cached_ipv4 = ! no;
+ cfg->entry_cfg.use_cached_ipv4_answers = ! no;
continue;
} else if (!strcasecmp(elt, "UseIPv6Cache")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- use_cached_ipv6 = ! no;
+ cfg->entry_cfg.use_cached_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "UseDNSCache")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- use_cached_ipv4 = use_cached_ipv6 = ! no;
+ cfg->entry_cfg.use_cached_ipv4_answers = ! no;
+ cfg->entry_cfg.use_cached_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "PreferIPv6Automap")) {
- prefer_ipv6_automap = ! no;
+ cfg->entry_cfg.prefer_ipv6_virtaddr = ! no;
continue;
} else if (!strcasecmp(elt, "PreferSOCKSNoAuth")) {
- prefer_no_auth = ! no;
+ cfg->entry_cfg.socks_prefer_no_auth = ! no;
continue;
} else if (!strcasecmp(elt, "KeepAliveIsolateSOCKSAuth")) {
- socks_iso_keep_alive = ! no;
+ cfg->entry_cfg.socks_iso_keep_alive = ! no;
continue;
} else if (!strcasecmp(elt, "ExtendedErrors")) {
- extended_errors = ! no;
+ cfg->entry_cfg.extended_socks5_codes = ! no;
continue;
}
@@ -6400,9 +6124,9 @@ port_parse_config(smartlist_t *out,
}
if (no) {
- isolation &= ~isoflag;
+ cfg->entry_cfg.isolation_flags &= ~isoflag;
} else {
- isolation |= isoflag;
+ cfg->entry_cfg.isolation_flags |= isoflag;
}
} SMARTLIST_FOREACH_END(elt);
}
@@ -6412,51 +6136,51 @@ port_parse_config(smartlist_t *out,
else
got_zero_port = 1;
- if (dns_request == 0 && listener_type == CONN_TYPE_AP_DNS_LISTENER) {
+ if (cfg->entry_cfg.dns_request == 0 &&
+ listener_type == CONN_TYPE_AP_DNS_LISTENER) {
log_warn(LD_CONFIG, "You have a %sPort entry with DNS disabled; that "
"won't work.", portname);
goto err;
}
-
- if (ipv4_traffic == 0 && ipv6_traffic == 0 && onion_traffic == 0
- && listener_type != CONN_TYPE_AP_DNS_LISTENER) {
+ if (cfg->entry_cfg.ipv4_traffic == 0 &&
+ cfg->entry_cfg.ipv6_traffic == 0 &&
+ cfg->entry_cfg.onion_traffic == 0 &&
+ listener_type != CONN_TYPE_AP_DNS_LISTENER) {
log_warn(LD_CONFIG, "You have a %sPort entry with all of IPv4 and "
"IPv6 and .onion disabled; that won't work.", portname);
goto err;
}
-
- if (dns_request == 1 && ipv4_traffic == 0 && ipv6_traffic == 0
- && listener_type != CONN_TYPE_AP_DNS_LISTENER) {
+ if (cfg->entry_cfg.dns_request == 1 &&
+ cfg->entry_cfg.ipv4_traffic == 0 &&
+ cfg->entry_cfg.ipv6_traffic == 0 &&
+ listener_type != CONN_TYPE_AP_DNS_LISTENER) {
log_warn(LD_CONFIG, "You have a %sPort entry with DNSRequest enabled, "
"but IPv4 and IPv6 disabled; DNS-based sites won't work.",
portname);
goto err;
}
-
- if ( has_used_unix_socket_only_option && ! unix_socket_path) {
+ if (has_used_unix_socket_only_option && !unix_socket_path) {
log_warn(LD_CONFIG, "You have a %sPort entry with GroupWritable, "
"WorldWritable, or RelaxDirModeCheck, but it is not a "
"unix socket.", portname);
goto err;
}
-
- if (!(isolation & ISO_SOCKSAUTH) && socks_iso_keep_alive) {
+ if (!(cfg->entry_cfg.isolation_flags & ISO_SOCKSAUTH) &&
+ cfg->entry_cfg.socks_iso_keep_alive) {
log_warn(LD_CONFIG, "You have a %sPort entry with both "
"NoIsolateSOCKSAuth and KeepAliveIsolateSOCKSAuth set.",
portname);
goto err;
}
-
- if (unix_socket_path && (isolation & ISO_CLIENTADDR)) {
+ if (unix_socket_path &&
+ (cfg->entry_cfg.isolation_flags & ISO_CLIENTADDR)) {
/* `IsolateClientAddr` is nonsensical in the context of AF_LOCAL.
* just silently remove the isolation flag.
*/
- isolation &= ~ISO_CLIENTADDR;
+ cfg->entry_cfg.isolation_flags &= ~ISO_CLIENTADDR;
}
-
if (out && port) {
size_t namelen = unix_socket_path ? strlen(unix_socket_path) : 0;
- port_cfg_t *cfg = port_cfg_new(namelen);
if (unix_socket_path) {
tor_addr_make_unspec(&cfg->addr);
memcpy(cfg->unix_addr, unix_socket_path, namelen + 1);
@@ -6467,33 +6191,13 @@ port_parse_config(smartlist_t *out,
cfg->port = port;
}
cfg->type = listener_type;
- cfg->is_world_writable = world_writable;
- cfg->is_group_writable = group_writable;
- cfg->relax_dirmode_check = relax_dirmode_check;
- cfg->entry_cfg.isolation_flags = isolation;
- cfg->entry_cfg.session_group = sessiongroup;
- cfg->server_cfg.no_advertise = no_advertise;
- cfg->server_cfg.no_listen = no_listen;
- cfg->server_cfg.all_addrs = all_addrs;
- cfg->server_cfg.bind_ipv4_only = bind_ipv4_only;
- cfg->server_cfg.bind_ipv6_only = bind_ipv6_only;
- cfg->entry_cfg.ipv4_traffic = ipv4_traffic;
- cfg->entry_cfg.ipv6_traffic = ipv6_traffic;
- cfg->entry_cfg.prefer_ipv6 = prefer_ipv6;
- cfg->entry_cfg.dns_request = dns_request;
- cfg->entry_cfg.onion_traffic = onion_traffic;
- cfg->entry_cfg.cache_ipv4_answers = cache_ipv4;
- cfg->entry_cfg.cache_ipv6_answers = cache_ipv6;
- cfg->entry_cfg.use_cached_ipv4_answers = use_cached_ipv4;
- cfg->entry_cfg.use_cached_ipv6_answers = use_cached_ipv6;
- cfg->entry_cfg.prefer_ipv6_virtaddr = prefer_ipv6_automap;
- cfg->entry_cfg.socks_prefer_no_auth = prefer_no_auth;
- if (! (isolation & ISO_SOCKSAUTH))
+ if (! (cfg->entry_cfg.isolation_flags & ISO_SOCKSAUTH))
cfg->entry_cfg.socks_prefer_no_auth = 1;
- cfg->entry_cfg.socks_iso_keep_alive = socks_iso_keep_alive;
- cfg->entry_cfg.extended_socks5_codes = extended_errors;
-
smartlist_add(out, cfg);
+ /* out owns cfg now, don't re-use or free it */
+ cfg = NULL;
+ } else {
+ tor_free(cfg);
}
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
smartlist_clear(elts);
@@ -6519,10 +6223,22 @@ port_parse_config(smartlist_t *out,
retval = 0;
err:
+ /* There are two ways we can error out:
+ * 1. part way through the loop: cfg needs to be freed;
+ * 2. ending the loop normally: cfg is always NULL.
+ * In this case, cfg has either been:
+ * - added to out, then set to NULL, or
+ * - freed and set to NULL (because out is NULL, or port is 0).
+ */
+ tor_free(cfg);
+
+ /* Free the other variables from the loop.
+ * elts is always non-NULL here, but it may or may not be empty. */
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
smartlist_free(elts);
tor_free(unix_socket_path);
tor_free(addrport);
+
return retval;
}