commit ce6209cee4a113c6a224f0c98244852354ccdb40 Author: Nick Mathewson <ni...@torproject.org> Date: Tue Nov 13 15:51:53 2018 -0500
Add a periodic event to become dormant. This event makes us become dormant if we have seen no activity in a long time. Note that being any kind of a server, or running an onion service, always counts as being active. Note that right now, just having an open stream that Tor did not open on its own (for a directory request) counts as "being active", so if you have an idle ssh connection, that will keep Tor from becoming dormant. Many of the features here should become configurable; I'd like feedback on which. --- src/core/mainloop/connection.c | 10 +++++++++ src/core/mainloop/connection.h | 1 + src/core/mainloop/mainloop.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index e0f1680c9..25224fd99 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -4429,6 +4429,16 @@ connection_get_by_type_state(int type, int state) CONN_GET_TEMPLATE(conn, conn->type == type && conn->state == state); } +/** + * Return a connection of type <b>type</b> that is not an internally linked + * connection, and is not marked for close. + **/ +connection_t * +connection_get_by_type_nonlinked(int type) +{ + CONN_GET_TEMPLATE(conn, conn->type == type && !conn->linked); +} + /** Return a connection of type <b>type</b> that has rendquery equal * to <b>rendquery</b>, and that is not marked for close. If state * is non-zero, conn must be of that state too. diff --git a/src/core/mainloop/connection.h b/src/core/mainloop/connection.h index b569bb038..9f1a23c6f 100644 --- a/src/core/mainloop/connection.h +++ b/src/core/mainloop/connection.h @@ -240,6 +240,7 @@ size_t connection_get_outbuf_len(connection_t *conn); connection_t *connection_get_by_global_id(uint64_t id); connection_t *connection_get_by_type(int type); +connection_t *connection_get_by_type_nonlinked(int type); MOCK_DECL(connection_t *,connection_get_by_type_addr_port_purpose,(int type, const tor_addr_t *addr, uint16_t port, int purpose)); diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index f18db2898..e6dee94fc 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -1367,6 +1367,7 @@ CALLBACK(write_bridge_ns); CALLBACK(write_stats_file); CALLBACK(control_per_second_events); CALLBACK(second_elapsed); +CALLBACK(check_network_participation); #undef CALLBACK @@ -1396,6 +1397,7 @@ STATIC periodic_event_item_t periodic_events[] = { CALLBACK(fetch_networkstatus, NET_PARTICIPANT, 0), CALLBACK(launch_descriptor_fetches, NET_PARTICIPANT, FL(NEED_NET)), CALLBACK(rotate_x509_certificate, NET_PARTICIPANT, 0), + CALLBACK(check_network_participation, NET_PARTICIPANT, 0), /* We need to do these if we're participating in the Tor network, and * immediately before we stop. */ @@ -1998,6 +2000,54 @@ add_entropy_callback(time_t now, const or_options_t *options) return ENTROPY_INTERVAL; } +/** Periodic callback: if there has been no network usage in a while, + * enter a dormant state. */ +static int +check_network_participation_callback(time_t now, const or_options_t *options) +{ + /* If we're a server, we can't become dormant. */ + if (server_mode(options)) { + goto found_activity; + } + + /* If we're running an onion service, we can't become dormant. */ + /* XXXX this would be nice to change, so that we can be dormant with a + * service. */ + if (hs_service_get_num_services() || rend_num_services()) { + goto found_activity; + } + + /* XXXX Add an option to never become dormant. */ + + /* If we have any currently open entry streams other than "linked" + * connections used for directory requests, those count as user activity. + */ + /* XXXX make this configurable? */ + if (connection_get_by_type_nonlinked(CONN_TYPE_AP) != NULL) { + goto found_activity; + } + + /* XXXX Make this configurable? */ +/** How often do we check whether we have had network activity? */ +#define CHECK_PARTICIPATION_INTERVAL (5*60) + + /** Become dormant if there has been no user activity in this long. */ + /* XXXX make this configurable! */ +#define BECOME_DORMANT_AFTER_INACTIVITY (24*60*60) + if (get_last_user_activity_time() + BECOME_DORMANT_AFTER_INACTIVITY >= now) { + log_notice(LD_GENERAL, "No user activity in a long time: becoming" + " dormant."); + set_network_participation(false); + rescan_periodic_events(options); + } + + return CHECK_PARTICIPATION_INTERVAL; + + found_activity: + note_user_activity(now); + return CHECK_PARTICIPATION_INTERVAL; +} + /** * Periodic callback: if we're an authority, make sure we test * the routers on the network for reachability. _______________________________________________ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits