aboutsummaryrefslogtreecommitdiff
path: root/src/or/dirserv.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-09-02 18:57:09 +0000
committerNick Mathewson <nickm@torproject.org>2004-09-02 18:57:09 +0000
commitd6e47bec460501b5d05903e90d6cf8188cd47de6 (patch)
treecbf3d3beb47226a2b111756ff646ca3d463554a1 /src/or/dirserv.c
parentbda41ba3fdcedf1bf9564e9b57d656bb6565f076 (diff)
downloadtor-d6e47bec460501b5d05903e90d6cf8188cd47de6.tar
tor-d6e47bec460501b5d05903e90d6cf8188cd47de6.tar.gz
Keep a deflated version of each directory so we can deliver it when requested
svn:r2328
Diffstat (limited to 'src/or/dirserv.c')
-rw-r--r--src/or/dirserv.c111
1 files changed, 73 insertions, 38 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 734cbc5d8..984c70288 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -20,6 +20,7 @@ static int runningrouters_is_dirty = 1;
static int list_running_servers(char **nicknames_out);
static void directory_remove_unrecognized(void);
+static int dirserv_regenerate_directory(void);
/************** Fingerprint handling code ************/
@@ -616,13 +617,19 @@ dirserv_dump_directory_to_string(char *s, unsigned int maxlen,
/** Most recently generated encoded signed directory. */
static char *the_directory = NULL;
static int the_directory_len = -1;
+static char *the_directory_z = NULL;
+static int the_directory_z_len = -1;
+
static char *cached_directory = NULL; /* used only by non-auth dirservers */
-static time_t cached_directory_published = 0;
static int cached_directory_len = -1;
+static char *cached_directory_z = NULL;
+static int cached_directory_z_len = -1;
+static time_t cached_directory_published = 0;
void dirserv_set_cached_directory(const char *directory, time_t when)
{
time_t now;
+ size_t z_len;
tor_assert(!options.AuthoritativeDir);
now = time(NULL);
if (when>cached_directory_published &&
@@ -630,61 +637,89 @@ void dirserv_set_cached_directory(const char *directory, time_t when)
tor_free(cached_directory);
cached_directory = tor_strdup(directory);
cached_directory_len = strlen(cached_directory);
+ tor_free(cached_directory_z);
+ if (tor_gzip_compress(&cached_directory_z, &z_len,
+ cached_directory, cached_directory_len,
+ ZLIB_METHOD)) {
+ log_fn(LOG_WARN,"Error compressing cached directory");
+ }
cached_directory_published = when;
}
}
/** Set *<b>directory</b> to the most recently generated encoded signed
* directory, generating a new one as necessary. */
-size_t dirserv_get_directory(const char **directory)
+size_t dirserv_get_directory(const char **directory, int deflate)
{
- char *new_directory;
- char filename[512];
if (!options.AuthoritativeDir) {
- if (cached_directory) {
- *directory = cached_directory;
- return (size_t) cached_directory_len;
+ if (deflate?cached_directory:cached_directory_z) {
+ *directory = deflate?cached_directory:cached_directory_z;
+ return (size_t) (deflate?cached_directory_len:cached_directory_z_len);
} else {
/* no directory yet retrieved */
return 0;
}
}
if (the_directory_is_dirty) {
- new_directory = tor_malloc(MAX_DIR_SIZE);
- if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE,
- get_identity_key())) {
- log(LOG_WARN, "Error creating directory.");
- free(new_directory);
+ if (dirserv_regenerate_directory())
return 0;
- }
- tor_free(the_directory);
- the_directory = new_directory;
- the_directory_len = strlen(the_directory);
- log_fn(LOG_INFO,"New directory (size %d):\n%s",the_directory_len,
- the_directory);
- /* Now read the directory we just made in order to update our own
- * router lists. This does more signature checking than is strictly
- * necessary, but safe is better than sorry. */
- new_directory = tor_strdup(the_directory);
- /* use a new copy of the dir, since get_dir_from_string scribbles on it */
- if (router_load_routerlist_from_directory(new_directory, get_identity_key())) {
- log_fn(LOG_ERR, "We just generated a directory we can't parse. Dying.");
- tor_cleanup();
- exit(0);
- }
- free(new_directory);
- if(get_data_directory(&options)) {
- sprintf(filename,"%s/cached-directory", get_data_directory(&options));
- if(write_str_to_file(filename,the_directory) < 0) {
- log_fn(LOG_WARN, "Couldn't write cached directory to disk. Ignoring.");
- }
- }
- the_directory_is_dirty = 0;
} else {
log(LOG_INFO,"Directory still clean, reusing.");
}
- *directory = the_directory;
- return the_directory_len;
+ *directory = deflate ? the_directory : the_directory_z;
+ return deflate ? the_directory_len : the_directory_z_len;
+}
+
+/**
+ * Generate a fresh directory (authdirservers only.)
+ */
+static int dirserv_regenerate_directory(void)
+{
+ char *new_directory;
+ char filename[512];
+
+ size_t z_dir_len;
+ new_directory = tor_malloc(MAX_DIR_SIZE);
+ if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE,
+ get_identity_key())) {
+ log(LOG_WARN, "Error creating directory.");
+ tor_free(new_directory);
+ return -1;
+ }
+ tor_free(the_directory);
+ the_directory = new_directory;
+ the_directory_len = strlen(the_directory);
+ log_fn(LOG_INFO,"New directory (size %d):\n%s",the_directory_len,
+ the_directory);
+ tor_free(the_directory_z);
+ if (tor_gzip_compress(&the_directory_z, &z_dir_len,
+ the_directory, the_directory_len,
+ ZLIB_METHOD)) {
+ log_fn(LOG_WARN, "Error gzipping directory.");
+ return -1;
+ }
+ the_directory_z_len = (int)z_dir_len;
+
+ /* Now read the directory we just made in order to update our own
+ * router lists. This does more signature checking than is strictly
+ * necessary, but safe is better than sorry. */
+ new_directory = tor_strdup(the_directory);
+ /* use a new copy of the dir, since get_dir_from_string scribbles on it */
+ if (router_load_routerlist_from_directory(new_directory, get_identity_key())) {
+ log_fn(LOG_ERR, "We just generated a directory we can't parse. Dying.");
+ tor_cleanup();
+ exit(0);
+ }
+ free(new_directory);
+ if(get_data_directory(&options)) {
+ sprintf(filename,"%s/cached-directory", get_data_directory(&options));
+ if(write_str_to_file(filename,the_directory) < 0) {
+ log_fn(LOG_WARN, "Couldn't write cached directory to disk. Ignoring.");
+ }
+ }
+ the_directory_is_dirty = 0;
+
+ return 0;
}
static char *runningrouters_string=NULL;