diff --git a/ChangeLog b/ChangeLog index e90fefa97e..bc3f28ed03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -81,6 +81,8 @@ Changes in version 0.2.1.6-alpha - 2008-09-xx servers. - Drop the requirement to have an open dir port for storing and serving v2 hidden service descriptors. + - Authorities now serve a /tor/dbg-stability.txt URL to help debug + WFU and MTBF calculations. o Code simplifications and refactoring: - Revise the connection_new functions so that a more typesafe variant diff --git a/src/or/directory.c b/src/or/directory.c index 8e4c6d4d3d..14c06b87fc 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3004,6 +3004,21 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, goto done; } + if (!strcmp(url,"/tor/dbg-stability.txt")) { + const char *stability; + size_t len; + if (! authdir_mode_tests_reachability(options) || + ! (stability = rep_hist_get_router_stability_doc(time(NULL)))) { + write_http_status_line(conn, 404, "Not found."); + goto done; + } + + len = strlen(stability); + write_http_response_header(conn, len, 0, 0); + connection_write_to_buf(stability, len, TO_CONN(conn)); + goto done; + } + #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) #define ADD_MALLINFO_LINE(x) do { \ tor_snprintf(tmp, sizeof(tmp), "%s %d\n", #x, mi.x); \ diff --git a/src/or/or.h b/src/or/or.h index d21b30e5c6..f57dcfbd90 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3841,6 +3841,7 @@ double rep_hist_get_stability(const char *id, time_t when); double rep_hist_get_weighted_fractional_uptime(const char *id, time_t when); long rep_hist_get_weighted_time_known(const char *id, time_t when); int rep_hist_have_measured_enough_stability(void); +const char *rep_hist_get_router_stability_doc(time_t now); void rep_hist_note_used_port(time_t now, uint16_t port); smartlist_t *rep_hist_get_predicted_ports(time_t now); diff --git a/src/or/rephist.c b/src/or/rephist.c index c179b1180c..6262147cb8 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -765,6 +765,101 @@ rep_hist_record_mtbf_data(void) return -1; } +/** DOCDOC */ +static char * +rep_hist_format_router_status(or_history_t *hist, time_t now) +{ + char buf[1024]; + char sor_buf[ISO_TIME_LEN+1]; + char sod_buf[ISO_TIME_LEN+1]; + double wfu; + double mtbf; + int up = 0, down = 0; + + if (hist->start_of_run) { + format_iso_time(sor_buf, hist->start_of_run); + up = 1; + } + if (hist->start_of_downtime) { + format_iso_time(sor_buf, hist->start_of_downtime); + down = 1; + } + + wfu = get_weighted_fractional_uptime(hist, now); + mtbf = get_stability(hist, now); + tor_snprintf(buf, sizeof(buf), + "%s%s%s" + "%s%s%s" + "wfu %0.3lf\n" + " weighted-time %lu\n" + " weighted-uptime %lu\n" + "mtbf %0.1lf\n" + " weighted-run-length %lu\n" + " total-run-weights %lf\n", + up?"uptime-started ":"", up?sor_buf:"", up?" UTC\n":"", + down?"downtime-started ":"", down?sod_buf:"", down?" UTC\n":"", + wfu, + hist->total_weighted_time, + hist->weighted_uptime, + mtbf, + hist->weighted_run_length, + hist->total_run_weights + ); + + return tor_strdup(buf); +} + +/* DOCDOC */ +static char *last_stability_doc = NULL; +static time_t built_last_stability_doc_at = 0; +#define MAX_STABILITY_DOC_BUILD_RATE (3*60) + +/* DOCDOC */ +const char * +rep_hist_get_router_stability_doc(time_t now) +{ + char *result; + smartlist_t *chunks; + if (built_last_stability_doc_at + MAX_STABILITY_DOC_BUILD_RATE > now) + return last_stability_doc; + + if (!history_map) + return NULL; + + tor_free(last_stability_doc); + chunks = smartlist_create(); + + DIGESTMAP_FOREACH(history_map, id, or_history_t *, hist) { + routerinfo_t *ri; + char dbuf[BASE64_DIGEST_LEN+1]; + char header_buf[128]; + char *info; + digest_to_base64(dbuf, id); + ri = router_get_by_digest(id); + if (ri) { + char *ip = tor_dup_ip(ri->addr); + tor_snprintf(header_buf, sizeof(header_buf), "router %s %s %s\n", + dbuf, ri->nickname, ip); + tor_free(ip); + } else { + tor_snprintf(header_buf, sizeof(header_buf), + "router %s {no descriptor}\n", dbuf); + } + smartlist_add(chunks, tor_strdup(header_buf)); + info = rep_hist_format_router_status(hist, now); + if (info) + smartlist_add(chunks, info); + } DIGESTMAP_FOREACH_END; + + result = smartlist_join_strings(chunks, "", 0, NULL); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_free(chunks); + + last_stability_doc = result; + built_last_stability_doc_at = time(NULL); + return result; +} + /** Helper: return the first j >= i such that !strcmpstart(sl[j], prefix) and * such that no line sl[k] with i <= k < j starts with "R ". Return -1 if no * such line exists. */ @@ -1693,6 +1788,8 @@ rep_hist_free_all(void) digestmap_free(history_map, free_or_history); tor_free(read_array); tor_free(write_array); + tor_free(last_stability_doc); + built_last_stability_doc_at = 0; predicted_ports_free(); }