Commit 2420e84b authored by David Goulet's avatar David Goulet 🐼
Browse files

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 5719dfb4 (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
parent 633813e3
Loading
Loading
Loading
Loading

changes/ticket28912

0 → 100644
+6 −0
Original line number Diff line number Diff line
  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".
+14 −3
Original line number Diff line number Diff line
@@ -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. */