aboutsummaryrefslogtreecommitdiff
path: root/src/core/or
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2023-10-18 14:40:18 +0000
committerDavid Goulet <dgoulet@torproject.org>2023-10-18 14:40:18 +0000
commitcc31724f409ee5cff10d82ca05d43e04a85a44e1 (patch)
tree98b93752cd9545cfccab9f5c7197f99a977065ab /src/core/or
parent2a1fc47d8683fa77ec899255c300e76ebdd8d702 (diff)
parenta382337be629ff74e621d2e24c8048e9e8d31d26 (diff)
downloadtor-cc31724f409ee5cff10d82ca05d43e04a85a44e1.tar.gz
tor-cc31724f409ee5cff10d82ca05d43e04a85a44e1.zip
Merge branch 'ticket40870_048_02' into 'main'
conflux: Flag set as in full teardown in the free path Closes #40870 See merge request tpo/core/tor!777
Diffstat (limited to 'src/core/or')
-rw-r--r--src/core/or/conflux_pool.c43
-rw-r--r--src/core/or/conflux_pool.h2
2 files changed, 42 insertions, 3 deletions
diff --git a/src/core/or/conflux_pool.c b/src/core/or/conflux_pool.c
index 4a7e941372..ec2938aefc 100644
--- a/src/core/or/conflux_pool.c
+++ b/src/core/or/conflux_pool.c
@@ -1607,7 +1607,22 @@ linked_circuit_free(circuit_t *circ, bool is_client)
/* Circuit can be freed without being closed and so we try to delete this leg
* so we can learn if this circuit is the last leg or not. */
- cfx_del_leg(circ->conflux, circ);
+ if (cfx_del_leg(circ->conflux, circ)) {
+ /* Check for instances of bug #40870, which we suspect happen
+ * during exit. If any happen outside of exit, BUG and warn. */
+ if (!circ->conflux->in_full_teardown) {
+ /* We should bug and warn if we're not in a shutdown process; that
+ * means we got here somehow without a close. */
+ if (BUG(!shutting_down)) {
+ log_warn(LD_BUG,
+ "Conflux circuit %p being freed without being marked for "
+ "full teardown via close, with shutdown state %d. "
+ "Please report this.", circ, shutting_down);
+ conflux_log_set(LOG_WARN, circ->conflux, is_client);
+ }
+ circ->conflux->in_full_teardown = true;
+ }
+ }
if (CONFLUX_NUM_LEGS(circ->conflux) > 0) {
/* The last leg will free the streams but until then, we nullify to avoid
@@ -2126,14 +2141,36 @@ conflux_log_set(int loglevel, const conflux_t *cfx, bool is_client)
}
}
+/**
+ * Conflux needs a notification when tor_shutdown() begins, so that
+ * when circuits are freed, new legs are not launched.
+ *
+ * This needs a separate notification from conflux_pool_free_all(),
+ * because circuits must be freed before that function.
+ */
+void
+conflux_notify_shutdown(void)
+{
+ shutting_down = true;
+}
+
+#ifdef TOR_UNIT_TESTS
+/**
+ * For unit tests: Clear the shutting down state so we resume building legs.
+ */
+void
+conflux_clear_shutdown(void)
+{
+ shutting_down = false;
+}
+#endif
+
/** Free and clean up the conflux pool subsystem. This is called by the subsys
* manager AFTER all circuits have been freed which implies that all objects in
* the pools aren't referenced anymore. */
void
conflux_pool_free_all(void)
{
- shutting_down = true;
-
digest256map_free(client_linked_pool, free_conflux_void_);
digest256map_free(server_linked_pool, free_conflux_void_);
digest256map_free(client_unlinked_pool, free_unlinked_void_);
diff --git a/src/core/or/conflux_pool.h b/src/core/or/conflux_pool.h
index afa4d9d058..eba726b03a 100644
--- a/src/core/or/conflux_pool.h
+++ b/src/core/or/conflux_pool.h
@@ -12,6 +12,7 @@
#include "core/or/or.h"
void conflux_pool_init(void);
+void conflux_notify_shutdown(void);
void conflux_pool_free_all(void);
origin_circuit_t *conflux_get_circ_for_conn(const entry_connection_t *conn,
@@ -41,6 +42,7 @@ void conflux_log_set(int loglevel, const conflux_t *cfx, bool is_client);
#ifdef TOR_UNIT_TESTS
bool launch_new_set(int num_legs);
+void conflux_clear_shutdown(void);
digest256map_t *get_linked_pool(bool is_client);
digest256map_t *get_unlinked_pool(bool is_client);
extern uint8_t DEFAULT_CLIENT_UX;