diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-03-29 19:28:16 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-03-29 19:28:16 +0000 |
commit | 0e6084d751a66d45d5e6ac6d5d6de4771a24680f (patch) | |
tree | 17969cdb4d8c8e6c77dc65460d3f3be9a3155c12 /src | |
parent | 47b9d4439a77c4a8f90e7b3c566f0e10d228d854 (diff) | |
download | tor-0e6084d751a66d45d5e6ac6d5d6de4771a24680f.tar tor-0e6084d751a66d45d5e6ac6d5d6de4771a24680f.tar.gz |
Remove descriptors that are older than 24 hours from the directory. Use strlcat instead of strncat to generate directories.
svn:r1361
Diffstat (limited to 'src')
-rw-r--r-- | src/or/dirserv.c | 71 | ||||
-rw-r--r-- | src/or/main.c | 3 | ||||
-rw-r--r-- | src/or/or.h | 3 |
3 files changed, 56 insertions, 21 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index a73be17c0..8ed63566c 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -4,6 +4,9 @@ #include "or.h" +/* How old do we allow a router to get before removing it? (seconds) */ +#define ROUTER_MAX_AGE (60*60*24) + /* How far in the future do we allow a router to get? (seconds) */ #define ROUTER_ALLOW_SKEW (30*60) @@ -199,6 +202,7 @@ dirserv_add_descriptor(const char **desc) char *desc_tmp = NULL; const char *cp; size_t desc_len; + time_t now; start = strstr(*desc, "router "); if (!start) { @@ -242,12 +246,20 @@ dirserv_add_descriptor(const char **desc) return 0; } /* Is there too much clock skew? */ - if (ri->published_on > time(NULL)+ROUTER_ALLOW_SKEW) { + now = time(NULL); + if (ri->published_on > now+ROUTER_ALLOW_SKEW) { log_fn(LOG_WARN, "Publication time for nickname %s is too far in the future; possible clock skew. Not adding", ri->nickname); routerinfo_free(ri); *desc = end; return -1; } + if (ri->published_on < now-ROUTER_MAX_AGE) { + log_fn(LOG_WARN, "Publication time for router with nickanem %s is too far in the past. Not adding", ri->nickname); + routerinfo_free(ri); + *desc = end; + return -1; + } + /* Do we already have an entry for this router? */ desc_ent_ptr = NULL; for (i = 0; i < n_descriptors; ++i) { @@ -348,6 +360,31 @@ list_running_servers(char **nicknames_out) return 0; } +/* Remove any descriptors from the directory that are more than ROUTER_MAX_AGE + * seconds old. + */ +void +dirserv_remove_old_servers(void) +{ + int i; + time_t cutoff; + cutoff = time(NULL) - ROUTER_MAX_AGE; + for (i = 0; i < n_descriptors; ++i) { + if (descriptor_list[i]->published < cutoff) { + /* descriptor_list[i] is too old. Remove it. */ + free_descriptor_entry(descriptor_list[i]); + descriptor_list[i] = descriptor_list[n_descriptors-1]; + --n_descriptors; + directory_set_dirty(); + --i; /* Don't advance the index; consider the new value now at i. */ + } + } +} + +/* Dump all routers currently in the directory into the string <s>, using + * at most <maxlen> characters, and signing the directory with <private_key>. + * Return 0 on success, -1 on failure. + */ int dirserv_dump_directory_to_string(char *s, int maxlen, crypto_pk_env_t *private_key) @@ -362,6 +399,7 @@ dirserv_dump_directory_to_string(char *s, int maxlen, if (list_running_servers(&cp)) return -1; + dirserv_remove_old_servers(); published_on = time(NULL); strftime(published, 32, "%Y-%m-%d %H:%M:%S", gmtime(&published_on)); snprintf(s, maxlen, @@ -374,18 +412,14 @@ dirserv_dump_directory_to_string(char *s, int maxlen, cp = s+i; for (i = 0; i < n_descriptors; ++i) { - strncat(cp, descriptor_list[i]->descriptor, descriptor_list[i]->desc_len); - /* XXX Nick: do strncat and friends null-terminate? man page is ambiguous. */ - cp += descriptor_list[i]->desc_len; - assert(!*cp); + if (strlcat(s, descriptor_list[i]->descriptor, maxlen) >= maxlen) + goto truncated; } - /* These multiple strlen calls are inefficient, but dwarfed by the RSA + /* These multiple strlcat calls are inefficient, but dwarfed by the RSA signature. */ - i = strlen(s); - strncat(s, "directory-signature\n", maxlen-i); - i = strlen(s); - cp = s + i; + if (strlcat(s, "directory-signature\n", maxlen) >= maxlen) + goto truncated; if (router_get_dir_hash(s,digest)) { log_fn(LOG_WARN,"couldn't compute digest"); @@ -399,8 +433,8 @@ dirserv_dump_directory_to_string(char *s, int maxlen, ((int)digest[0])&0xff,((int)digest[1])&0xff, ((int)digest[2])&0xff,((int)digest[3])&0xff); - strncpy(cp, "-----BEGIN SIGNATURE-----\n", maxlen-i); - cp[maxlen-i-1] = 0; + if (strlcat(cp, "-----BEGIN SIGNATURE-----\n", maxlen) >= maxlen) + goto truncated; i = strlen(s); cp = s+i; @@ -409,16 +443,13 @@ dirserv_dump_directory_to_string(char *s, int maxlen, return -1; } - i = strlen(s); - cp = s+i; - strncat(cp, "-----END SIGNATURE-----\n", maxlen-i); - i = strlen(s); - if (i == maxlen) { - log_fn(LOG_WARN,"tried to exceed string length."); - return -1; - } + if (strlcat(s, "-----END SIGNATURE-----\n", maxlen) >= maxlen) + goto truncated; return 0; + truncated: + log_fn(LOG_WARN,"tried to exceed string length."); + return -1; } static char *the_directory = NULL; diff --git a/src/or/main.c b/src/or/main.c index 3afefcb3e..3478008db 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -330,6 +330,9 @@ static void run_scheduled_events(time_t now) { * Hope this doesn't bite us later. */ directory_initiate_command(router_pick_directory_server(), DIR_CONN_STATE_CONNECTING_FETCH); + } else { + /* We're a directory; dump any old descriptors. */ + dirserv_remove_old_servers(); } time_to_fetch_directory = now + options.DirFetchPostPeriod; } diff --git a/src/or/or.h b/src/or/or.h index 25c8420b7..606edfb89 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -905,8 +905,9 @@ int dirserv_init_from_directory_string(const char *dir); void dirserv_free_descriptors(); int dirserv_dump_directory_to_string(char *s, int maxlen, crypto_pk_env_t *private_key); -void directory_set_dirty(); +void directory_set_dirty(void); size_t dirserv_get_directory(const char **cp); +void dirserv_remove_old_servers(void); /********************************* rephist.c ***************************/ |