aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-03-29 19:28:16 +0000
committerNick Mathewson <nickm@torproject.org>2004-03-29 19:28:16 +0000
commit0e6084d751a66d45d5e6ac6d5d6de4771a24680f (patch)
tree17969cdb4d8c8e6c77dc65460d3f3be9a3155c12
parent47b9d4439a77c4a8f90e7b3c566f0e10d228d854 (diff)
downloadtor-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
-rw-r--r--src/or/dirserv.c71
-rw-r--r--src/or/main.c3
-rw-r--r--src/or/or.h3
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 ***************************/