diff --git a/src/or/config.c b/src/or/config.c index d2068ee045..cd5f3a9d97 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -179,6 +179,8 @@ static config_var_t config_vars[] = { VAR("SysLog", LINELIST_S, OldLogOptions, NULL), OBSOLETE("TrafficShaping"), VAR("User", STRING, User, NULL), + VAR("UseHelperNodes", BOOL, UseHelperNodes, "0"), + VAR("NumHelperNodes", UINT, NumHelperNodes, "3"), VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"), { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL } }; @@ -1564,6 +1566,11 @@ options_validate(or_options_t *options) result = -1; } + if (options->UseHelperNodes && ! options->NumHelperNodes) { + log_fn(LOG_WARN, "Cannot enable UseHelperNodes with NumHelperNodes set to 0"); + result = -1; + } + if (check_nickname_list(options->ExitNodes, "ExitNodes")) result = -1; if (check_nickname_list(options->EntryNodes, "EntryNodes")) diff --git a/src/or/control.c b/src/or/control.c index 2aa6305ca9..dc3633fa99 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1121,6 +1121,8 @@ handle_getinfo_helper(const char *question, char **answer) *answer = NULL; /* unrecognized key by default */ if (!strcmp(question, "version")) { *answer = tor_strdup(VERSION); + } else if (!strcmpstart(question, "accounting/")) { + return accounting_getinfo_helper(question, answer); } else if (!strcmpstart(question, "desc/id/")) { routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/")); if (ri && ri->signed_descriptor) diff --git a/src/or/hibernate.c b/src/or/hibernate.c index e8c5d69a05..0c5a112c1a 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -100,6 +100,8 @@ static void accounting_set_wakeup_time(void); * Functions for bandwidth accounting. * ************/ + + /** Configure accounting start/end time settings based on * options->AccountingStart. Return 0 on success, -1 on failure. If * validate_only is true, do not change the current settings. */ @@ -846,3 +848,41 @@ consider_hibernation(time_t now) } } +/** DOCDOC */ +int +accounting_getinfo_helper(const char *question, char **answer) +{ + if (!strcmp(question, "accounting/enabled")) { + *answer = tor_strdup(get_options()->AccountingMax ? "1" : "0"); + } else if (!strcmp(question, "accounting/hibernating")) { + if (hibernate_state == HIBERNATE_STATE_DORMANT) + *answer = tor_strdup("hard"); + else if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH) + *answer = tor_strdup("soft"); + else + *answer = tor_strdup("awake"); + } else if (!strcmp(question, "accounting/bytes")) { + *answer = tor_malloc(32); + tor_snprintf(*answer, 32, U64_FORMAT" "U64_FORMAT, + U64_PRINTF_ARG(n_bytes_read_in_interval), + U64_PRINTF_ARG(n_bytes_written_in_interval)); + } else if (!strcmp(question, "accounting/bytes-left")) { + *answer = tor_malloc(32); + uint64_t limit = get_options()->AccountingMax; + tor_snprintf(*answer, 32, U64_FORMAT" "U64_FORMAT, + U64_PRINTF_ARG(limit - n_bytes_read_in_interval), + U64_PRINTF_ARG(limit - n_bytes_written_in_interval)); + } else if (!strcmp(question, "accounting/interval-start")) { + *answer = tor_malloc(ISO_TIME_LEN+1); + format_iso_time(*answer, interval_start_time); + } else if (!strcmp(question, "accounting/interval-wake")) { + *answer = tor_malloc(ISO_TIME_LEN+1); + format_iso_time(*answer, interval_wakeup_time); + } else if (!strcmp(question, "accounting/interval-end")) { + *answer = tor_malloc(ISO_TIME_LEN+1); + format_iso_time(*answer, interval_end_time); + } else { + *answer = NULL; + } + return 0; +} diff --git a/src/or/or.h b/src/or/or.h index aa16547cc4..71c2ea0abc 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1164,6 +1164,9 @@ typedef struct { * such as addresses (0), or do we scrub them first (1)? */ int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware * acceleration where available? */ + int UseHelperNodes; /**< Boolean: Do we try to enter from a smallish number + * of fixed nodes? */ + int NumHelperNodes; /**< How many helper nodes do we try to establish? */ } or_options_t; #define MAX_SOCKS_REPLY_LEN 1024 @@ -1619,6 +1622,8 @@ int accounting_record_bandwidth_usage(time_t now); void hibernate_begin_shutdown(void); int we_are_hibernating(void); void consider_hibernation(time_t now); +int accounting_getinfo_helper(const char *question, char **answer); + /********************************* main.c ***************************/