aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorteor <teor@torproject.org>2019-11-25 12:37:07 +1000
committerteor <teor@torproject.org>2019-11-25 12:37:07 +1000
commit26071aa3be8f26d7e81384f1d40bb1d5fe94cca0 (patch)
tree17caa24248899bdbf3cd2261d43b3487578a3aef /src
parent29eb7b07ef5d5af0c54bbc36804363a0bfdd3252 (diff)
parent055f5d4d1b2c8ea5a85691f7110e82a9c468b6dd (diff)
downloadtor-26071aa3be8f26d7e81384f1d40bb1d5fe94cca0.tar.gz
tor-26071aa3be8f26d7e81384f1d40bb1d5fe94cca0.zip
Merge branch 'maint-0.4.0' into maint-0.4.1
Diffstat (limited to 'src')
-rw-r--r--src/core/mainloop/connection.c18
-rw-r--r--src/core/mainloop/mainloop.c12
-rw-r--r--src/core/mainloop/periodic.c5
-rw-r--r--src/feature/client/transports.c6
-rw-r--r--src/feature/hs/hs_client.c8
-rw-r--r--src/feature/hs/hs_service.c9
-rw-r--r--src/lib/tls/buffers_tls.c4
7 files changed, 47 insertions, 15 deletions
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 127f08683f..372494a577 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -900,13 +900,19 @@ connection_mark_for_close_(connection_t *conn, int line, const char *file)
}
/** Mark <b>conn</b> to be closed next time we loop through
- * conn_close_if_marked() in main.c; the _internal version bypasses the
- * CONN_TYPE_OR checks; this should be called when you either are sure that
- * if this is an or_connection_t the controlling channel has been notified
- * (e.g. with connection_or_notify_error()), or you actually are the
+ * conn_close_if_marked() in main.c.
+ *
+ * This _internal version bypasses the CONN_TYPE_OR checks; this should be
+ * called when you either are sure that if this is an or_connection_t the
+ * controlling channel has been notified (e.g. with
+ * connection_or_notify_error()), or you actually are the
* connection_or_close_for_error() or connection_or_close_normally() function.
- * For all other cases, use connection_mark_and_flush() instead, which
- * checks for or_connection_t properly, instead. See below.
+ * For all other cases, use connection_mark_and_flush() which checks for
+ * or_connection_t properly, instead. See below.
+ *
+ * We want to keep this function simple and quick, since it can be called from
+ * quite deep in the call chain, and hence it should avoid having side-effects
+ * that interfere with its callers view of the connection.
*/
MOCK_IMPL(void,
connection_mark_for_close_internal_, (connection_t *conn,
diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c
index c051b11566..6f29a6981a 100644
--- a/src/core/mainloop/mainloop.c
+++ b/src/core/mainloop/mainloop.c
@@ -874,6 +874,16 @@ conn_read_callback(evutil_socket_t fd, short event, void *_conn)
/* assert_connection_ok(conn, time(NULL)); */
+ /* Handle marked for close connections early */
+ if (conn->marked_for_close && connection_is_reading(conn)) {
+ /* Libevent says we can read, but we are marked for close so we will never
+ * try to read again. We will try to close the connection below inside of
+ * close_closeable_connections(), but let's make sure not to cause Libevent
+ * to spin on conn_read_callback() while we wait for the socket to let us
+ * flush to it.*/
+ connection_stop_reading(conn);
+ }
+
if (connection_handle_read(conn) < 0) {
if (!conn->marked_for_close) {
#ifndef _WIN32
@@ -1378,7 +1388,7 @@ STATIC periodic_event_item_t mainloop_periodic_events[] = {
/* This is a legacy catch-all callback that runs once per second if
* we are online and active. */
CALLBACK(second_elapsed, NET_PARTICIPANT,
- FL(NEED_NET)|FL(RUN_ON_DISABLE)),
+ FL(RUN_ON_DISABLE)),
/* XXXX Do we have a reason to do this on a callback? Does it do any good at
* all? For now, if we're dormant, we can let our listeners decay. */
diff --git a/src/core/mainloop/periodic.c b/src/core/mainloop/periodic.c
index dbc4553a73..5c2f6f2b36 100644
--- a/src/core/mainloop/periodic.c
+++ b/src/core/mainloop/periodic.c
@@ -153,6 +153,11 @@ periodic_event_disconnect(periodic_event_item_t *event)
{
if (!event)
return;
+
+ /* First disable the event so we first cancel the event and set its enabled
+ * flag properly. */
+ periodic_event_disable(event);
+
mainloop_event_free(event->ev);
event->last_action_time = 0;
}
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c
index 97bfc8ae30..3f731ac7d4 100644
--- a/src/feature/client/transports.c
+++ b/src/feature/client/transports.c
@@ -1826,15 +1826,13 @@ managed_proxy_stdout_callback(process_t *process,
managed_proxy_t *mp = process_get_data(process);
- if (BUG(mp == NULL))
+ if (mp == NULL)
return;
handle_proxy_line(line, mp);
- if (proxy_configuration_finished(mp)) {
+ if (proxy_configuration_finished(mp))
handle_finished_proxy(mp);
- tor_assert(mp->conf_state == PT_PROTO_COMPLETED);
- }
}
/** Callback function that is called when our PT process have data on its
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index f8d47f0114..492e77faff 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -682,8 +682,12 @@ setup_intro_circ_auth_key(origin_circuit_t *circ)
tor_assert(circ);
desc = hs_cache_lookup_as_client(&circ->hs_ident->identity_pk);
- if (BUG(desc == NULL)) {
- /* Opening intro circuit without the descriptor is no good... */
+ if (desc == NULL) {
+ /* There is a very small race window between the opening of this circuit
+ * and the client descriptor cache that gets purged (NEWNYM) or the
+ * cleaned up because it expired. Mark the circuit for close so a new
+ * descriptor fetch can occur. */
+ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
goto end;
}
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index 2835912742..d1ca33b12e 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -1652,6 +1652,15 @@ build_desc_intro_points(const hs_service_t *service,
DIGEST256MAP_FOREACH(desc->intro_points.map, key,
const hs_service_intro_point_t *, ip) {
+ if (!ip->circuit_established) {
+ /* Ignore un-established intro points. They can linger in that list
+ * because their circuit has not opened and they haven't been removed
+ * yet even though we have enough intro circuits.
+ *
+ * Due to #31561, it can stay in that list until rotation so this check
+ * prevents to publish an intro point without a circuit. */
+ continue;
+ }
hs_desc_intro_point_t *desc_ip = hs_desc_intro_point_new();
if (setup_desc_intro_point(&desc->signing_kp, ip, now, desc_ip) < 0) {
hs_desc_intro_point_free(desc_ip);
diff --git a/src/lib/tls/buffers_tls.c b/src/lib/tls/buffers_tls.c
index 3c18cc7e43..bf03b61459 100644
--- a/src/lib/tls/buffers_tls.c
+++ b/src/lib/tls/buffers_tls.c
@@ -68,9 +68,9 @@ buf_read_from_tls(buf_t *buf, tor_tls_t *tls, size_t at_most)
check_no_tls_errors();
- if (BUG(buf->datalen >= INT_MAX))
+ IF_BUG_ONCE(buf->datalen >= INT_MAX)
return -1;
- if (BUG(buf->datalen >= INT_MAX - at_most))
+ IF_BUG_ONCE(buf->datalen >= INT_MAX - at_most)
return -1;
while (at_most > total_read) {