commit 6ce862fda29539e8c11536ff1728d2553c9a862b Author: George Kadianakis desnacked@gmail.com Date: Sat Aug 20 06:47:22 2011 +0200
Reorder managed.c.
No functions were altered during this commit. --- src/managed.c | 622 ++++++++++++++++++++++++++++----------------------------- 1 files changed, 301 insertions(+), 321 deletions(-)
diff --git a/src/managed.c b/src/managed.c index 979bc38..4178b97 100644 --- a/src/managed.c +++ b/src/managed.c @@ -70,73 +70,11 @@ enum launch_status { #define PROTO_CMETHODS_DONE "CMETHODS DONE\n" #define PROTO_SMETHODS_DONE "SMETHODS DONE\n"
-static int handle_environment(managed_proxy_t *proxy); -static int conf_proto_version_negotiation(const managed_proxy_t *proxy); -static int launch_listeners(const managed_proxy_t *proxy); -static void print_method_line(const char *transport, - const managed_proxy_t *proxy, - config_t *cfg); -static void print_method_error_line(const char *protocol, - const managed_proxy_t *proxy, - enum launch_status status); -static const char *get_launch_error_message(enum launch_status status); - -static void print_method_done_line(const managed_proxy_t *proxy); - -static const char *get_env_parsing_error_message(enum env_parsing_status status); - -static void proxy_free(managed_proxy_t *proxy); -static int is_supported_conf_protocol(const char *name); -static void print_protocol_line(const char *format, ...); - -static int validate_environment(managed_proxy_t *proxy); - const char *supported_conf_protocols[] = { "1" }; const size_t n_supported_conf_protocols = sizeof(supported_conf_protocols)/sizeof(supported_conf_protocols[0]);
/** - This function fires up the managed proxy. - It first reads the environment that tor should have prepared, and then - launches the appropriate listeners. - - Returns 0 if we managed to launch at least one proxy, - returns -1 if something went wrong or we didn't launch any proxies. -*/ -int -launch_managed_proxy(void) -{ - int r=-1; - managed_proxy_t *proxy = xzalloc(sizeof(managed_proxy_t)); - proxy->configs = smartlist_create(); - - obfsproxy_init(); - - if (handle_environment(proxy) < 0) - goto done; - - if (validate_environment(proxy) < 0) - goto done; - - if (conf_proto_version_negotiation(proxy) < 0) - goto done; - - if (launch_listeners(proxy) < 0) - goto done; - - /* Kickstart libevent */ - event_base_dispatch(get_event_base()); - - r=0; - - done: - obfsproxy_cleanup(); - proxy_free(proxy); - - return r; -} - -/** Make sure that we got *all* the necessary environment variables off tor. */ static inline void @@ -159,180 +97,40 @@ assert_proxy_env(managed_proxy_t *proxy) }
/** - Validates the environment variables that we got off tor. -*/ -static int -validate_environment(managed_proxy_t *proxy) -{ - enum env_parsing_status status; - - assert_proxy_env(proxy); - - if (proxy->is_server) { - if (validate_bindaddrs(proxy->vars.bindaddrs, proxy->vars.transports) < 0) { - status = ST_ENV_FAIL_BINDADDR; - goto err; - } - } - - return 0; - - err: - print_protocol_line("%s %s\n", PROTO_ENV_ERROR, - get_env_parsing_error_message(status)); - - return -1; -} - -/** - Free memory allocated by 'proxy'. + This function is used for obfsproxy to communicate with tor. + Practically a wrapper of printf, it prints 'format' and the + fflushes stdout so that the output is always immediately available + to tor. */ static void -proxy_free(managed_proxy_t *proxy) -{ - free(proxy->vars.state_loc); - free(proxy->vars.conf_proto_version); - free(proxy->vars.transports); - free(proxy->vars.extended_port); - free(proxy->vars.or_port); - free(proxy->vars.bindaddrs); - - SMARTLIST_FOREACH(proxy->configs, config_t *, cfg, config_free(cfg)); - smartlist_free(proxy->configs); - - free(proxy); -} - -/** - Given a smartlist of listener configs; launch them all and print - method lines as appropriate. Return 0 if at least a listener was - spawned, -1 otherwise. -*/ -static int -open_listeners_managed(const managed_proxy_t *proxy) +print_protocol_line(const char *format, ...) { - int ret=-1; - const char *transport; - - /* Open listeners for each configuration. */ - SMARTLIST_FOREACH_BEGIN(proxy->configs, config_t *, cfg) { - transport = get_transport_name_from_config(cfg); - - if (open_listeners(get_event_base(), cfg)) { - ret=0; /* success! launched at least one listener. */ - print_method_line(transport, proxy, cfg); - } else { /* fail. print a method error line. */ - print_method_error_line(transport, proxy, ST_LAUNCH_FAIL_LSN); - } - } SMARTLIST_FOREACH_END(cfg); - - return ret; + va_list ap; + va_start(ap,format); + vprintf(format, ap); + fflush(stdout); + va_end(ap); }
/** - Launch all server listeners that tor wants us to launch. + Return a string containing the error we encountered while parsing + the environment variables, according to 'status'. */ -static int -launch_server_listeners(const managed_proxy_t *proxy) +static inline const char * +get_env_parsing_error_message(enum env_parsing_status status) { - int ret=-1; - int i, n_transports; - const char *transport = NULL; - const char *bindaddr_temp = NULL; - const char *bindaddr = NULL; - config_t *cfg = NULL; - - /* list of transports */ - smartlist_t *transports = smartlist_create(); - /* a list of "<transport>-<bindaddr>" strings */ - smartlist_t *bindaddrs = smartlist_create(); - - /* split the comma-separated transports/bindaddrs to their smartlists */ - smartlist_split_string(transports, proxy->vars.transports, ",", - SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); - smartlist_split_string(bindaddrs, proxy->vars.bindaddrs, ",", - SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); - - n_transports = smartlist_len(transports); - - /* Iterate transports; match them with their bindaddr; create their - config_t. */ - for (i=0;i<n_transports;i++) { - transport = smartlist_get(transports, i); - bindaddr_temp = smartlist_get(bindaddrs, i); - - obfs_assert(strlen(bindaddr_temp) > strlen(transport)+1); - - bindaddr = bindaddr_temp+strlen(transport)+1; /* +1 for the dash */ - - cfg = config_create_managed(proxy->is_server, - transport, bindaddr, proxy->vars.or_port); - if (cfg) /* if a config was created; put it in the config smartlist */ - smartlist_add(proxy->configs, cfg); - else /* otherwise, spit a method error line */ - print_method_error_line(transport, proxy, ST_LAUNCH_FAIL_SETUP); + switch(status) { + case ST_ENV_SMOOTH: return "no error"; + case ST_ENV_FAIL_STATE_LOC: return "failed on TOR_PT_STATE_LOCATION"; + case ST_ENV_FAIL_CONF_PROTO_VER: return "failed on TOR_PT_MANAGED_TRANSPORT_VER"; + case ST_ENV_FAIL_CLIENT_TRANSPORTS: return "failed on TOR_PT_CLIENT_TRANSPORTS"; + case ST_ENV_FAIL_EXTENDED_PORT: return "failed on TOR_PT_EXTENDED_SERVER_PORT"; + case ST_ENV_FAIL_ORPORT: return "failed on TOR_PT_ORPORT"; + case ST_ENV_FAIL_BINDADDR: return "failed on TOR_PT_SERVER_BINDADDR"; + case ST_ENV_FAIL_SERVER_TRANSPORTS: return "failed on TOR_PT_SERVER_TRANSPORTS"; + default: + obfs_assert(0); return "UNKNOWN"; } - - /* open listeners */ - ret = open_listeners_managed(proxy); - - SMARTLIST_FOREACH(bindaddrs, char *, cp, free(cp)); - smartlist_free(bindaddrs); - SMARTLIST_FOREACH(transports, char *, cp, free(cp)); - smartlist_free(transports); - - print_method_done_line(proxy); /* print {C,S}METHODS DONE */ - - return ret; -} - -/** - Launch all client listeners that tor wants us to launch. -*/ -static int -launch_client_listeners(const managed_proxy_t *proxy) -{ - int ret=-1; - config_t *cfg = NULL; - - /* list of transports */ - smartlist_t *transports = smartlist_create(); - - smartlist_split_string(transports, proxy->vars.transports, ",", - SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); - - SMARTLIST_FOREACH_BEGIN(transports, char *, transport) { - /* clients should find their own listen port */ - cfg = config_create_managed(proxy->is_server, - transport, "127.0.0.1:0", proxy->vars.or_port); - if (cfg) /* if config was created; put it in the config smartlist */ - smartlist_add(proxy->configs, cfg); - else - print_method_error_line(transport, proxy, ST_LAUNCH_FAIL_SETUP); - } SMARTLIST_FOREACH_END(transport); - - /* open listeners */ - ret = open_listeners_managed(proxy); - - SMARTLIST_FOREACH(transports, char *, cp, free(cp)); - smartlist_free(transports); - - print_method_done_line(proxy); /* print {C,S}METHODS DONE */ - - return ret; -} - -/** - Launch all listeners that tor wants us to launch. - Return 0 if at least a listener was launched, -1 otherwise. -*/ -static inline int -launch_listeners(const managed_proxy_t *proxy) -{ - if (proxy->is_server) - return launch_server_listeners(proxy); - else - return launch_client_listeners(proxy); }
/** @@ -423,69 +221,20 @@ validate_bindaddrs(const char *all_bindaddrs, const char *all_transports) }
/** - Read the environment variables defined in the - 180-pluggable-transport.txt spec and fill 'proxy' accordingly. - - Return 0 if all necessary environment variables were set properly. - Return -1 otherwise. + Validates the environment variables that we got off tor. */ static int -handle_environment(managed_proxy_t *proxy) +validate_environment(managed_proxy_t *proxy) { - char *tmp; - enum env_parsing_status status=ST_ENV_SMOOTH; + enum env_parsing_status status;
- tmp = getenv("TOR_PT_STATE_LOCATION"); - if (!tmp) { - status = ST_ENV_FAIL_STATE_LOC; - goto err; - } - proxy->vars.state_loc = xstrdup(tmp); - - tmp = getenv("TOR_PT_MANAGED_TRANSPORT_VER"); - if (!tmp) { - status = ST_ENV_FAIL_CONF_PROTO_VER; - goto err; - } - proxy->vars.conf_proto_version = xstrdup(tmp); - - tmp = getenv("TOR_PT_CLIENT_TRANSPORTS"); - if (tmp) { - proxy->vars.transports = xstrdup(tmp); - proxy->is_server = 0; - } else { - proxy->is_server = 1; - } + assert_proxy_env(proxy);
if (proxy->is_server) { - tmp = getenv("TOR_PT_EXTENDED_SERVER_PORT"); - if (!tmp) { - status = ST_ENV_FAIL_EXTENDED_PORT; - goto err; - } - proxy->vars.extended_port = xstrdup(tmp); - - tmp = getenv("TOR_PT_ORPORT"); - if (!tmp) { - status = ST_ENV_FAIL_ORPORT; - goto err; - } - proxy->vars.or_port = xstrdup(tmp); - - tmp = getenv("TOR_PT_SERVER_BINDADDR"); - if (tmp) { - proxy->vars.bindaddrs = xstrdup(tmp); - } else { + if (validate_bindaddrs(proxy->vars.bindaddrs, proxy->vars.transports) < 0) { status = ST_ENV_FAIL_BINDADDR; goto err; } - - tmp = getenv("TOR_PT_SERVER_TRANSPORTS"); - if (!tmp) { - status = ST_ENV_FAIL_SERVER_TRANSPORTS; - goto err; - } - proxy->vars.transports = xstrdup(tmp); }
return 0; @@ -498,22 +247,22 @@ handle_environment(managed_proxy_t *proxy) }
/** - Given the name of a protocol we tried to launch in 'protocol' - the managed proxy parameters in 'proxy' and a listener launch - status in 'status', print a line of the form: - CMETHOD-ERROR <methodname> "<errormessage>" - to signify a listener launching failure. + Free memory allocated by 'proxy'. */ -static inline void -print_method_error_line(const char *protocol, - const managed_proxy_t *proxy, - enum launch_status status) +static void +managed_proxy_free(managed_proxy_t *proxy) { - print_protocol_line("%s %s %s\n", - proxy->is_server ? - PROTO_SMETHOD_ERROR : PROTO_CMETHOD_ERROR, - protocol, - get_launch_error_message(status)); + free(proxy->vars.state_loc); + free(proxy->vars.conf_proto_version); + free(proxy->vars.transports); + free(proxy->vars.extended_port); + free(proxy->vars.or_port); + free(proxy->vars.bindaddrs); + + SMARTLIST_FOREACH(proxy->configs, config_t *, cfg, config_free(cfg)); + smartlist_free(proxy->configs); + + free(proxy); }
/** @@ -616,25 +365,80 @@ conf_proto_version_negotiation(const managed_proxy_t *proxy) return r; }
+ /** - Return a string containing the error we encountered while parsing - the environment variables, according to 'status'. + Read the environment variables defined in the + 180-pluggable-transport.txt spec and fill 'proxy' accordingly. + + Return 0 if all necessary environment variables were set properly. + Return -1 otherwise. */ -static inline const char * -get_env_parsing_error_message(enum env_parsing_status status) +static int +handle_environment(managed_proxy_t *proxy) { - switch(status) { - case ST_ENV_SMOOTH: return "no error"; - case ST_ENV_FAIL_STATE_LOC: return "failed on TOR_PT_STATE_LOCATION"; - case ST_ENV_FAIL_CONF_PROTO_VER: return "failed on TOR_PT_MANAGED_TRANSPORT_VER"; - case ST_ENV_FAIL_CLIENT_TRANSPORTS: return "failed on TOR_PT_CLIENT_TRANSPORTS"; - case ST_ENV_FAIL_EXTENDED_PORT: return "failed on TOR_PT_EXTENDED_SERVER_PORT"; - case ST_ENV_FAIL_ORPORT: return "failed on TOR_PT_ORPORT"; - case ST_ENV_FAIL_BINDADDR: return "failed on TOR_PT_SERVER_BINDADDR"; - case ST_ENV_FAIL_SERVER_TRANSPORTS: return "failed on TOR_PT_SERVER_TRANSPORTS"; - default: - obfs_assert(0); return "UNKNOWN"; + char *tmp; + enum env_parsing_status status=ST_ENV_SMOOTH; + + tmp = getenv("TOR_PT_STATE_LOCATION"); + if (!tmp) { + status = ST_ENV_FAIL_STATE_LOC; + goto err; + } + proxy->vars.state_loc = xstrdup(tmp); + + tmp = getenv("TOR_PT_MANAGED_TRANSPORT_VER"); + if (!tmp) { + status = ST_ENV_FAIL_CONF_PROTO_VER; + goto err; + } + proxy->vars.conf_proto_version = xstrdup(tmp); + + tmp = getenv("TOR_PT_CLIENT_TRANSPORTS"); + if (tmp) { + proxy->vars.transports = xstrdup(tmp); + proxy->is_server = 0; + } else { + proxy->is_server = 1; + } + + if (proxy->is_server) { + tmp = getenv("TOR_PT_EXTENDED_SERVER_PORT"); + if (!tmp) { + status = ST_ENV_FAIL_EXTENDED_PORT; + goto err; + } + proxy->vars.extended_port = xstrdup(tmp); + + tmp = getenv("TOR_PT_ORPORT"); + if (!tmp) { + status = ST_ENV_FAIL_ORPORT; + goto err; + } + proxy->vars.or_port = xstrdup(tmp); + + tmp = getenv("TOR_PT_SERVER_BINDADDR"); + if (tmp) { + proxy->vars.bindaddrs = xstrdup(tmp); + } else { + status = ST_ENV_FAIL_BINDADDR; + goto err; + } + + tmp = getenv("TOR_PT_SERVER_TRANSPORTS"); + if (!tmp) { + status = ST_ENV_FAIL_SERVER_TRANSPORTS; + goto err; + } + proxy->vars.transports = xstrdup(tmp); } + + return 0; + + err: + print_protocol_line("%s %s\n", PROTO_ENV_ERROR, + get_env_parsing_error_message(status)); + + return -1; }
/** @@ -654,17 +458,193 @@ get_launch_error_message(enum launch_status status) }
/** - This function is used for obfsproxy to communicate with tor. - Practically a wrapper of printf, it prints 'format' and the - fflushes stdout so that the output is always immediately available - to tor. + Given the name of a protocol we tried to launch in 'protocol' + the managed proxy parameters in 'proxy' and a listener launch + status in 'status', print a line of the form: + CMETHOD-ERROR <methodname> "<errormessage>" + to signify a listener launching failure. */ -static void -print_protocol_line(const char *format, ...) +static inline void +print_method_error_line(const char *protocol, + const managed_proxy_t *proxy, + enum launch_status status) { - va_list ap; - va_start(ap,format); - vprintf(format, ap); - fflush(stdout); - va_end(ap); + print_protocol_line("%s %s %s\n", + proxy->is_server ? + PROTO_SMETHOD_ERROR : PROTO_CMETHOD_ERROR, + protocol, + get_launch_error_message(status)); +} + +/** + Given a smartlist of listener configs; launch them all and print + method lines as appropriate. Return 0 if at least a listener was + spawned, -1 otherwise. +*/ +static int +open_listeners_managed(const managed_proxy_t *proxy) +{ + int ret=-1; + const char *transport; + + /* Open listeners for each configuration. */ + SMARTLIST_FOREACH_BEGIN(proxy->configs, config_t *, cfg) { + transport = get_transport_name_from_config(cfg); + + if (open_listeners(get_event_base(), cfg)) { + ret=0; /* success! launched at least one listener. */ + print_method_line(transport, proxy, cfg); + } else { /* fail. print a method error line. */ + print_method_error_line(transport, proxy, ST_LAUNCH_FAIL_LSN); + } + } SMARTLIST_FOREACH_END(cfg); + + return ret; +} + +/** + Launch all server listeners that tor wants us to launch. +*/ +static int +launch_server_listeners(const managed_proxy_t *proxy) +{ + int ret=-1; + int i, n_transports; + const char *transport = NULL; + const char *bindaddr_temp = NULL; + const char *bindaddr = NULL; + config_t *cfg = NULL; + + /* list of transports */ + smartlist_t *transports = smartlist_create(); + /* a list of "<transport>-<bindaddr>" strings */ + smartlist_t *bindaddrs = smartlist_create(); + + /* split the comma-separated transports/bindaddrs to their smartlists */ + smartlist_split_string(transports, proxy->vars.transports, ",", + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); + smartlist_split_string(bindaddrs, proxy->vars.bindaddrs, ",", + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); + + n_transports = smartlist_len(transports); + + /* Iterate transports; match them with their bindaddr; create their + config_t. */ + for (i=0;i<n_transports;i++) { + transport = smartlist_get(transports, i); + bindaddr_temp = smartlist_get(bindaddrs, i); + + obfs_assert(strlen(bindaddr_temp) > strlen(transport)+1); + + bindaddr = bindaddr_temp+strlen(transport)+1; /* +1 for the dash */ + + cfg = config_create_managed(proxy->is_server, + transport, bindaddr, proxy->vars.or_port); + if (cfg) /* if a config was created; put it in the config smartlist */ + smartlist_add(proxy->configs, cfg); + else /* otherwise, spit a method error line */ + print_method_error_line(transport, proxy, ST_LAUNCH_FAIL_SETUP); + } + + /* open listeners */ + ret = open_listeners_managed(proxy); + + SMARTLIST_FOREACH(bindaddrs, char *, cp, free(cp)); + smartlist_free(bindaddrs); + SMARTLIST_FOREACH(transports, char *, cp, free(cp)); + smartlist_free(transports); + + print_method_done_line(proxy); /* print {C,S}METHODS DONE */ + + return ret; +} + +/** + Launch all client listeners that tor wants us to launch. +*/ +static int +launch_client_listeners(const managed_proxy_t *proxy) +{ + int ret=-1; + config_t *cfg = NULL; + + /* list of transports */ + smartlist_t *transports = smartlist_create(); + + smartlist_split_string(transports, proxy->vars.transports, ",", + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); + + SMARTLIST_FOREACH_BEGIN(transports, char *, transport) { + /* clients should find their own listen port */ + cfg = config_create_managed(proxy->is_server, + transport, "127.0.0.1:0", proxy->vars.or_port); + if (cfg) /* if config was created; put it in the config smartlist */ + smartlist_add(proxy->configs, cfg); + else + print_method_error_line(transport, proxy, ST_LAUNCH_FAIL_SETUP); + } SMARTLIST_FOREACH_END(transport); + + /* open listeners */ + ret = open_listeners_managed(proxy); + + SMARTLIST_FOREACH(transports, char *, cp, free(cp)); + smartlist_free(transports); + + print_method_done_line(proxy); /* print {C,S}METHODS DONE */ + + return ret; +} + +/** + Launch all listeners that tor wants us to launch. + Return 0 if at least a listener was launched, -1 otherwise. +*/ +static inline int +launch_listeners(const managed_proxy_t *proxy) +{ + if (proxy->is_server) + return launch_server_listeners(proxy); + else + return launch_client_listeners(proxy); +} + +/** + This function fires up the managed proxy. + It first reads the environment that tor should have prepared, and then + launches the appropriate listeners. + + Returns 0 if we managed to launch at least one proxy, + returns -1 if something went wrong or we didn't launch any proxies. +*/ +int +launch_managed_proxy(void) +{ + int r=-1; + managed_proxy_t *proxy = xzalloc(sizeof(managed_proxy_t)); + proxy->configs = smartlist_create(); + + obfsproxy_init(); + + if (handle_environment(proxy) < 0) + goto done; + + if (validate_environment(proxy) < 0) + goto done; + + if (conf_proto_version_negotiation(proxy) < 0) + goto done; + + if (launch_listeners(proxy) < 0) + goto done; + + /* Kickstart libevent */ + event_base_dispatch(get_event_base()); + + r=0; + + done: + obfsproxy_cleanup(); + managed_proxy_free(proxy); + + return r; }