int r;
char *field2=NULL;
- const char *name=NULL;
+ const char *transports=NULL;
+ smartlist_t *transport_list=NULL;
char *addrport=NULL;
tor_addr_t addr;
uint16_t port = 0;
goto err;
}
- name = smartlist_get(items, 0);
- if (!string_is_C_identifier(name)) {
- log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).", name);
- goto err;
- }
+ /* Get the first line element, split it to commas into
+ transport_list (in case it's multiple transports) and validate
+ the transport names. */
+ transports = smartlist_get(items, 0);
+ transport_list = smartlist_create();
+ smartlist_split_string(transport_list, transports, ",",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
+ if (!string_is_C_identifier(transport_name)) {
+ log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
+ transport_name);
+ goto err;
+ }
+ } SMARTLIST_FOREACH_END(transport_name);
/* field2 is either a SOCKS version or "exec" */
field2 = smartlist_get(items, 1);
*tmp = NULL; /*terminated with NUL pointer, just like execve() likes it*/
/* kickstart the thing */
- pt_kickstart_client_proxy(name, proxy_argv);
+ pt_kickstart_client_proxy(transport_list, proxy_argv);
}
} else { /* external */
+ if (smartlist_len(transport_list) != 1) {
+ log_warn(LD_CONFIG, "You can't have an external proxy with "
+ "more than one transports.");
+ goto err;
+ }
+
addrport = smartlist_get(items, 2);
if (tor_addr_port_parse(addrport, &addr, &port)<0) {
}
if (!validate_only) {
- transport_add_from_config(&addr, port, name, socks_ver);
+ transport_add_from_config(&addr, port, smartlist_get(transport_list, 0),
+ socks_ver);
- log_info(LD_DIR, "Transport '%s' found at %s:%d", name,
- fmt_addr(&addr), (int)port);
+ log_info(LD_DIR, "Transport '%s' found at %s:%d",
+ transports, fmt_addr(&addr), (int)port);
}
}
done:
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
smartlist_free(items);
+ SMARTLIST_FOREACH(transport_list, char*, s, tor_free(s));
+ smartlist_free(transport_list);
+
return r;
}
{
smartlist_t *items = NULL;
int r;
- const char *name=NULL;
+ const char *transports=NULL;
+ smartlist_t *transport_list=NULL;
char *type=NULL;
char *addrport=NULL;
tor_addr_t addr;
goto err;
}
- name = smartlist_get(items, 0);
- if (!string_is_C_identifier(name)) {
- log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).", name);
- goto err;
- }
+ /* Get the first line element, split it to commas into
+ transport_list (in case it's multiple transports) and validate
+ the transport names. */
+ transports = smartlist_get(items, 0);
+ transport_list = smartlist_create();
+ smartlist_split_string(transport_list, transports, ",",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
+ if (!string_is_C_identifier(transport_name)) {
+ log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
+ transport_name);
+ goto err;
+ }
+ } SMARTLIST_FOREACH_END(transport_name);
type = smartlist_get(items, 1);
*tmp = NULL; /*terminated with NUL pointer, just like execve() likes it*/
/* kickstart the thing */
- pt_kickstart_server_proxy(name, proxy_argv);
+ pt_kickstart_server_proxy(transport_list, proxy_argv);
}
} else { /* external */
+ if (smartlist_len(transport_list) != 1) {
+ log_warn(LD_CONFIG, "You can't have an external proxy with "
+ "more than one transports.");
+ goto err;
+ }
+
addrport = smartlist_get(items, 2);
if (tor_addr_port_parse(addrport, &addr, &port)<0) {
}
if (!validate_only) {
- log_info(LD_DIR, "Server transport '%s' at %s:%d.", name,
- fmt_addr(&addr), (int)port);
+ log_info(LD_DIR, "Server transport '%s' at %s:%d.",
+ transports, fmt_addr(&addr), (int)port);
}
}
done:
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
smartlist_free(items);
+ SMARTLIST_FOREACH(transport_list, char*, s, tor_free(s));
+ smartlist_free(transport_list);
+
return r;
}
}
return 0;
}
+
* <b>proxy_argv</b>. If <b>is_server</b> is true, it's a server
* managed proxy. */
static managed_proxy_t *
-managed_proxy_create(const char *transport, char **proxy_argv, int is_server)
+managed_proxy_create(const smartlist_t *transport_list,
+ char **proxy_argv, int is_server)
{
managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
mp->conf_state = PT_PROTO_INFANT;
mp->transports = smartlist_create();
mp->transports_to_launch = smartlist_create();
- add_transport_to_proxy(transport, mp);
+ SMARTLIST_FOREACH(transport_list, const char *, transport,
+ add_transport_to_proxy(transport, mp));
/* register the managed proxy */
if (!managed_proxy_list)
* the managed proxy subsystem.
* If <b>is_server</b> is true, then the proxy is a server proxy. */
void
-pt_kickstart_proxy(const char *transport, char **proxy_argv, int is_server)
+pt_kickstart_proxy(const smartlist_t *transport_list,
+ char **proxy_argv, int is_server)
{
managed_proxy_t *mp=NULL;
transport_t *old_transport = NULL;
mp = get_managed_proxy_by_argv_and_type(proxy_argv, is_server);
if (!mp) { /* we haven't seen this proxy before */
- managed_proxy_create(transport, proxy_argv, is_server);
+ managed_proxy_create(transport_list, proxy_argv, is_server);
} else { /* known proxy. add its transport to its transport list */
if (mp->got_hup) {
unconfigured_proxies_n++;
}
- old_transport = transport_get_by_name(transport);
- if (old_transport)
- old_transport->marked_for_removal = 0;
+ SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport) {
+ old_transport = transport_get_by_name(transport);
+ if (old_transport)
+ old_transport->marked_for_removal = 0;
+ } SMARTLIST_FOREACH_END(transport);
}
- add_transport_to_proxy(transport, mp);
+ SMARTLIST_FOREACH(transport_list, const char *, transport,
+ add_transport_to_proxy(transport, mp));
free_execve_args(proxy_argv);
}
}