diff options
author | David Goulet <dgoulet@torproject.org> | 2018-12-21 11:17:45 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2018-12-21 11:25:23 -0500 |
commit | 2420e84ba4d4a35581eaa6bc41b08082002bfd4f (patch) | |
tree | 740fc78d306bc75f707173f91cc58b1aba891639 | |
parent | 633813e313cc6e889790e2bf9875a842ba1d99b7 (diff) | |
download | tor-2420e84ba4d4a35581eaa6bc41b08082002bfd4f.tar.gz tor-2420e84ba4d4a35581eaa6bc41b08082002bfd4f.zip |
mainloop: Reactivate the linked connection event with a non empty list
Linked connections aren't woken up by libevent due to I/O but rather
artificially so we can, by chunks, empty the spooled object(s).
Commit 5719dfb48f87a54aeb5982ff03345303bc058ebb (in 0.3.4.1-alpha) made it
that the schedule_active_linked_connections_event would be only called once at
startup but this is wrong because then we would never go through again the
active linked connections.
Fortunately, everytime a new linked connection is created, the event is
activated and thus we would go through the active list again. On a busy relay,
this issue is mitigated by that but on a slower relays or bridge, a connection
could get stuck for a while until a new directory information request would
show up.
Fixes #28717, #28912
-rw-r--r-- | changes/ticket28912 | 6 | ||||
-rw-r--r-- | src/or/main.c | 17 |
2 files changed, 20 insertions, 3 deletions
diff --git a/changes/ticket28912 b/changes/ticket28912 new file mode 100644 index 0000000000..4119b778bc --- /dev/null +++ b/changes/ticket28912 @@ -0,0 +1,6 @@ + o Major bugfixes (relay, directory): + - A connection serving directory information wouldn't get reactivated after + the first chunk of data was sent (usually 32KB). Tor now always activate + the main loop event that goes through these connections as long as at + least one connection is still active. Fixes bug 28912; bugfix on + 0.3.4.1-alpha. Patch by "cypherpunks3". diff --git a/src/or/main.c b/src/or/main.c index bc01e07c3d..aaa31c0579 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -404,6 +404,9 @@ connection_unlink(connection_t *conn) connection_free(conn); } +/** Event that invokes schedule_active_linked_connections_cb. */ +static mainloop_event_t *schedule_active_linked_connections_event = NULL; + /** * Callback: used to activate read events for all linked connections, so * libevent knows to call their read callbacks. This callback run as a @@ -420,10 +423,18 @@ schedule_active_linked_connections_cb(mainloop_event_t *event, void *arg) * so that libevent knows to run their callbacks. */ SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn, event_active(conn->read_event, EV_READ, 1)); -} -/** Event that invokes schedule_active_linked_connections_cb. */ -static mainloop_event_t *schedule_active_linked_connections_event = NULL; + /* Reactivate the event if we still have connections in the active list. + * + * A linked connection doesn't get woken up by I/O but rather artificially + * by this event callback. It has directory data spooled in it and it is + * sent incrementally by small chunks unless spool_eagerly is true. For that + * to happen, we need to induce the activation of the read event so it can + * be flushed. */ + if (smartlist_len(active_linked_connection_lst)) { + mainloop_event_activate(schedule_active_linked_connections_event); + } +} /** Initialize the global connection list, closeable connection list, * and active connection list. */ |