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

Write function that parses ServerTransportOptions torrc lines.

And use it to validate them.
parent 9fda7e8c
......@@ -280,6 +280,7 @@ static config_var_t option_vars_[] = {
V(IPv6Exit, BOOL, "0"),
VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL),
V(ServerTransportListenAddr, LINELIST, NULL),
V(ServerTransportOptions, LINELIST, NULL),
V(Socks4Proxy, STRING, NULL),
V(Socks5Proxy, STRING, NULL),
V(Socks5ProxyUsername, STRING, NULL),
......@@ -3147,6 +3148,19 @@ options_validate(or_options_t *old_options, or_options_t *options,
"ServerTransportListenAddr line will be ignored.");
for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
/** If get_options_from_transport_options_line() fails with
'transport' being NULL, it means that something went wrong
while parsing the ServerTransportOptions line. */
smartlist_t *options_sl =
get_options_from_transport_options_line(cl->value, NULL);
if (!options_sl)
REJECT("ServerTransportOptions did not parse. See logs for details.");
SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp));
if (options->ConstrainedSockets) {
/* If the user wants to constrain socket buffer use, make sure the desired
* limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
......@@ -4580,6 +4594,63 @@ get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
return addrport;
/** Given a ServerTransportOptions <b>line</b>, return a smartlist
* with the options. 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 smartlist and its strings are allocated on the heap
* and it's the responsibility of the caller to free it. */
smartlist_t *
get_options_from_transport_options_line(const char *line,const char *transport)
smartlist_t *items = smartlist_new();
smartlist_t *options = smartlist_new();
const char *parsed_transport = NULL;
smartlist_split_string(items, line, NULL,
if (smartlist_len(items) < 2) {
log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line.");
goto err;
parsed_transport = smartlist_get(items, 0);
/* If 'transport' is given, check if it matches the one on the line */
if (transport && strcmp(transport, parsed_transport))
goto err;
SMARTLIST_FOREACH_BEGIN(items, const char *, option) {
if (option_sl_idx == 0) /* skip the transport field (first field)*/
/* validate that it's a k=v value */
if (!string_is_key_value(LOG_WARN, option)) {
log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option));
goto err;
/* add it to the options smartlist */
smartlist_add(options, tor_strdup(option));
log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option));
goto done;
SMARTLIST_FOREACH(options, char*, s, tor_free(s));
options = NULL;
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
return options;
/** 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
......@@ -112,6 +112,9 @@ typedef struct bridge_line_t {
void bridge_line_free(bridge_line_t *bridge_line);
bridge_line_t *parse_bridge_line(const char *line);
smartlist_t *get_options_from_transport_options_line(const char *line,
const char *transport);
......@@ -3500,6 +3500,9 @@ typedef struct {
/** List of TCP/IP addresses that transports should listen at. */
config_line_t *ServerTransportListenAddr;
/** List of options that must be passed to pluggable transports. */
config_line_t *ServerTransportOptions;
int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make
* this explicit so we can change how we behave in the
* future. */
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