commit 16386a8cd15997acebdc1bd4ee047274b5c2730a Author: teor (Tim Wilson-Brown) teor2345@gmail.com Date: Mon Jul 11 13:12:10 2016 +1000
Count unix sockets when counting client listeners
Users can't run an anonymous client and non-anonymous single onion service at the same time. We need to know whether we have any client ports or sockets open to do this check.
When determining whether a client port (SOCKS, Trans, NATD, DNS) is set, count unix sockets when counting client listeners. This has no user-visible behaviour change, because these options are set once and never read in the current tor codebase.
Don't count sockets when setting ControlPort_set, that's what ControlSocket is for. (This will be reviewed in #19665.)
Don't count sockets when counting server listeners, because the code that uses these options expects to count externally-visible ports. (And it would change the behaviour of Tor.) --- changes/bug19677 | 6 ++++++ src/or/config.c | 33 ++++++++++++++++++--------------- src/or/or.h | 10 +++++++--- 3 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/changes/bug19677 b/changes/bug19677 new file mode 100644 index 0000000..e8ba3dd --- /dev/null +++ b/changes/bug19677 @@ -0,0 +1,6 @@ + o Minor bug fixes (option parsing): + - Count unix sockets when counting client listeners (SOCKS, Trans, + NATD, and DNS). This has no user-visible behaviour changes: these + options are set once, and never read. + Required for correct behaviour in ticket #17178. + Fixes bug #19677, patch by teor. diff --git a/src/or/config.c b/src/or/config.c index 98b3270..136958c 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -6739,14 +6739,17 @@ parse_port_config(smartlist_t *out, }
/** Return the number of ports which are actually going to listen with type - * <b>listenertype</b>. Do not count no_listen ports. Do not count unix - * sockets. */ + * <b>listenertype</b>. Do not count no_listen ports. Only count unix + * sockets if count_sockets is true. */ static int -count_real_listeners(const smartlist_t *ports, int listenertype) +count_real_listeners(const smartlist_t *ports, int listenertype, + int count_sockets) { int n = 0; SMARTLIST_FOREACH_BEGIN(ports, port_cfg_t *, port) { - if (port->server_cfg.no_listen || port->is_unix_addr) + if (port->server_cfg.no_listen) + continue; + if (!count_sockets && port->is_unix_addr) continue; if (port->type != listenertype) continue; @@ -6755,9 +6758,8 @@ count_real_listeners(const smartlist_t *ports, int listenertype) return n; }
-/** Parse all client port types (Socks, DNS, Trans, NATD) from - * <b>options</b>. On success, set *<b>n_ports_out</b> to the number - * of ports that are listed, update the *Port_set values in +/** Parse all ports from <b>options</b>. On success, set *<b>n_ports_out</b> + * to the number of ports that are listed, update the *Port_set values in * <b>options</b>, and return 0. On failure, set *<b>msg</b> to a * description of the problem and return -1. * @@ -6883,21 +6885,22 @@ parse_ports(or_options_t *options, int validate_only, /* Update the *Port_set options. The !! here is to force a boolean out of an integer. */ options->ORPort_set = - !! count_real_listeners(ports, CONN_TYPE_OR_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_OR_LISTENER, 0); options->SocksPort_set = - !! count_real_listeners(ports, CONN_TYPE_AP_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_AP_LISTENER, 1); options->TransPort_set = - !! count_real_listeners(ports, CONN_TYPE_AP_TRANS_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_AP_TRANS_LISTENER, 1); options->NATDPort_set = - !! count_real_listeners(ports, CONN_TYPE_AP_NATD_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_AP_NATD_LISTENER, 1); + /* Use options->ControlSocket to test if a control socket is set */ options->ControlPort_set = - !! count_real_listeners(ports, CONN_TYPE_CONTROL_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_CONTROL_LISTENER, 0); options->DirPort_set = - !! count_real_listeners(ports, CONN_TYPE_DIR_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_DIR_LISTENER, 0); options->DNSPort_set = - !! count_real_listeners(ports, CONN_TYPE_AP_DNS_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_AP_DNS_LISTENER, 1); options->ExtORPort_set = - !! count_real_listeners(ports, CONN_TYPE_EXT_OR_LISTENER); + !! count_real_listeners(ports, CONN_TYPE_EXT_OR_LISTENER, 0);
if (world_writable_control_socket) { SMARTLIST_FOREACH(ports, port_cfg_t *, p, diff --git a/src/or/or.h b/src/or/or.h index 34089ad..574f184 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3604,9 +3604,13 @@ typedef struct {
/** @name port booleans * - * Derived booleans: True iff there is a non-listener port on an AF_INET or - * AF_INET6 address of the given type configured in one of the _lines - * options above. + * Derived booleans: For server ports and ControlPort, true iff there is a + * non-listener port on an AF_INET or AF_INET6 address of the given type + * configured in one of the _lines options above. + * For client ports, also true if there is a unix socket configured. + * If you are checking for client ports, you may want to use: + * SocksPort_set || TransPort_set || NATDPort_set || DNSPort_set + * rather than SocksPort_set. * * @{ */
tor-commits@lists.torproject.org