summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-06-13 09:40:32 -0400
committerNick Mathewson <nickm@torproject.org>2013-06-13 09:40:32 -0400
commit25dddf7a8f30699242b52fce115f29401f63ee9c (patch)
tree1b353ff92a3f30b3e8a94804f580b223555ac906
parent74a534be15a26cddb8b134757416a7550072f44b (diff)
parente602c4031b57f0780661ce0473a5e30d187d385c (diff)
downloadtor-25dddf7a8f30699242b52fce115f29401f63ee9c.tar.gz
tor-25dddf7a8f30699242b52fce115f29401f63ee9c.zip
Merge remote-tracking branch 'public/bug8822' into maint-0.2.4
-rw-r--r--changes/bug88225
-rw-r--r--src/or/control.c6
-rw-r--r--src/or/dirserv.c2
-rw-r--r--src/or/microdesc.c26
4 files changed, 30 insertions, 9 deletions
diff --git a/changes/bug8822 b/changes/bug8822
new file mode 100644
index 0000000000..c6787afe06
--- /dev/null
+++ b/changes/bug8822
@@ -0,0 +1,5 @@
+ o Major bugfixes (windows):
+ - Prevent failures on Windows Vista and later when rebuilding the
+ microdescriptor cache. Diagnosed by Robert Ransom. Fixes bug 8822;
+ bugfix on 0.2.4.12-alpha.
+
diff --git a/src/or/control.c b/src/or/control.c
index 88bd00b5e3..a88de12d69 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1711,8 +1711,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
const node_t *node = node_get_by_hex_id(question+strlen("md/id/"));
const microdesc_t *md = NULL;
if (node) md = node->md;
- if (md) {
- tor_assert(md->body);
+ if (md && md->body) {
*answer = tor_strndup(md->body, md->bodylen);
}
} else if (!strcmpstart(question, "md/name/")) {
@@ -1722,8 +1721,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
/* XXXX duplicated code */
const microdesc_t *md = NULL;
if (node) md = node->md;
- if (md) {
- tor_assert(md->body);
+ if (md && md->body) {
*answer = tor_strndup(md->body, md->bodylen);
}
} else if (!strcmpstart(question, "desc-annotations/id/")) {
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 8f6d9ec438..3e46153a55 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -3981,7 +3981,7 @@ connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn)
char *fp256 = smartlist_pop_last(conn->fingerprint_stack);
microdesc_t *md = microdesc_cache_lookup_by_digest256(cache, fp256);
tor_free(fp256);
- if (!md)
+ if (!md || !md->body)
continue;
if (conn->zlib_state) {
/* XXXX024 This 'last' business should actually happen on the last
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index d9955c7b49..05e3b41815 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -75,6 +75,10 @@ dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out)
{
ssize_t r = 0;
size_t written;
+ if (md->body == NULL) {
+ *annotation_len_out = 0;
+ return 0;
+ }
/* XXXX drops unknown annotations. */
if (md->last_listed) {
char buf[ISO_TIME_LEN+1];
@@ -447,7 +451,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
HT_FOREACH(mdp, microdesc_map, &cache->map) {
microdesc_t *md = *mdp;
size_t annotation_len;
- if (md->no_save)
+ if (md->no_save || !md->body)
continue;
size = dump_microdescriptor(fd, md, &annotation_len);
@@ -474,15 +478,29 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
smartlist_add(wrote, md);
}
+ /* We must do this unmap _before_ we call finish_writing_to_file(), or
+ * windows will not actually replace the file. */
+ if (cache->cache_content)
+ tor_munmap_file(cache->cache_content);
+
if (finish_writing_to_file(open_file) < 0) {
log_warn(LD_DIR, "Error rebuilding microdescriptor cache: %s",
strerror(errno));
+ /* Okay. Let's prevent from making things worse elsewhere. */
+ cache->cache_content = NULL;
+ HT_FOREACH(mdp, microdesc_map, &cache->map) {
+ microdesc_t *md = *mdp;
+ if (md->saved_location == SAVED_IN_CACHE) {
+ md->off = 0;
+ md->saved_location = SAVED_NOWHERE;
+ md->body = NULL;
+ md->bodylen = 0;
+ md->no_save = 1;
+ }
+ }
return -1;
}
- if (cache->cache_content)
- tor_munmap_file(cache->cache_content);
-
cache->cache_content = tor_mmap_file(cache->cache_fname);
if (!cache->cache_content && smartlist_len(wrote)) {