aboutsummaryrefslogtreecommitdiff
path: root/src/core/or/ocirc_event.c
diff options
context:
space:
mode:
authorTaylor Yu <catalyst@torproject.org>2018-12-16 17:01:25 -0600
committerTaylor Yu <catalyst@torproject.org>2018-12-20 18:46:17 -0600
commita0b4fa1f167f9b013ee1a8326e325ec3f97e4700 (patch)
tree23af519fc5dcd46d597776dea0ec9556aa9e3eab /src/core/or/ocirc_event.c
parent271b50f54abac7af44e3e54589ff965d3cdac816 (diff)
downloadtor-a0b4fa1f167f9b013ee1a8326e325ec3f97e4700.tar.gz
tor-a0b4fa1f167f9b013ee1a8326e325ec3f97e4700.zip
Add origin circuit event pubsub system
Add a publish-subscribe subsystem to publish messages about changes to origin circuits. Functions in circuitbuild.c and circuitlist.c publish messages to this subsystem. Move circuit event constants out of control.h so that subscribers don't have to include all of control.h to take actions based on messages they receive. Part of ticket 27167.
Diffstat (limited to 'src/core/or/ocirc_event.c')
-rw-r--r--src/core/or/ocirc_event.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/core/or/ocirc_event.c b/src/core/or/ocirc_event.c
new file mode 100644
index 0000000000..f9f8af279f
--- /dev/null
+++ b/src/core/or/ocirc_event.c
@@ -0,0 +1,84 @@
+/* Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file ocirc_event.c
+ * \brief Publish state change messages for origin circuits
+ *
+ * Implements a basic publish-subscribe framework for messages about
+ * the state of origin circuits. The publisher calls the subscriber
+ * callback functions synchronously.
+ *
+ * Although the synchronous calls might not simplify the call graph,
+ * this approach improves data isolation because the publisher doesn't
+ * need knowledge about the internals of subscribing subsystems. It
+ * also avoids race conditions that might occur in asynchronous
+ * frameworks.
+ **/
+
+#include "core/or/or.h"
+
+#define OCIRC_EVENT_PRIVATE
+
+#include "core/or/cpath_build_state_st.h"
+#include "core/or/ocirc_event.h"
+#include "core/or/ocirc_event_sys.h"
+#include "core/or/origin_circuit_st.h"
+#include "lib/subsys/subsys.h"
+
+/** List of subscribers */
+static smartlist_t *ocirc_event_rcvrs;
+
+/** Initialize subscriber list */
+static int
+ocirc_event_init(void)
+{
+ ocirc_event_rcvrs = smartlist_new();
+ return 0;
+}
+
+/** Free subscriber list */
+static void
+ocirc_event_fini(void)
+{
+ smartlist_free(ocirc_event_rcvrs);
+}
+
+/**
+ * Subscribe to messages about origin circuit events
+ *
+ * Register a callback function to receive messages about origin
+ * circuits. The publisher calls this function synchronously.
+ **/
+void
+ocirc_event_subscribe(ocirc_event_rcvr_t fn)
+{
+ tor_assert(fn);
+ /* Don't duplicate subscriptions. */
+ if (smartlist_contains(ocirc_event_rcvrs, fn))
+ return;
+
+ smartlist_add(ocirc_event_rcvrs, fn);
+}
+
+/**
+ * Publish a message about OR connection events
+ *
+ * This calls the subscriber receiver function synchronously.
+ **/
+void
+ocirc_event_publish(const ocirc_event_msg_t *msg)
+{
+ SMARTLIST_FOREACH_BEGIN(ocirc_event_rcvrs, ocirc_event_rcvr_t, fn) {
+ tor_assert(fn);
+ (*fn)(msg);
+ } SMARTLIST_FOREACH_END(fn);
+}
+
+const subsys_fns_t sys_ocirc_event = {
+ .name = "ocirc_event",
+ .supported = true,
+ .level = -39,
+ .initialize = ocirc_event_init,
+ .shutdown = ocirc_event_fini,
+};