From db94b7f46ef02d5a1de132a5b746b350f3d066b7 Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Wed, 7 Jul 2010 14:55:42 +0200 Subject: [PATCH] Count bytes we spend on answering directory requests. --- changes/enhancement1790 | 5 ++ doc/spec/dir-spec.txt | 11 ++++ src/or/config.c | 6 ++ src/or/connection.c | 12 +++- src/or/or.h | 6 ++ src/or/rephist.c | 148 ++++++++++++++++++++++++++++++++++++++---------- src/or/rephist.h | 2 + 7 files changed, 157 insertions(+), 33 deletions(-) create mode 100644 changes/enhancement1790 diff --git a/changes/enhancement1790 b/changes/enhancement1790 new file mode 100644 index 0000000000..d92292a774 --- /dev/null +++ b/changes/enhancement1790 @@ -0,0 +1,5 @@ + o Minor features: + - Relays report the number of bytes spent on answering directory + requests in extra-info descriptors similar to {read,write}-history. + Implements enhancement 1790. + diff --git a/doc/spec/dir-spec.txt b/doc/spec/dir-spec.txt index 477536376f..bd3b8ba245 100644 --- a/doc/spec/dir-spec.txt +++ b/doc/spec/dir-spec.txt @@ -779,6 +779,17 @@ had a smaller bandwidth than md, the other half had a larger bandwidth than md. + "dirreq-read-history" YYYY-MM-DD HH:MM:SS (NSEC s) NUM,NUM,NUM... NL + [At most once] + "dirreq-write-history" YYYY-MM-DD HH:MM:SS (NSEC s) NUM,NUM,NUM... NL + [At most once] + + Declare how much bandwidth the OR has spent on answering directory + requests. Usage is divided into intervals of NSEC seconds. The + YYYY-MM-DD HH:MM:SS field defines the end of the most recent + interval. The numbers are the number of bytes used in the most + recent intervals, ordered from oldest to newest. + "entry-stats-end" YYYY-MM-DD HH:MM:SS (NSEC s) NL [At most once.] diff --git a/src/or/config.c b/src/or/config.c index 58cf2ff2d3..1c3326d0c3 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -440,6 +440,12 @@ static config_var_t _state_vars[] = { V(BWHistoryWriteEnds, ISOTIME, NULL), V(BWHistoryWriteInterval, UINT, "900"), V(BWHistoryWriteValues, CSV, ""), + V(BWHistoryDirReadEnds, ISOTIME, NULL), + V(BWHistoryDirReadInterval, UINT, "900"), + V(BWHistoryDirReadValues, CSV, ""), + V(BWHistoryDirWriteEnds, ISOTIME, NULL), + V(BWHistoryDirWriteInterval, UINT, "900"), + V(BWHistoryDirWriteValues, CSV, ""), V(TorVersion, STRING, NULL), diff --git a/src/or/connection.c b/src/or/connection.c index 55d2fa8146..5438cf7d0d 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -2082,8 +2082,6 @@ static void connection_buckets_decrement(connection_t *conn, time_t now, size_t num_read, size_t num_written) { - if (!connection_is_rate_limited(conn)) - return; /* local IPs are free */ if (num_written >= INT_MAX || num_read >= INT_MAX) { log_err(LD_BUG, "Value out of range. num_read=%lu, num_written=%lu, " "connection type=%s, state=%s", @@ -2095,6 +2093,16 @@ connection_buckets_decrement(connection_t *conn, time_t now, tor_fragile_assert(); } + /* Count bytes of answering direct and tunneled directory requests */ + if (conn->type == CONN_TYPE_DIR && conn->purpose == DIR_PURPOSE_SERVER) { + if (num_read > 0) + rep_hist_note_dir_bytes_read(num_read, now); + if (num_written > 0) + rep_hist_note_dir_bytes_written(num_written, now); + } + + if (!connection_is_rate_limited(conn)) + return; /* local IPs are free */ if (num_read > 0) { if (conn->type == CONN_TYPE_EXIT) rep_hist_note_exit_bytes_read(conn->port, num_read); diff --git a/src/or/or.h b/src/or/or.h index e1f4541a7e..78c04eada5 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2842,6 +2842,12 @@ typedef struct { time_t BWHistoryWriteEnds; int BWHistoryWriteInterval; smartlist_t *BWHistoryWriteValues; + time_t BWHistoryDirReadEnds; + int BWHistoryDirReadInterval; + smartlist_t *BWHistoryDirReadValues; + time_t BWHistoryDirWriteEnds; + int BWHistoryDirWriteInterval; + smartlist_t *BWHistoryDirWriteValues; /** Build time histogram */ config_line_t * BuildtimeHistogram; diff --git a/src/or/rephist.c b/src/or/rephist.c index 72addde5b5..28248c3212 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -1284,13 +1284,21 @@ bw_array_new(void) static bw_array_t *read_array = NULL; /** Recent history of bandwidth observations for write operations. */ static bw_array_t *write_array = NULL; - -/** Set up read_array and write_array. */ +/** Recent history of bandwidth observations for read operations for the + directory protocol. */ +static bw_array_t *dir_read_array = NULL; +/** Recent history of bandwidth observations for write operations for the + directory protocol. */ +static bw_array_t *dir_write_array = NULL; + +/** Set up [dir-]read_array and [dir-]write_array. */ static void bw_arrays_init(void) { read_array = bw_array_new(); write_array = bw_array_new(); + dir_read_array = bw_array_new(); + dir_write_array = bw_array_new(); } /** We read num_bytes more bytes in second when. @@ -1324,6 +1332,24 @@ rep_hist_note_bytes_read(size_t num_bytes, time_t when) add_obs(read_array, when, num_bytes); } +/** We wrote num_bytes more directory bytes in second when. + * (like rep_hist_note_bytes_written() above) + */ +void +rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when) +{ + add_obs(dir_write_array, when, num_bytes); +} + +/** We read num_bytes more directory bytes in second when. + * (like rep_hist_note_bytes_written() above) + */ +void +rep_hist_note_dir_bytes_read(size_t num_bytes, time_t when) +{ + add_obs(dir_read_array, when, num_bytes); +} + /** Helper: Return the largest value in b->maxima. (This is equal to the * most bandwidth used in any NUM_SECS_ROLLING_MEASURE period for the last * NUM_SECS_BW_SUM_IS_VALID seconds.) @@ -1359,9 +1385,9 @@ rep_hist_bandwidth_assess(void) return (int)(U64_TO_DBL(r)/NUM_SECS_ROLLING_MEASURE); } -/** Print the bandwidth history of b (either read_array or write_array) - * into the buffer pointed to by buf. The format is simply comma - * separated numbers, from oldest to newest. +/** Print the bandwidth history of b (either [dir-]read_array or + * [dir-]write_array) into the buffer pointed to by buf. The format is + * simply comma separated numbers, from oldest to newest. * * It returns the number of bytes written. */ @@ -1419,20 +1445,37 @@ rep_hist_get_bandwidth_lines(int for_extrainfo) char *buf, *cp; char t[ISO_TIME_LEN+1]; int r; - bw_array_t *b; + bw_array_t *b = NULL; + const char *desc = NULL; size_t len; - /* opt (read|write)-history yyyy-mm-dd HH:MM:SS (n s) n,n,n,n,n... */ - len = (60+21*NUM_TOTALS)*2; + /* opt [dirreq-](read|write)-history yyyy-mm-dd HH:MM:SS (n s) n,n,n... */ + len = (67+21*NUM_TOTALS)*4; buf = tor_malloc_zero(len); cp = buf; - for (r=0;r<2;++r) { - b = r?read_array:write_array; + for (r=0;r<4;++r) { + switch (r) { + case 0: + b = write_array; + desc = "write-history"; + break; + case 1: + b = read_array; + desc = "read-history"; + break; + case 2: + b = dir_write_array; + desc = "dirreq-write-history"; + break; + case 3: + b = dir_read_array; + desc = "dirreq-read-history"; + break; + } tor_assert(b); format_iso_time(t, b->next_period-NUM_SECS_BW_SUM_INTERVAL); tor_snprintf(cp, len-(cp-buf), "%s%s %s (%d s) ", - for_extrainfo ? "" : "opt ", - r ? "read-history" : "write-history", t, + for_extrainfo ? "" : "opt ", desc, t, NUM_SECS_BW_SUM_INTERVAL); cp += strlen(cp); cp += rep_hist_fill_bandwidth_history(cp, len-(cp-buf), b); @@ -1448,20 +1491,41 @@ rep_hist_update_state(or_state_t *state) { int len, r; char *buf, *cp; - smartlist_t **s_values; - time_t *s_begins; - int *s_interval; - bw_array_t *b; + smartlist_t **s_values = NULL; + time_t *s_begins = NULL; + int *s_interval = NULL; + bw_array_t *b = NULL; len = 20*NUM_TOTALS+1; buf = tor_malloc_zero(len); - for (r=0;r<2;++r) { - b = r?read_array:write_array; - s_begins = r?&state->BWHistoryReadEnds :&state->BWHistoryWriteEnds; - s_interval= r?&state->BWHistoryReadInterval:&state->BWHistoryWriteInterval; - s_values = r?&state->BWHistoryReadValues :&state->BWHistoryWriteValues; - + for (r=0;r<4;++r) { + switch (r) { + case 0: + b = write_array; + s_begins = &state->BWHistoryWriteEnds; + s_interval = &state->BWHistoryWriteInterval; + s_values = &state->BWHistoryWriteValues; + break; + case 1: + b = read_array; + s_begins = &state->BWHistoryReadEnds; + s_interval = &state->BWHistoryReadInterval; + s_values = &state->BWHistoryReadValues; + break; + case 2: + b = dir_write_array; + s_begins = &state->BWHistoryDirWriteEnds; + s_interval = &state->BWHistoryDirWriteInterval; + s_values = &state->BWHistoryDirWriteValues; + break; + case 3: + b = dir_read_array; + s_begins = &state->BWHistoryDirReadEnds; + s_interval = &state->BWHistoryDirReadInterval; + s_values = &state->BWHistoryDirReadValues; + break; + } if (*s_values) { SMARTLIST_FOREACH(*s_values, char *, val, tor_free(val)); smartlist_free(*s_values); @@ -1501,23 +1565,45 @@ rep_hist_update_state(or_state_t *state) int rep_hist_load_state(or_state_t *state, char **err) { - time_t s_begins, start; + time_t s_begins = 0, start; time_t now = time(NULL); uint64_t v; int r,i,ok; int all_ok = 1; - int s_interval; - smartlist_t *s_values; - bw_array_t *b; + int s_interval = 0; + smartlist_t *s_values = NULL; + bw_array_t *b = NULL; /* Assert they already have been malloced */ tor_assert(read_array && write_array); - for (r=0;r<2;++r) { - b = r?read_array:write_array; - s_begins = r?state->BWHistoryReadEnds:state->BWHistoryWriteEnds; - s_interval = r?state->BWHistoryReadInterval:state->BWHistoryWriteInterval; - s_values = r?state->BWHistoryReadValues:state->BWHistoryWriteValues; + for (r=0;r<4;++r) { + switch (r) { + case 0: + b = write_array; + s_begins = state->BWHistoryWriteEnds; + s_interval = state->BWHistoryWriteInterval; + s_values = state->BWHistoryWriteValues; + break; + case 1: + b = read_array; + s_begins = state->BWHistoryReadEnds; + s_interval = state->BWHistoryReadInterval; + s_values = state->BWHistoryReadValues; + break; + case 2: + b = dir_write_array; + s_begins = state->BWHistoryDirWriteEnds; + s_interval = state->BWHistoryDirWriteInterval; + s_values = state->BWHistoryDirWriteValues; + break; + case 3: + b = dir_read_array; + s_begins = state->BWHistoryDirReadEnds; + s_interval = state->BWHistoryDirReadInterval; + s_values = state->BWHistoryDirReadValues; + break; + } if (s_values && s_begins >= now - NUM_SECS_BW_SUM_INTERVAL*NUM_TOTALS) { start = s_begins - s_interval*(smartlist_len(s_values)); if (start > now) diff --git a/src/or/rephist.h b/src/or/rephist.h index fe45a81a3b..dc756df501 100644 --- a/src/or/rephist.h +++ b/src/or/rephist.h @@ -23,6 +23,8 @@ void rep_hist_note_extend_failed(const char *from_name, const char *to_name); void rep_hist_dump_stats(time_t now, int severity); void rep_hist_note_bytes_read(size_t num_bytes, time_t when); void rep_hist_note_bytes_written(size_t num_bytes, time_t when); +void rep_hist_note_dir_bytes_read(size_t num_bytes, time_t when); +void rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when); void rep_hist_note_exit_bytes_read(uint16_t port, size_t num_bytes); void rep_hist_note_exit_bytes_written(uint16_t port, size_t num_bytes); void rep_hist_note_exit_stream_opened(uint16_t port); -- 2.11.4.GIT