]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Decouple the backend for directory_all_unreachable to simplify our CFG
authorNick Mathewson <nickm@torproject.org>
Tue, 11 Aug 2015 13:58:30 +0000 (09:58 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 12 Aug 2015 15:02:20 +0000 (11:02 -0400)
See ticket 16762.

changes/decouple_dir_all_unreachable [new file with mode: 0644]
src/or/main.c

diff --git a/changes/decouple_dir_all_unreachable b/changes/decouple_dir_all_unreachable
new file mode 100644 (file)
index 0000000..1e57b3d
--- /dev/null
@@ -0,0 +1,4 @@
+  o Code simplification and refactoring:
+    - Simply the control graph further by deferring the inner body of
+      directory_all_unreachable() into a callback. Closes ticket
+      16762.
\ No newline at end of file
index e564e6c1328ecac57f3493fd01e798a94c1d493d..a29387c67ac5465bd37b3c2749a7f4a8bb544f73 100644 (file)
@@ -982,19 +982,18 @@ conn_close_if_marked(int i)
   return 1;
 }
 
-/** We've just tried every dirserver we know about, and none of
- * them were reachable. Assume the network is down. Change state
- * so next time an application connection arrives we'll delay it
- * and try another directory fetch. Kill off all the circuit_wait
- * streams that are waiting now, since they will all timeout anyway.
+/** Implementation for directory_all_unreachable.  This is done in a callback,
+ * since otherwise it would complicate Tor's control-flow graph beyond all
+ * reason.
  */
-void
-directory_all_unreachable(time_t now)
+static void
+directory_all_unreachable_cb(evutil_socket_t fd, short event, void *arg)
 {
-  connection_t *conn;
-  (void)now;
+  (void)fd;
+  (void)event;
+  (void)arg;
 
-  stats_n_seconds_working=0; /* reset it */
+  connection_t *conn;
 
   while ((conn = connection_get_by_type_state(CONN_TYPE_AP,
                                               AP_CONN_STATE_CIRCUIT_WAIT))) {
@@ -1010,6 +1009,31 @@ directory_all_unreachable(time_t now)
   control_event_general_status(LOG_ERR, "DIR_ALL_UNREACHABLE");
 }
 
+static struct event *directory_all_unreachable_cb_event = NULL;
+
+/** We've just tried every dirserver we know about, and none of
+ * them were reachable. Assume the network is down. Change state
+ * so next time an application connection arrives we'll delay it
+ * and try another directory fetch. Kill off all the circuit_wait
+ * streams that are waiting now, since they will all timeout anyway.
+ */
+void
+directory_all_unreachable(time_t now)
+{
+  (void)now;
+
+  stats_n_seconds_working=0; /* reset it */
+
+  if (!directory_all_unreachable_cb_event) {
+    directory_all_unreachable_cb_event =
+      tor_event_new(tor_libevent_get_base(),
+                    -1, EV_READ, directory_all_unreachable_cb, NULL);
+    tor_assert(directory_all_unreachable_cb_event);
+  }
+
+  event_active(directory_all_unreachable_cb_event, EV_READ, 1);
+}
+
 /** This function is called whenever we successfully pull down some new
  * network statuses or server descriptors. */
 void