aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-02-11 18:55:05 +0000
committerNick Mathewson <nickm@torproject.org>2008-02-11 18:55:05 +0000
commitc3bd8d144c56aaffcbd568be47031539b5698d1f (patch)
tree312b4c426af659d62b261fe96c7219975a60abb5
parent259d2f7207ec7b571ad26cfc4a682af2c6f26faa (diff)
downloadtor-c3bd8d144c56aaffcbd568be47031539b5698d1f.tar.gz
tor-c3bd8d144c56aaffcbd568be47031539b5698d1f.zip
r18031@catbus: nickm | 2008-02-11 13:54:58 -0500
Have assert_connection_ok() allow marked-for-close dir conns with stuff to flush but no way to flush it. Adjust conn_dirserv_unlink_from_bridge() to mark edge and dir conns not already marked, since once linked conns are unlinked they are no longer viable. Likely fix for bug 406, which was crashing 0.1.2.x servers periodically. svn:r13469
-rw-r--r--ChangeLog4
-rw-r--r--src/or/connection.c3
-rw-r--r--src/or/dirserv.c10
3 files changed, 14 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index ede44c1464..99f1b2acea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@ Changes in versino 0.1.2.20 - 2008-??-??
- Patch from "Andrew S. Lists" to catch when we contact a directory
mirror at IP address X and he says we look like we're coming from
IP address X. Bugfix on 0.1.2.x.
+ - Allow a closing-down linked directory connection to have its
+ blocked_on_or_conn field set. This prevents a rare assertion error
+ that could occur when an OR connection carrying tunneled directory
+ requests closed before the requests were complete. Fixes bug 406.
o Minor bugfixes:
- Stop recommending that every server operator send mail to tor-ops.
diff --git a/src/or/connection.c b/src/or/connection.c
index 04fe25dce2..88de54d62e 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -2403,7 +2403,8 @@ assert_connection_ok(connection_t *conn, time_t now)
if (conn->outbuf_flushlen > 0) {
tor_assert(connection_is_writing(conn) || conn->wants_to_write ||
(conn->type == CONN_TYPE_DIR &&
- TO_DIR_CONN(conn)->is_blocked_on_or_conn));
+ (conn->marked_for_close ||
+ TO_DIR_CONN(conn)->is_blocked_on_or_conn)));
}
if (conn->hold_open_until_flushed)
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index a2ff421ebf..f61b9feb03 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2051,12 +2051,18 @@ connection_dirserv_unlink_from_bridge(dir_connection_t *dir_conn)
or_conn = connection_dirserv_get_target_or_conn(dir_conn);
if (or_conn) {
/* XXXX Really, this is only necessary if dir_conn->is_blocked_on_or_conn.
- * But for now, let's leave it in, so the assert can catch */
+ * But for now, let's leave it in, so the assert can catch problems. */
connection_dirserv_remove_from_blocked_list(or_conn, dir_conn);
}
dir_conn->is_blocked_on_or_conn = 0; /* Probably redundant. */
- edge_conn->bridge_for_conn = NULL;
dir_conn->bridge_conn = NULL;
+ if (edge_conn) {
+ edge_conn->bridge_for_conn = NULL;
+ if (!edge_conn->_base.marked_for_close)
+ connection_mark_for_close(TO_CONN(edge_conn));
+ }
+ if (!dir_conn->_base.marked_for_close)
+ connection_mark_for_close(TO_CONN(dir_conn));
}
/** Stop writing on a bridged dir_conn, and remember that it's blocked because