Commit f88c3038 authored by George Kadianakis's avatar George Kadianakis Committed by Nick Mathewson
Browse files

Add a torrc option to specify the bind address of managed proxies.

parent 848333c6
o Minor features:
- Add a new torrc option 'ServerTransportListenAddr' which allows
users to select the address where their pluggable transports
will listen for connections.
...@@ -181,6 +181,11 @@ GENERAL OPTIONS ...@@ -181,6 +181,11 @@ GENERAL OPTIONS
using __options__ as its command-line options, and expects to receive using __options__ as its command-line options, and expects to receive
proxied client traffic from it. proxied client traffic from it.
**ServerTransportListenAddr** __transport__ __IP__:__PORT__::
When this option is set, Tor will suggest __IP__:__PORT__ as the
listening address of any pluggable transport proxy that tries to
launch __transport__.
**ConnLimit** __NUM__:: **ConnLimit** __NUM__::
The minimum number of file descriptors that must be available to the Tor The minimum number of file descriptors that must be available to the Tor
process before it will start. Tor will ask the OS for as many file process before it will start. Tor will ask the OS for as many file
......
...@@ -273,6 +273,7 @@ static config_var_t option_vars_[] = { ...@@ -273,6 +273,7 @@ static config_var_t option_vars_[] = {
V(HTTPSProxy, STRING, NULL), V(HTTPSProxy, STRING, NULL),
V(HTTPSProxyAuthenticator, STRING, NULL), V(HTTPSProxyAuthenticator, STRING, NULL),
VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL), VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL),
V(ServerTransportListenAddr, LINELIST, NULL),
V(Socks4Proxy, STRING, NULL), V(Socks4Proxy, STRING, NULL),
V(Socks5Proxy, STRING, NULL), V(Socks5Proxy, STRING, NULL),
V(Socks5ProxyUsername, STRING, NULL), V(Socks5ProxyUsername, STRING, NULL),
...@@ -462,6 +463,9 @@ static int parse_bridge_line(const char *line, int validate_only); ...@@ -462,6 +463,9 @@ static int parse_bridge_line(const char *line, int validate_only);
static int parse_client_transport_line(const char *line, int validate_only); static int parse_client_transport_line(const char *line, int validate_only);
static int parse_server_transport_line(const char *line, int validate_only); static int parse_server_transport_line(const char *line, int validate_only);
static char *get_bindaddr_from_transport_listen_line(const char *line,
const char *transport);
static int parse_dir_server_line(const char *line, static int parse_dir_server_line(const char *line,
dirinfo_type_t required_type, dirinfo_type_t required_type,
int validate_only); int validate_only);
...@@ -2879,6 +2883,22 @@ options_validate(or_options_t *old_options, or_options_t *options, ...@@ -2879,6 +2883,22 @@ options_validate(or_options_t *old_options, or_options_t *options,
escaped(options->ServerTransportPlugin->value)); escaped(options->ServerTransportPlugin->value));
} }
for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
/** If get_bindaddr_from_transport_listen_line() fails with
'transport' being NULL, it means that something went wrong
while parsing the ServerTransportListenAddr line. */
char *bindaddr = get_bindaddr_from_transport_listen_line(cl->value, NULL);
if (!bindaddr)
REJECT("ServerTransportListenAddr did not parse. See logs for details.");
tor_free(bindaddr);
}
if (options->ServerTransportListenAddr && !options->ServerTransportPlugin) {
log_notice(LD_GENERAL, "You need at least a single managed-proxy to "
"specify a transport listen address. The "
"ServerTransportListenAddr line will be ignored.");
}
if (options->ConstrainedSockets) { if (options->ConstrainedSockets) {
/* If the user wants to constrain socket buffer use, make sure the desired /* If the user wants to constrain socket buffer use, make sure the desired
* limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */ * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
...@@ -4117,6 +4137,87 @@ parse_client_transport_line(const char *line, int validate_only) ...@@ -4117,6 +4137,87 @@ parse_client_transport_line(const char *line, int validate_only)
return r; return r;
} }
/** Given a ServerTransportListenAddr <b>line</b>, return its
* <address:port> string. Return NULL if the line was not
* well-formed.
*
* If <b>transport</b> is set, return NULL if the line is not
* referring to <b>transport</b>.
*
* The returned string is allocated on the heap and it's the
* responsibility of the caller to free it. */
static char *
get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
{
smartlist_t *items = NULL;
const char *parsed_transport = NULL;
char *addrport = NULL;
char *addr = NULL;
uint16_t port = 0;
items = smartlist_new();
smartlist_split_string(items, line, NULL,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
if (smartlist_len(items) < 2) {
log_warn(LD_CONFIG,"Too few arguments on ServerTransportListenAddr line.");
goto err;
}
parsed_transport = smartlist_get(items, 0);
addrport = tor_strdup(smartlist_get(items, 1));
/* If 'transport' is given, check if it matches the one on the line */
if (transport && strcmp(transport, parsed_transport))
goto err;
/* Validate addrport */
if (tor_addr_port_split(LOG_WARN, addrport, &addr, &port)<0) {
log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr "
"address '%s'", addrport);
goto err;
}
if (!port) {
log_warn(LD_CONFIG,
"ServerTransportListenAddr address '%s' has no port.", addrport);
goto err;
}
goto done;
err:
tor_free(addrport);
addrport = NULL;
done:
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
smartlist_free(items);
tor_free(addr);
return addrport;
}
/** Given the name of a pluggable transport in <b>transport</b>, check
* the configuration file to see if the user has explicitly asked for
* it to listen on a specific port. Return a <address:port> string if
* so, otherwise NULL. */
char *
get_transport_bindaddr_from_config(const char *transport)
{
config_line_t *cl;
const or_options_t *options = get_options();
for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
char *bindaddr =
get_bindaddr_from_transport_listen_line(cl->value, transport);
if (bindaddr)
return bindaddr;
}
return NULL;
}
/** Read the contents of a ServerTransportPlugin line from /** Read the contents of a ServerTransportPlugin line from
* <b>line</b>. Return 0 if the line is well-formed, and -1 if it * <b>line</b>. Return 0 if the line is well-formed, and -1 if it
* isn't. * isn't.
......
...@@ -82,6 +82,8 @@ const char *tor_get_digests(void); ...@@ -82,6 +82,8 @@ const char *tor_get_digests(void);
uint32_t get_effective_bwrate(const or_options_t *options); uint32_t get_effective_bwrate(const or_options_t *options);
uint32_t get_effective_bwburst(const or_options_t *options); uint32_t get_effective_bwburst(const or_options_t *options);
char *get_transport_bindaddr_from_config(const char *transport);
#ifdef CONFIG_PRIVATE #ifdef CONFIG_PRIVATE
/* Used only by config.c and test.c */ /* Used only by config.c and test.c */
or_options_t *options_new(void); or_options_t *options_new(void);
......
...@@ -3218,6 +3218,9 @@ typedef struct { ...@@ -3218,6 +3218,9 @@ typedef struct {
config_line_t *ServerTransportPlugin; /**< List of client config_line_t *ServerTransportPlugin; /**< List of client
transport plugins. */ transport plugins. */
/** List of TCP/IP addresses that transports should listen at. */
config_line_t *ServerTransportListenAddr;
int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make
* this explicit so we can change how we behave in the * this explicit so we can change how we behave in the
* future. */ * future. */
......
...@@ -517,8 +517,17 @@ get_stored_bindaddr_for_server_transport(const char *transport) ...@@ -517,8 +517,17 @@ get_stored_bindaddr_for_server_transport(const char *transport)
{ {
char *default_addrport = NULL; char *default_addrport = NULL;
const char *stored_bindaddr = NULL; const char *stored_bindaddr = NULL;
config_line_t *line = NULL;
{
/* See if the user explicitly asked for a specific listening
address for this transport. */
char *conf_bindaddr = get_transport_bindaddr_from_config(transport);
if (conf_bindaddr)
return conf_bindaddr;
}
config_line_t *line = get_transport_in_state_by_name(transport); line = get_transport_in_state_by_name(transport);
if (!line) /* Found no references in state for this transport. */ if (!line) /* Found no references in state for this transport. */
goto no_bindaddr_found; goto no_bindaddr_found;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment