Line data Source code
1 : /* Copyright (c) 2007-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file ocirc_event.c
6 : * \brief Publish state change messages for origin circuits
7 : *
8 : * Implements a basic publish-subscribe framework for messages about
9 : * the state of origin circuits. The publisher calls the subscriber
10 : * callback functions synchronously.
11 : *
12 : * Although the synchronous calls might not simplify the call graph,
13 : * this approach improves data isolation because the publisher doesn't
14 : * need knowledge about the internals of subscribing subsystems. It
15 : * also avoids race conditions that might occur in asynchronous
16 : * frameworks.
17 : **/
18 :
19 : #include "core/or/or.h"
20 :
21 : #define OCIRC_EVENT_PRIVATE
22 :
23 : #include "core/or/cpath_build_state_st.h"
24 : #include "core/or/ocirc_event.h"
25 : #include "core/or/or_sys.h"
26 : #include "core/or/origin_circuit_st.h"
27 : #include "lib/subsys/subsys.h"
28 :
29 1 : DECLARE_PUBLISH(ocirc_state);
30 8 : DECLARE_PUBLISH(ocirc_chan);
31 1 : DECLARE_PUBLISH(ocirc_cevent);
32 :
33 : static void
34 10 : ocirc_event_free(msg_aux_data_t u)
35 : {
36 10 : tor_free_(u.ptr);
37 10 : }
38 :
39 : static char *
40 2 : ocirc_state_fmt(msg_aux_data_t u)
41 : {
42 2 : ocirc_state_msg_t *msg = (ocirc_state_msg_t *)u.ptr;
43 2 : char *s = NULL;
44 :
45 2 : tor_asprintf(&s, "<gid=%"PRIu32" state=%d onehop=%d>",
46 2 : msg->gid, msg->state, msg->onehop);
47 2 : return s;
48 : }
49 :
50 : static char *
51 16 : ocirc_chan_fmt(msg_aux_data_t u)
52 : {
53 16 : ocirc_chan_msg_t *msg = (ocirc_chan_msg_t *)u.ptr;
54 16 : char *s = NULL;
55 :
56 16 : tor_asprintf(&s, "<gid=%"PRIu32" chan=%"PRIu64" onehop=%d>",
57 16 : msg->gid, msg->chan, msg->onehop);
58 16 : return s;
59 : }
60 :
61 : static char *
62 2 : ocirc_cevent_fmt(msg_aux_data_t u)
63 : {
64 2 : ocirc_cevent_msg_t *msg = (ocirc_cevent_msg_t *)u.ptr;
65 2 : char *s = NULL;
66 :
67 2 : tor_asprintf(&s, "<gid=%"PRIu32" evtype=%d reason=%d onehop=%d>",
68 2 : msg->gid, msg->evtype, msg->reason, msg->onehop);
69 2 : return s;
70 : }
71 :
72 : static dispatch_typefns_t ocirc_state_fns = {
73 : .free_fn = ocirc_event_free,
74 : .fmt_fn = ocirc_state_fmt,
75 : };
76 :
77 : static dispatch_typefns_t ocirc_chan_fns = {
78 : .free_fn = ocirc_event_free,
79 : .fmt_fn = ocirc_chan_fmt,
80 : };
81 :
82 : static dispatch_typefns_t ocirc_cevent_fns = {
83 : .free_fn = ocirc_event_free,
84 : .fmt_fn = ocirc_cevent_fmt,
85 : };
86 :
87 : int
88 245 : ocirc_add_pubsub(struct pubsub_connector_t *connector)
89 : {
90 245 : if (DISPATCH_REGISTER_TYPE(connector, ocirc_state, ô_state_fns))
91 : return -1;
92 245 : if (DISPATCH_REGISTER_TYPE(connector, ocirc_chan, ô_chan_fns))
93 : return -1;
94 245 : if (DISPATCH_REGISTER_TYPE(connector, ocirc_cevent, ô_cevent_fns))
95 : return -1;
96 245 : if (DISPATCH_ADD_PUB(connector, ocirc, ocirc_state))
97 : return -1;
98 245 : if (DISPATCH_ADD_PUB(connector, ocirc, ocirc_chan))
99 : return -1;
100 245 : if (DISPATCH_ADD_PUB(connector, ocirc, ocirc_cevent))
101 0 : return -1;
102 : return 0;
103 : }
104 :
105 : void
106 1 : ocirc_state_publish(ocirc_state_msg_t *msg)
107 : {
108 1 : PUBLISH(ocirc_state, msg);
109 1 : }
110 :
111 : void
112 8 : ocirc_chan_publish(ocirc_chan_msg_t *msg)
113 : {
114 8 : PUBLISH(ocirc_chan, msg);
115 8 : }
116 :
117 : void
118 1 : ocirc_cevent_publish(ocirc_cevent_msg_t *msg)
119 : {
120 1 : PUBLISH(ocirc_cevent, msg);
121 1 : }
|