diff --git a/src/or/geoip.c b/src/or/geoip.c index 622b582173..247e16cff3 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -365,6 +365,23 @@ geoip_get_mean_shares(time_t now, double *v2_share_out, return 0; } +/* Rotate period of v2 and v3 network status requests. */ +static void +rotate_request_period(void) +{ + SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, { + memmove(&c->n_v2_ns_requests[0], &c->n_v2_ns_requests[1], + sizeof(uint32_t)*(REQUEST_HIST_LEN-1)); + memmove(&c->n_v3_ns_requests[0], &c->n_v3_ns_requests[1], + sizeof(uint32_t)*(REQUEST_HIST_LEN-1)); + c->n_v2_ns_requests[REQUEST_HIST_LEN-1] = 0; + c->n_v3_ns_requests[REQUEST_HIST_LEN-1] = 0; + }); + current_request_period_starts += REQUEST_HIST_PERIOD; + if (n_old_request_periods < REQUEST_HIST_LEN-1) + ++n_old_request_periods; +} + /** Note that we've seen a client connect from the IP addr (host order) * at time now. Ignored by all but bridges and directories if * configured accordingly. */ @@ -404,17 +421,7 @@ geoip_note_client_seen(geoip_client_action_t action, * with action GEOIP_CLIENT_NETWORKSTATUS{_V2}.) */ geoip_remove_old_clients(current_request_period_starts); /* Now rotate request period */ - SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, { - memmove(&c->n_v2_ns_requests[0], &c->n_v2_ns_requests[1], - sizeof(uint32_t)*(REQUEST_HIST_LEN-1)); - memmove(&c->n_v3_ns_requests[0], &c->n_v3_ns_requests[1], - sizeof(uint32_t)*(REQUEST_HIST_LEN-1)); - c->n_v2_ns_requests[REQUEST_HIST_LEN-1] = 0; - c->n_v3_ns_requests[REQUEST_HIST_LEN-1] = 0; - }); - current_request_period_starts += REQUEST_HIST_PERIOD; - if (n_old_request_periods < REQUEST_HIST_LEN-1) - ++n_old_request_periods; + rotate_request_period(); } } @@ -1046,17 +1053,7 @@ geoip_dirreq_stats_write(time_t now) open_file = NULL; /* Rotate request period */ - SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, { - memmove(&c->n_v2_ns_requests[0], &c->n_v2_ns_requests[1], - sizeof(uint32_t)*(REQUEST_HIST_LEN-1)); - memmove(&c->n_v3_ns_requests[0], &c->n_v3_ns_requests[1], - sizeof(uint32_t)*(REQUEST_HIST_LEN-1)); - c->n_v2_ns_requests[REQUEST_HIST_LEN-1] = 0; - c->n_v3_ns_requests[REQUEST_HIST_LEN-1] = 0; - }); - current_request_period_starts += REQUEST_HIST_PERIOD; - if (n_old_request_periods < REQUEST_HIST_LEN-1) - ++n_old_request_periods; + rotate_request_period(); start_of_dirreq_stats_interval = now; diff --git a/src/or/relay.c b/src/or/relay.c index a79a4c161a..c81b8311a0 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1677,7 +1677,7 @@ cell_queue_clear(cell_queue_t *queue) queue->insertion_times->first = elem->next; mp_pool_release(elem); } - queue->insertion_times = NULL; + tor_free(queue->insertion_times); } } diff --git a/src/or/rephist.c b/src/or/rephist.c index f7d0b2bbcf..8d78ac26c3 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -1371,6 +1371,9 @@ rep_hist_exit_stats_write(time_t now) open_file_t *open_file = NULL; FILE *out = NULL; + if (!exit_streams) + return; /* Not initialized */ + statsdir = get_datadir_fname("stats"); if (check_private_dir(statsdir, CPD_CREATE) < 0) goto done; @@ -1480,6 +1483,8 @@ rep_hist_note_exit_bytes_written(uint16_t port, size_t num_bytes) { if (!get_options()->ExitPortStatistics) return; + if (!exit_bytes_written) + return; /* Not initialized */ exit_bytes_written[port] += num_bytes; log_debug(LD_HIST, "Written %lu bytes to exit connection to port %d.", (unsigned long)num_bytes, port); @@ -1492,6 +1497,8 @@ rep_hist_note_exit_bytes_read(uint16_t port, size_t num_bytes) { if (!get_options()->ExitPortStatistics) return; + if (!exit_bytes_read) + return; /* Not initialized */ exit_bytes_read[port] += num_bytes; log_debug(LD_HIST, "Read %lu bytes from exit connection to port %d.", (unsigned long)num_bytes, port); @@ -1503,6 +1510,8 @@ rep_hist_note_exit_stream_opened(uint16_t port) { if (!get_options()->ExitPortStatistics) return; + if (!exit_streams) + return; /* Not initialized */ exit_streams[port]++; log_debug(LD_HIST, "Opened exit stream to port %d", port); } diff --git a/src/or/router.c b/src/or/router.c index 64267f242c..2d6734ae04 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1826,36 +1826,40 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, return (int)written+1; } -/** Load the contents of filename, find the first line starting - * with end_line that has a timestamp after after, and write - * the file contents starting with that line to **contents. Return - * 1 for success, 0 if the file does not exist or does not contain a line - * matching these criteria, or -1 for failure. */ +/** Load the contents of filename, find the last line starting with + * end_line, ensure that its timestamp is not more than 25 hours in + * the past or more than 1 hour in the future with respect to now, + * and write the file contents starting with that line to **out. + * 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 after, +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, timestr[ISO_TIME_LEN+1]; + 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))) { - start = contents; - do { - if (start != contents) - start++; /* Avoid infinite loops. */ - if (!(start = strstr(start, end_line))) - 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; - } while (written <= after); - *out = tor_malloc(strlen(start)); - strlcpy(*out, start, strlen(start)); + 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: @@ -1908,7 +1912,8 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, load_stats_file("stats"PATH_SEPARATOR"dirreq-stats", "dirreq-stats-end", since, &contents) > 0) { int pos = strlen(s); - if (tor_snprintf(s + pos, maxlen - strlen(s), "%s\n", contents) < 0) { + 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'; @@ -1919,7 +1924,8 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, load_stats_file("stats"PATH_SEPARATOR"entry-stats", "entry-stats-end", since, &contents) > 0) { int pos = strlen(s); - if (tor_snprintf(s + pos, maxlen - strlen(s), "%s\n", contents) < 0) { + 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'; @@ -1930,7 +1936,8 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, load_stats_file("stats"PATH_SEPARATOR"buffer-stats", "cell-stats-end", since, &contents) > 0) { int pos = strlen(s); - if (tor_snprintf(s + pos, maxlen - strlen(s), "%s\n", contents) < 0) { + 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'; @@ -1941,7 +1948,8 @@ extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, load_stats_file("stats"PATH_SEPARATOR"exit-stats", "exit-stats-end", since, &contents) > 0) { int pos = strlen(s); - if (tor_snprintf(s + pos, maxlen - strlen(s), "%s\n", contents) < 0) { + 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';