diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitbuild.c | 5 | ||||
-rw-r--r-- | src/or/config.c | 4 | ||||
-rw-r--r-- | src/or/control.c | 48 | ||||
-rw-r--r-- | src/or/geoip.c | 9 | ||||
-rw-r--r-- | src/or/hibernate.c | 4 | ||||
-rw-r--r-- | src/or/networkstatus.c | 7 | ||||
-rw-r--r-- | src/or/or.h | 18 | ||||
-rw-r--r-- | src/or/policies.c | 4 |
8 files changed, 68 insertions, 31 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 4090054c1e..33f208a7c7 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4240,9 +4240,12 @@ entry_guards_update_state(or_state_t *state) * */ int getinfo_helper_entry_guards(control_connection_t *conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { (void) conn; + (void) errmsg; + if (!strcmp(question,"entry-guards") || !strcmp(question,"helper-nodes")) { smartlist_t *sl = smartlist_create(); diff --git a/src/or/config.c b/src/or/config.c index 7dee8ffab2..70a3ee6218 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -5060,9 +5060,11 @@ remove_file_if_very_old(const char *fname, time_t now) * types. */ int getinfo_helper_config(control_connection_t *conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { (void) conn; + (void) errmsg; if (!strcmp(question, "config/names")) { smartlist_t *sl = smartlist_create(); int i; diff --git a/src/or/control.c b/src/or/control.c index ea6ce4c464..ab17bec8a4 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1296,7 +1296,7 @@ handle_control_mapaddress(control_connection_t *conn, uint32_t len, * trivial-to-implement questions. */ static int getinfo_helper_misc(control_connection_t *conn, const char *question, - char **answer) + char **answer, const char **errmsg) { (void) conn; if (!strcmp(question, "version")) { @@ -1316,15 +1316,19 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, *answer = tor_strdup("VERBOSE_NAMES EXTENDED_EVENTS"); } else if (!strcmp(question, "address")) { uint32_t addr; - if (router_pick_published_address(get_options(), &addr) < 0) + if (router_pick_published_address(get_options(), &addr) < 0) { + *errmsg = "Address unknown"; return -1; + } *answer = tor_dup_ip(addr); } else if (!strcmp(question, "dir-usage")) { *answer = directory_dump_request_log(); } else if (!strcmp(question, "fingerprint")) { routerinfo_t *me = router_get_my_routerinfo(); - if (!me) + if (!me) { + *errmsg = "No routerdesc known; am I really a server?"; return -1; + } *answer = tor_malloc(HEX_DIGEST_LEN+1); base16_encode(*answer, HEX_DIGEST_LEN+1, me->cache_info.identity_digest, DIGEST_LEN); @@ -1385,7 +1389,8 @@ munge_extrainfo_into_routerinfo(const char *ri_body, signed_descriptor_t *ri, * directory information. */ static int getinfo_helper_dir(control_connection_t *control_conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { (void) control_conn; if (!strcmpstart(question, "desc/id/")) { @@ -1462,6 +1467,7 @@ getinfo_helper_dir(control_connection_t *control_conn, log_warn(LD_CONTROL, "getinfo '%s': %s", question, msg); smartlist_free(descs); tor_free(url); + *errmsg = msg; return -1; } SMARTLIST_FOREACH(descs, signed_descriptor_t *, sd, @@ -1558,7 +1564,8 @@ getinfo_helper_dir(control_connection_t *control_conn, * current states of things we send events about. */ static int getinfo_helper_events(control_connection_t *control_conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { (void) control_conn; if (!strcmp(question, "circuit-status")) { @@ -1759,8 +1766,10 @@ getinfo_helper_events(control_connection_t *control_conn, } } else if (!strcmp(question, "status/clients-seen")) { const char *bridge_stats = geoip_get_bridge_stats_controller(time(NULL)); - if (!bridge_stats) + if (!bridge_stats) { + *errmsg = "No bridge-client stats available"; return -1; + } *answer = tor_strdup(bridge_stats); } else { return 0; @@ -1771,12 +1780,14 @@ getinfo_helper_events(control_connection_t *control_conn, /** Callback function for GETINFO: on a given control connection, try to * answer the question <b>q</b> and store the newly-allocated answer in - * *<b>a</b>. If an internal error occurs, return -1. On success, or if - * the key is not recognized, return 0. Do not set <b>a</b> if the key is - * not recognized. + * *<b>a</b>. If an internal error occurs, return -1 and optionally set + * *<b>error_out</b> to point to an error message to be delivered to the + * controller. On success, _or if the key is not recognized_, return 0. Do not + * set <b>a</b> if the key is not recognized. */ typedef int (*getinfo_helper_t)(control_connection_t *, - const char *q, char **a); + const char *q, char **a, + const char **error_out); /** A single item for the GETINFO question-to-answer-function table. */ typedef struct getinfo_item_t { @@ -1911,7 +1922,8 @@ list_getinfo_options(void) * internal error. */ static int handle_getinfo_helper(control_connection_t *control_conn, - const char *question, char **answer) + const char *question, char **answer, + const char **err_out) { int i; *answer = NULL; /* unrecognized key by default */ @@ -1924,7 +1936,7 @@ handle_getinfo_helper(control_connection_t *control_conn, match = !strcmp(question, getinfo_items[i].varname); if (match) { tor_assert(getinfo_items[i].fn); - return getinfo_items[i].fn(control_conn, question, answer); + return getinfo_items[i].fn(control_conn, question, answer, err_out); } } @@ -1946,10 +1958,12 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len, smartlist_split_string(questions, body, " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - SMARTLIST_FOREACH(questions, const char *, q, - { - if (handle_getinfo_helper(conn, q, &ans) < 0) { - connection_write_str_to_buf("551 Internal error\r\n", conn); + SMARTLIST_FOREACH_BEGIN(questions, const char *, q) { + const char *errmsg = NULL; + if (handle_getinfo_helper(conn, q, &ans, &errmsg) < 0) { + if (!errmsg) + errmsg = "Internal error"; + connection_printf_to_buf(conn, "551 %s\r\n", errmsg); goto done; } if (!ans) { @@ -1958,7 +1972,7 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len, smartlist_add(answers, tor_strdup(q)); smartlist_add(answers, ans); } - }); + } SMARTLIST_FOREACH_END(q); if (smartlist_len(unrecognized)) { for (i=0; i < smartlist_len(unrecognized)-1; ++i) connection_printf_to_buf(conn, diff --git a/src/or/geoip.c b/src/or/geoip.c index ad28a77ffd..7f6cf79d8b 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -1318,10 +1318,15 @@ geoip_entry_stats_write(time_t now) /** Helper used to implement GETINFO ip-to-country/... controller command. */ int getinfo_helper_geoip(control_connection_t *control_conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { (void)control_conn; - if (geoip_is_loaded() && !strcmpstart(question, "ip-to-country/")) { + if (!geoip_is_loaded()) { + *errmsg = "GeoIP data not loaded"; + return -1; + } + if (!strcmpstart(question, "ip-to-country/")) { int c; uint32_t ip; struct in_addr in; diff --git a/src/or/hibernate.c b/src/or/hibernate.c index 3c52a31729..6b512eacf2 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -863,9 +863,11 @@ consider_hibernation(time_t now) * NULL. */ int getinfo_helper_accounting(control_connection_t *conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { (void) conn; + (void) errmsg; if (!strcmp(question, "accounting/enabled")) { *answer = tor_strdup(accounting_is_enabled(get_options()) ? "1" : "0"); } else if (!strcmp(question, "accounting/hibernating")) { diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 49bc8053ab..4834d13764 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -2124,7 +2124,8 @@ networkstatus_parse_flavor_name(const char *flavname) * ORs. Return 0 on success, -1 on unrecognized question format. */ int getinfo_helper_networkstatus(control_connection_t *conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { routerstatus_t *status; (void) conn; @@ -2148,8 +2149,10 @@ getinfo_helper_networkstatus(control_connection_t *conn, } else if (!strcmpstart(question, "ns/id/")) { char d[DIGEST_LEN]; - if (base16_decode(d, DIGEST_LEN, question+6, strlen(question+6))) + if (base16_decode(d, DIGEST_LEN, question+6, strlen(question+6))) { + *errmsg = "Data not decodeable as hex"; return -1; + } status = router_get_consensus_status_by_id(d); } else if (!strcmpstart(question, "ns/name/")) { status = router_get_consensus_status_by_nickname(question+8, 0); diff --git a/src/or/or.h b/src/or/or.h index c9c2f41641..3418f53e1d 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3004,7 +3004,8 @@ routerinfo_t *choose_random_entry(cpath_build_state_t *state); int entry_guards_parse_state(or_state_t *state, int set, char **msg); void entry_guards_update_state(or_state_t *state); int getinfo_helper_entry_guards(control_connection_t *conn, - const char *question, char **answer); + const char *question, char **answer, + const char **errmsg); void clear_bridge_list(void); int routerinfo_is_a_configured_bridge(routerinfo_t *ri); @@ -3361,7 +3362,8 @@ int or_state_save(time_t now); int options_need_geoip_info(or_options_t *options, const char **reason_out); int getinfo_helper_config(control_connection_t *conn, - const char *question, char **answer); + const char *question, char **answer, + const char **errmsg); const char *tor_get_digests(void); uint32_t get_effective_bwrate(or_options_t *options); @@ -4162,7 +4164,8 @@ char *geoip_get_client_history_bridge(time_t now, geoip_client_action_t action); char *geoip_get_request_history(time_t now, geoip_client_action_t action); int getinfo_helper_geoip(control_connection_t *control_conn, - const char *question, char **answer); + const char *question, char **answer, + const char **errmsg); void geoip_free_all(void); /** Directory requests that we are measuring can be either direct or @@ -4220,7 +4223,8 @@ void hibernate_begin_shutdown(void); int we_are_hibernating(void); void consider_hibernation(time_t now); int getinfo_helper_accounting(control_connection_t *conn, - const char *question, char **answer); + const char *question, char **answer, + const char **errmsg); void accounting_set_bandwidth_usage_from_state(or_state_t *state); /********************************* main.c ***************************/ @@ -4397,7 +4401,8 @@ int32_t get_net_param_from_list(smartlist_t *net_params, const char *name, int32_t networkstatus_get_param(networkstatus_t *ns, const char *param_name, int32_t default_val); int getinfo_helper_networkstatus(control_connection_t *conn, - const char *question, char **answer); + const char *question, char **answer, + const char **errmsg); int32_t networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight, int32_t default_val); const char *networkstatus_get_flavor_name(consensus_flavor_t flav); @@ -4504,7 +4509,8 @@ void policies_set_router_exitpolicy_to_reject_all(routerinfo_t *exitrouter); int exit_policy_is_general_exit(smartlist_t *policy); int policy_is_reject_star(const smartlist_t *policy); int getinfo_helper_policies(control_connection_t *conn, - const char *question, char **answer); + const char *question, char **answer, + const char **errmsg); int policy_write_item(char *buf, size_t buflen, addr_policy_t *item, int format_for_desc); diff --git a/src/or/policies.c b/src/or/policies.c index 90e159a880..f5c02a6000 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -1288,9 +1288,11 @@ cleanup: * about "exit-policy/..." */ int getinfo_helper_policies(control_connection_t *conn, - const char *question, char **answer) + const char *question, char **answer, + const char **errmsg) { (void) conn; + (void) errmsg; if (!strcmp(question, "exit-policy/default")) { *answer = tor_strdup(DEFAULT_EXIT_POLICY); } |