aboutsummaryrefslogtreecommitdiff
path: root/src/or/router.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-08-26 11:36:40 -0400
committerNick Mathewson <nickm@torproject.org>2009-08-26 11:36:40 -0400
commit1d9b8a1e16b3007999a29879b01c63c7836e2e12 (patch)
tree6c901960facca0df950d04243f69bffe018da825 /src/or/router.c
parentc9203749a2ead39433fa4f62452a2360e0901e42 (diff)
parent8c29b7920ae18a46ce0527806507275783d1ae42 (diff)
downloadtor-1d9b8a1e16b3007999a29879b01c63c7836e2e12.tar
tor-1d9b8a1e16b3007999a29879b01c63c7836e2e12.tar.gz
Merge commit 'karsten/proposal-166-impl-master'
Diffstat (limited to 'src/or/router.c')
-rw-r--r--src/or/router.c147
1 files changed, 134 insertions, 13 deletions
diff --git a/src/or/router.c b/src/or/router.c
index f2747f514..ea7a430fa 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1269,6 +1269,7 @@ router_rebuild_descriptor(int force)
uint32_t addr;
char platform[256];
int hibernating = we_are_hibernating();
+ size_t ei_size;
or_options_t *options = get_options();
if (desc_clean_since && !force)
@@ -1382,9 +1383,10 @@ router_rebuild_descriptor(int force)
ei->cache_info.published_on = ri->cache_info.published_on;
memcpy(ei->cache_info.identity_digest, ri->cache_info.identity_digest,
DIGEST_LEN);
- ei->cache_info.signed_descriptor_body = tor_malloc(8192);
- if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
- ei, get_identity_key()) < 0) {
+ ei_size = options->ExtraInfoStatistics ? MAX_EXTRAINFO_UPLOAD_SIZE : 8192;
+ ei->cache_info.signed_descriptor_body = tor_malloc(ei_size);
+ if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body,
+ ei_size, ei, get_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
extrainfo_free(ei);
return -1;
@@ -1822,6 +1824,57 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
return (int)written+1;
}
+/** Load the contents of <b>filename</b>, find the last line starting with
+ * <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
+ * the past or more than 1 hour in the future with respect to <b>now</b>,
+ * and write the file contents starting with that line to **<b>out</b>.
+ * Return 1 for success, 0 if the file does not exist or does not contain
+ * a line matching these criteria, or -1 for failure. */
+static int
+load_stats_file(const char *filename, const char *end_line, time_t now,
+ char **out)
+{
+ int r = -1;
+ char *fname = get_datadir_fname(filename);
+ char *contents, *start = NULL, *tmp, timestr[ISO_TIME_LEN+1];
+ time_t written;
+ switch (file_status(fname)) {
+ case FN_FILE:
+ /* X022 Find an alternative to reading the whole file to memory. */
+ if ((contents = read_file_to_str(fname, 0, NULL))) {
+ tmp = strstr(contents, end_line);
+ /* Find last block starting with end_line */
+ while (tmp) {
+ start = tmp;
+ tmp = strstr(tmp + 1, end_line);
+ }
+ if (!start)
+ goto notfound;
+ if (strlen(start) < strlen(end_line) + 1 + sizeof(timestr))
+ goto notfound;
+ strlcpy(timestr, start + 1 + strlen(end_line), sizeof(timestr));
+ if (parse_iso_time(timestr, &written) < 0)
+ goto notfound;
+ if (written < now - (25*60*60) || written > now + (1*60*60))
+ goto notfound;
+ *out = tor_strdup(start);
+ r = 1;
+ }
+ notfound:
+ tor_free(contents);
+ break;
+ case FN_NOENT:
+ r = 0;
+ break;
+ case FN_ERROR:
+ case FN_DIR:
+ default:
+ break;
+ }
+ tor_free(fname);
+ return r;
+}
+
/** Write the contents of <b>extrainfo</b> to the <b>maxlen</b>-byte string
* <b>s</b>, signing them with <b>ident_key</b>. Return 0 on success,
* negative on failure. */
@@ -1836,6 +1889,7 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
char *bandwidth_usage;
int result;
size_t len;
+ static int write_stats_to_extrainfo = 1;
base16_encode(identity, sizeof(identity),
extrainfo->cache_info.identity_digest, DIGEST_LEN);
@@ -1847,6 +1901,61 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
"published %s\n%s",
extrainfo->nickname, identity,
published, bandwidth_usage);
+
+ if (options->ExtraInfoStatistics && write_stats_to_extrainfo) {
+ char *contents = NULL;
+ time_t since = time(NULL) - (24*60*60);
+ log_info(LD_GENERAL, "Adding stats to extra-info descriptor.");
+ if (options->DirReqStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"dirreq-stats",
+ "dirreq-stats-end", since, &contents) > 0) {
+ int pos = strlen(s);
+ if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
+ strlen(contents)) {
+ log_warn(LD_DIR, "Could not write dirreq-stats to extra-info "
+ "descriptor.");
+ s[pos] = '\0';
+ }
+ tor_free(contents);
+ }
+ if (options->EntryStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"entry-stats",
+ "entry-stats-end", since, &contents) > 0) {
+ int pos = strlen(s);
+ if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
+ strlen(contents)) {
+ log_warn(LD_DIR, "Could not write entry-stats to extra-info "
+ "descriptor.");
+ s[pos] = '\0';
+ }
+ tor_free(contents);
+ }
+ if (options->CellStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"buffer-stats",
+ "cell-stats-end", since, &contents) > 0) {
+ int pos = strlen(s);
+ if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
+ strlen(contents)) {
+ log_warn(LD_DIR, "Could not write buffer-stats to extra-info "
+ "descriptor.");
+ s[pos] = '\0';
+ }
+ tor_free(contents);
+ }
+ if (options->ExitPortStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"exit-stats",
+ "exit-stats-end", since, &contents) > 0) {
+ int pos = strlen(s);
+ if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
+ strlen(contents)) {
+ log_warn(LD_DIR, "Could not write exit-stats to extra-info "
+ "descriptor.");
+ s[pos] = '\0';
+ }
+ tor_free(contents);
+ }
+ }
+
tor_free(bandwidth_usage);
if (result<0)
return -1;
@@ -1875,7 +1984,6 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
if (router_append_dirobj_signature(s+len, maxlen-len, digest, ident_key)<0)
return -1;
-#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
{
char *cp, *s_dup;
extrainfo_t *ei_tmp;
@@ -1890,7 +1998,24 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
tor_free(s_dup);
extrainfo_free(ei_tmp);
}
-#endif
+
+ if (options->ExtraInfoStatistics && write_stats_to_extrainfo) {
+ char *cp, *s_dup;
+ extrainfo_t *ei_tmp;
+ cp = s_dup = tor_strdup(s);
+ ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
+ if (!ei_tmp) {
+ log_warn(LD_GENERAL,
+ "We just generated an extra-info descriptor with "
+ "statistics that we can't parse. Not adding statistics to "
+ "this or any future extra-info descriptors. Descriptor "
+ "was:\n%s", s);
+ write_stats_to_extrainfo = 0;
+ extrainfo_dump_to_string(s, maxlen, extrainfo, ident_key);
+ }
+ tor_free(s_dup);
+ extrainfo_free(ei_tmp);
+ }
return (int)strlen(s)+1;
}
@@ -1905,13 +2030,9 @@ char *
extrainfo_get_client_geoip_summary(time_t now)
{
static time_t last_purged_at = 0;
- int geoip_purge_interval = 48*60*60;
-#ifdef ENABLE_DIRREQ_STATS
- geoip_purge_interval = DIR_RECORD_USAGE_RETAIN_IPS;
-#endif
-#ifdef ENABLE_ENTRY_STATS
- geoip_purge_interval = ENTRY_RECORD_USAGE_RETAIN_IPS;
-#endif
+ int geoip_purge_interval =
+ (get_options()->DirReqStatistics || get_options()->EntryStatistics) ?
+ DIR_ENTRY_RECORD_USAGE_RETAIN_IPS : 48*60*60;
if (now > last_purged_at+geoip_purge_interval) {
/* (Note that this also discards items in the client history with
* action GEOIP_CLIENT_NETWORKSTATUS{_V2}, which doesn't matter
@@ -1920,7 +2041,7 @@ extrainfo_get_client_geoip_summary(time_t now)
geoip_remove_old_clients(now-geoip_purge_interval);
last_purged_at = now;
}
- return geoip_get_client_history(now, GEOIP_CLIENT_CONNECT);
+ return geoip_get_client_history_bridge(now, GEOIP_CLIENT_CONNECT);
}
/** Return true iff <b>s</b> is a legally valid server nickname. */